ia64/xen-unstable

changeset 19432:e54eeff2de54

merge with xen-unstable.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Fri Mar 27 11:07:11 2009 +0900 (2009-03-27)
parents 5e4dd7079c48 0b13d9787622
children 56eb2c541255 d5ddc782bc49
files tools/hotplug/Linux/blktap
line diff
     1.1 --- a/Makefile	Fri Mar 27 10:54:08 2009 +0900
     1.2 +++ b/Makefile	Fri Mar 27 11:07:11 2009 +0900
     1.3 @@ -203,6 +203,8 @@ uninstall:
     1.4  	rm -rf $(D)/etc/hotplug/xen-backend.agent
     1.5  	rm -f  $(D)/etc/udev/rules.d/xen-backend.rules
     1.6  	rm -f  $(D)/etc/udev/xen-backend.rules
     1.7 +	rm -f  $(D)/etc/udev/rules.d/xend.rules
     1.8 +	rm -f  $(D)/etc/udev/xend.rules
     1.9  	rm -f  $(D)/etc/sysconfig/xendomains
    1.10  	rm -rf $(D)/var/run/xen* $(D)/var/lib/xen*
    1.11  	rm -rf $(D)/boot/*xen*
     2.1 --- a/config/NetBSD.mk	Fri Mar 27 10:54:08 2009 +0900
     2.2 +++ b/config/NetBSD.mk	Fri Mar 27 11:07:11 2009 +0900
     2.3 @@ -2,3 +2,7 @@ include $(XEN_ROOT)/config/StdGNU.mk
     2.4  
     2.5  # Override settings for this OS
     2.6  CURSES_LIBS = -lcurses
     2.7 +
     2.8 +LIBLEAFDIR_x86_64 = lib
     2.9 +LIBEXEC = $(PREFIX)/libexec
    2.10 +PRIVATE_BINDIR = $(BINDIR)
     3.1 --- a/config/StdGNU.mk	Fri Mar 27 10:54:08 2009 +0900
     3.2 +++ b/config/StdGNU.mk	Fri Mar 27 11:07:11 2009 +0900
     3.3 @@ -25,9 +25,12 @@ PREFIX ?= /usr
     3.4  BINDIR = $(PREFIX)/bin
     3.5  INCLUDEDIR = $(PREFIX)/include
     3.6  LIBLEAFDIR = lib
     3.7 +LIBLEAFDIR_x86_32 = lib
     3.8  LIBLEAFDIR_x86_64 = lib64
     3.9  LIBDIR = $(PREFIX)/$(LIBLEAFDIR)
    3.10 +LIBDIR_x86_32 = $(PREFIX)/$(LIBLEAFDIR_x86_32)
    3.11  LIBDIR_x86_64 = $(PREFIX)/$(LIBLEAFDIR_x86_64)
    3.12 +LIBEXEC = $(LIBDIR_x86_32)/xen/bin
    3.13  MANDIR = $(PREFIX)/share/man
    3.14  MAN1DIR = $(MANDIR)/man1
    3.15  MAN8DIR = $(MANDIR)/man8
     4.1 --- a/docs/misc/vtd.txt	Fri Mar 27 10:54:08 2009 +0900
     4.2 +++ b/docs/misc/vtd.txt	Fri Mar 27 11:07:11 2009 +0900
     4.3 @@ -26,7 +26,18 @@ title Xen-Fedora Core (2.6.18-xen)
     4.4          module /boot/vmlinuz-2.6.18.8-xen root=LABEL=/ ro xencons=ttyS console=tty0 console=ttyS0, pciback.hide=(01:00.0)(03:00.0)
     4.5          module /boot/initrd-2.6.18-xen.img
     4.6  
     4.7 -12) reboot system
     4.8 +    or use dynamic hiding via PCI backend sysfs interface:
     4.9 +        a) check if the driver has binded to the device
    4.10 +            ls -l /sys/bus/pci/devices/0000:01:00.0/driver
    4.11 +            ... /sys/bus/pci/devices/0000:01:00.0/driver -> ../../../../bus/pci/drivers/igb
    4.12 +        b) if yes, then unload the driver first
    4.13 +            echo -n 0000:01:00.0 >/sys/bus/pci/drivers/igb/unbind
    4.14 +        c) add the device to the PCI backend
    4.15 +            echo -n 0000:01:00.0 >/sys/bus/pci/drivers/pciback/new_slot
    4.16 +        d) let the PCI backend bind to the device
    4.17 +            echo -n 0000:01:00.0 >/sys/bus/pci/drivers/pciback/bind
    4.18 +
    4.19 +12) reboot system (not requires if you use the dynamic hiding method)
    4.20  13) add "pci" line in /etc/xen/hvm.conf for to assigned devices
    4.21          pci = [ '01:00.0', '03:00.0' ]
    4.22  15) start hvm guest and use "lspci" to see the passthru device and
    4.23 @@ -160,3 +171,82 @@ driver's view are different. As a result
    4.24  buffer specified by driver.
    4.25  
    4.26  Such devices assigned to HVM domain currently do not work.
    4.27 +
    4.28 +
    4.29 +Using SR-IOV with VT-d
    4.30 +--------------------------------
    4.31 +
    4.32 +The Single Root I/O Virtualization is a PCI Express feature supported by
    4.33 +some devices such as Intel 82576 which allows you to create virtual PCI
    4.34 +devices (Virtual Function) and assign them to the HVM guest.
    4.35 +
    4.36 +You can use latest lspci (v3.1 and above) to check if your PCIe device
    4.37 +supports the SR-IOV capability or not.
    4.38 +
    4.39 +  $ lspci -s 01:00.0 -vvv
    4.40 +
    4.41 +  01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    4.42 +        Subsystem: Intel Corporation Gigabit ET Dual Port Server Adapter
    4.43 +
    4.44 +        ...
    4.45 +
    4.46 +        Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
    4.47 +                IOVCap: Migration-, Interrupt Message Number: 000
    4.48 +                IOVCtl: Enable+ Migration- Interrupt- MSE+ ARIHierarchy+
    4.49 +                IOVSta: Migration-
    4.50 +                Initial VFs: 8, Total VFs: 8, Number of VFs: 7, Function Dependency Link: 00
    4.51 +                VF offset: 128, stride: 2, Device ID: 10ca
    4.52 +                Supported Page Size: 00000553, System Page Size: 00000001
    4.53 +                VF Migration: offset: 00000000, BIR: 0
    4.54 +        Kernel driver in use: igb
    4.55 +
    4.56 +
    4.57 +The function that has the SR-IOV capability is also known as Physical
    4.58 +Function. You need the Physical Function driver (runs in the Dom0 and
    4.59 +controls the physical resources allocation) to enable the Virtual Function.
    4.60 +Following is the Virtual Functions associated with above Physical Function.
    4.61 +
    4.62 +  $ lspci | grep -e 01:1[01].[0246]
    4.63 +
    4.64 +  01:10.0 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.65 +  01:10.2 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.66 +  01:10.4 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.67 +  01:10.6 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.68 +  01:11.0 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.69 +  01:11.2 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.70 +  01:11.4 Ethernet controller: Intel Corporation Device 10ca (rev 01)
    4.71 +
    4.72 +We can tell that Physical Function 01:00.0 has 7 Virtual Functions (01:10.0,
    4.73 +01:10.2, 01:10.4, 01:10.6, 01:11.0, 01:11.2, 01:11.4). And the Virtual
    4.74 +Function PCI Configuration Space looks just like normal PCI device.
    4.75 +
    4.76 +  $ lspci -s 01:10.0 -vvv
    4.77 +
    4.78 +  01:10.0 Ethernet controller: Intel Corporation 82576 Gigabit Virtual Function
    4.79 +        Subsystem: Intel Corporation Gigabit Virtual Function
    4.80 +        Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
    4.81 +        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    4.82 +        Region 0: [virtual] Memory at d2840000 (64-bit, non-prefetchable) [size=16K]
    4.83 +        Region 3: [virtual] Memory at d2860000 (64-bit, non-prefetchable) [size=16K]
    4.84 +        Capabilities: [70] MSI-X: Enable+ Mask- TabSize=3
    4.85 +                Vector table: BAR=3 offset=00000000
    4.86 +                PBA: BAR=3 offset=00002000
    4.87 +        Capabilities: [a0] Express (v2) Endpoint, MSI 00
    4.88 +
    4.89 +        ...
    4.90 +
    4.91 +
    4.92 +The Virtual Function only appears after the Physical Function driver
    4.93 +is loaded. Once the Physical Function driver is unloaded. All Virtual
    4.94 +Functions associated with this Physical Function disappear.
    4.95 +
    4.96 +The Virtual Function is essentially same as the normal PCI device when
    4.97 +using it in VT-d environment. You need to hide the Virtual Function,
    4.98 +use the Virtual Function bus, device and function number in the HVM
    4.99 +guest configuration file and then boot the HVM guest. You also need the
   4.100 +Virtual Function driver which is the normal PCI device driver in the
   4.101 +HMV guest to drive the Virtual Function. The PCIe SR-IOV specification
   4.102 +requires that the Virtual Function can only support MSI/MSI-x if it
   4.103 +uses interrupt. This means you also need to enable Xen/MSI support.
   4.104 +Since the Virtual Function is dynamically allocated by Physical Function
   4.105 +driver, you might want to use the dynamic hiding method mentioned above.
     5.1 --- a/extras/mini-os/arch/ia64/mm.c	Fri Mar 27 10:54:08 2009 +0900
     5.2 +++ b/extras/mini-os/arch/ia64/mm.c	Fri Mar 27 11:07:11 2009 +0900
     5.3 @@ -162,6 +162,12 @@ int unmap_frames(unsigned long virt_addr
     5.4      ASSERT(0);
     5.5  }
     5.6  
     5.7 +unsigned long alloc_contig_pages(int order, unsigned int addr_bits)
     5.8 +{
     5.9 +    /* TODO */
    5.10 +    ASSERT(0);
    5.11 +}
    5.12 +
    5.13  void arch_init_p2m(unsigned long max_pfn)
    5.14  {
    5.15      printk("Warn: p2m map not implemented.\n");
     6.1 --- a/extras/mini-os/arch/x86/mm.c	Fri Mar 27 10:54:08 2009 +0900
     6.2 +++ b/extras/mini-os/arch/x86/mm.c	Fri Mar 27 11:07:11 2009 +0900
     6.3 @@ -702,6 +702,148 @@ int unmap_frames(unsigned long va, unsig
     6.4  }
     6.5  
     6.6  /*
     6.7 + * Allocate pages which are contiguous in machine memory.
     6.8 + * Returns a VA to where they are mapped or 0 on failure.
     6.9 + * 
    6.10 + * addr_bits indicates if the region has restrictions on where it is
    6.11 + * located. Typical values are 32 (if for example PCI devices can't access
    6.12 + * 64bit memory) or 0 for no restrictions.
    6.13 + *
    6.14 + * Allocated pages can be freed using the page allocators free_pages() 
    6.15 + * function.
    6.16 + *
    6.17 + * based on Linux function xen_create_contiguous_region()
    6.18 + */
    6.19 +#define MAX_CONTIG_ORDER 9 /* 2MB */
    6.20 +unsigned long alloc_contig_pages(int order, unsigned int addr_bits)
    6.21 +{
    6.22 +    unsigned long in_va, va;
    6.23 +    unsigned long in_frames[1UL << order], out_frames, mfn;
    6.24 +    multicall_entry_t call[1UL << order];
    6.25 +    unsigned int i, num_pages = 1UL << order;
    6.26 +    int ret, exch_success;
    6.27 +
    6.28 +    /* pass in num_pages 'extends' of size 1 and
    6.29 +     * request 1 extend of size 'order */
    6.30 +    struct xen_memory_exchange exchange = {
    6.31 +        .in = {
    6.32 +            .nr_extents   = num_pages,
    6.33 +            .extent_order = 0,
    6.34 +            .domid        = DOMID_SELF
    6.35 +        },
    6.36 +        .out = {
    6.37 +            .nr_extents   = 1,
    6.38 +            .extent_order = order,
    6.39 +            .address_bits = addr_bits,
    6.40 +            .domid        = DOMID_SELF
    6.41 +        },
    6.42 +        .nr_exchanged = 0
    6.43 +    };
    6.44 +
    6.45 +    if ( order > MAX_CONTIG_ORDER )
    6.46 +    {
    6.47 +        printk("alloc_contig_pages: order too large 0x%x > 0x%x\n",
    6.48 +               order, MAX_CONTIG_ORDER);
    6.49 +        return 0;
    6.50 +    }
    6.51 +
    6.52 +    /* Allocate some potentially discontiguous pages */
    6.53 +    in_va = alloc_pages(order);
    6.54 +    if ( !in_va )
    6.55 +    {
    6.56 +        printk("alloc_contig_pages: could not get enough pages (order=0x%x\n",
    6.57 +               order);
    6.58 +        return 0;
    6.59 +    }
    6.60 +
    6.61 +    /* set up arguments for exchange hyper call */
    6.62 +    set_xen_guest_handle(exchange.in.extent_start, in_frames);
    6.63 +    set_xen_guest_handle(exchange.out.extent_start, &out_frames);
    6.64 +
    6.65 +    /* unmap current frames, keep a list of MFNs */
    6.66 +    for ( i = 0; i < num_pages; i++ )
    6.67 +    {
    6.68 +        int arg = 0;
    6.69 +
    6.70 +        va = in_va + (PAGE_SIZE * i);
    6.71 +        in_frames[i] = virt_to_mfn(va);
    6.72 +
    6.73 +        /* update P2M mapping */
    6.74 +        phys_to_machine_mapping[virt_to_pfn(va)] = INVALID_P2M_ENTRY;
    6.75 +
    6.76 +        /* build multi call */
    6.77 +        call[i].op = __HYPERVISOR_update_va_mapping;
    6.78 +        call[i].args[arg++] = va;
    6.79 +        call[i].args[arg++] = 0;
    6.80 +#ifdef __i386__
    6.81 +        call[i].args[arg++] = 0;
    6.82 +#endif  
    6.83 +        call[i].args[arg++] = UVMF_INVLPG;
    6.84 +    }
    6.85 +
    6.86 +    ret = HYPERVISOR_multicall(call, i);
    6.87 +    if ( ret )
    6.88 +    {
    6.89 +        printk("Odd, update_va_mapping hypercall failed with rc=%d.\n", ret);
    6.90 +        return 0;
    6.91 +    }
    6.92 +
    6.93 +    /* try getting a contig range of MFNs */
    6.94 +    out_frames = virt_to_pfn(in_va); /* PFNs to populate */
    6.95 +    ret = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
    6.96 +    if ( ret ) {
    6.97 +        printk("mem exchanged order=0x%x failed with rc=%d, nr_exchanged=%d\n", 
    6.98 +               order, ret, exchange.nr_exchanged);
    6.99 +        /* we still need to return the allocated pages above to the pool
   6.100 +         * ie. map them back into the 1:1 mapping etc. so we continue but 
   6.101 +         * in the end return the pages to the page allocator and return 0. */
   6.102 +        exch_success = 0;
   6.103 +    }
   6.104 +    else
   6.105 +        exch_success = 1;
   6.106 +
   6.107 +    /* map frames into 1:1 and update p2m */
   6.108 +    for ( i = 0; i < num_pages; i++ )
   6.109 +    {
   6.110 +        int arg = 0;
   6.111 +        pte_t pte;
   6.112 +
   6.113 +        va = in_va + (PAGE_SIZE * i);
   6.114 +        mfn = i < exchange.nr_exchanged ? (out_frames + i) : in_frames[i];
   6.115 +        pte = __pte(mfn << PAGE_SHIFT | L1_PROT);
   6.116 +
   6.117 +        /* update P2M mapping */
   6.118 +        phys_to_machine_mapping[virt_to_pfn(va)] = mfn;
   6.119 +
   6.120 +        /* build multi call */
   6.121 +        call[i].op = __HYPERVISOR_update_va_mapping;
   6.122 +        call[i].args[arg++] = va;
   6.123 +#ifdef __x86_64__
   6.124 +        call[i].args[arg++] = (pgentry_t)pte.pte;
   6.125 +#else
   6.126 +        call[i].args[arg++] = pte.pte_low;
   6.127 +        call[i].args[arg++] = pte.pte_high;
   6.128 +#endif  
   6.129 +        call[i].args[arg++] = UVMF_INVLPG;
   6.130 +    }
   6.131 +    ret = HYPERVISOR_multicall(call, i);
   6.132 +    if ( ret )
   6.133 +    {
   6.134 +        printk("update_va_mapping hypercall no. 2 failed with rc=%d.\n", ret);
   6.135 +        return 0;
   6.136 +    }
   6.137 +
   6.138 +    if ( !exch_success )
   6.139 +    {
   6.140 +        /* since the exchanged failed we just free the pages as well */
   6.141 +        free_pages((void *) in_va, order);
   6.142 +        return 0;
   6.143 +    }
   6.144 +    
   6.145 +    return in_va;
   6.146 +}
   6.147 +
   6.148 +/*
   6.149   * Check if a given MFN refers to real memory
   6.150   */
   6.151  static long system_ram_end_mfn;
     7.1 --- a/extras/mini-os/include/mm.h	Fri Mar 27 10:54:08 2009 +0900
     7.2 +++ b/extras/mini-os/include/mm.h	Fri Mar 27 11:07:11 2009 +0900
     7.3 @@ -72,6 +72,7 @@ void do_map_frames(unsigned long addr,
     7.4          unsigned long *f, unsigned long n, unsigned long stride,
     7.5  	unsigned long increment, domid_t id, int may_fail, unsigned long prot);
     7.6  int unmap_frames(unsigned long va, unsigned long num_frames);
     7.7 +unsigned long alloc_contig_pages(int order, unsigned int addr_bits);
     7.8  #ifdef HAVE_LIBC
     7.9  extern unsigned long heap, brk, heap_mapped, heap_end;
    7.10  #endif
     8.1 --- a/extras/mini-os/include/x86/arch_mm.h	Fri Mar 27 10:54:08 2009 +0900
     8.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Fri Mar 27 11:07:11 2009 +0900
     8.3 @@ -137,6 +137,9 @@ typedef unsigned long pgentry_t;
     8.4  #define IO_PROT (L1_PROT)
     8.5  #define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
     8.6  
     8.7 +/* for P2M */
     8.8 +#define INVALID_P2M_ENTRY (~0UL)
     8.9 +
    8.10  #include "arch_limits.h"
    8.11  #define PAGE_SIZE       __PAGE_SIZE
    8.12  #define PAGE_SHIFT      __PAGE_SHIFT
     9.1 --- a/stubdom/Makefile	Fri Mar 27 10:54:08 2009 +0900
     9.2 +++ b/stubdom/Makefile	Fri Mar 27 11:07:11 2009 +0900
     9.3 @@ -7,8 +7,6 @@ export stubdom=y
     9.4  export debug=y
     9.5  include $(XEN_ROOT)/Config.mk
     9.6  
     9.7 -IOEMU_OPTIONS=--disable-sdl --disable-opengl --disable-vnc-tls --disable-brlapi --disable-kqemu
     9.8 -
     9.9  #ZLIB_URL?=http://www.zlib.net
    9.10  ZLIB_URL=$(XEN_EXTFILES_URL)
    9.11  ZLIB_VERSION=1.2.3
    9.12 @@ -237,8 +235,12 @@ ioemu: cross-zlib cross-libpci libxc
    9.13  	[ -f ioemu/config-host.mak ] || \
    9.14  	  ( $(absolutify_xen_root); \
    9.15  	    cd ioemu ; \
    9.16 -          CONFIG_STUBDOM=yes XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) CFLAGS="$(TARGET_CFLAGS)" sh ./xen-setup --cc=$(CC) --disable-gcc-check $(IOEMU_OPTIONS))
    9.17 -	CPPFLAGS= TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) TOOLS= CONFIG_STUBDOM=yes
    9.18 +	    LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) \
    9.19 +	    TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" \
    9.20 +	    TARGET_CFLAGS="$(TARGET_CFLAGS)" \
    9.21 +	    TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \
    9.22 +	    ./xen-setup-stubdom )
    9.23 +	$(MAKE) -C ioemu
    9.24  
    9.25  ######
    9.26  # caml
    9.27 @@ -312,14 +314,14 @@ install-readme:
    9.28  	$(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.stubdom
    9.29  
    9.30  install-ioemu: ioemu-stubdom
    9.31 -	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/bin"
    9.32 -	$(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
    9.33 -	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
    9.34 -	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-ioemu/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz"
    9.35 +	$(INSTALL_DIR) "$(DESTDIR)$(LIBEXEC)"
    9.36 +	$(INSTALL_PROG) stubdom-dm "$(DESTDIR)$(LIBEXEC)"
    9.37 +	$(INSTALL_DIR) "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot"
    9.38 +	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-ioemu/mini-os.gz "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot/ioemu-stubdom.gz"
    9.39  
    9.40  install-grub: pv-grub
    9.41 -	$(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot"
    9.42 -	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/pv-grub-$(XEN_TARGET_ARCH).gz"
    9.43 +	$(INSTALL_DIR) "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot"
    9.44 +	$(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot/pv-grub-$(XEN_TARGET_ARCH).gz"
    9.45  
    9.46  #######
    9.47  # clean
    10.1 --- a/tools/Makefile	Fri Mar 27 10:54:08 2009 +0900
    10.2 +++ b/tools/Makefile	Fri Mar 27 11:07:11 2009 +0900
    10.3 @@ -19,11 +19,11 @@ SUBDIRS-y += xenmon
    10.4  SUBDIRS-$(VTPM_TOOLS) += vtpm_manager
    10.5  SUBDIRS-$(VTPM_TOOLS) += vtpm
    10.6  SUBDIRS-y += xenstat
    10.7 -SUBDIRS-y += libaio
    10.8 -SUBDIRS-y += blktap
    10.9 +SUBDIRS-$(CONFIG_Linux) += libaio
   10.10 +SUBDIRS-$(CONFIG_Linux) += blktap
   10.11  SUBDIRS-y += libfsimage
   10.12  SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
   10.13 -SUBDIRS-y += fs-back
   10.14 +SUBDIRS-$(CONFIG_Linux) += fs-back
   10.15  SUBDIRS-$(CONFIG_IOEMU) += ioemu-dir
   10.16  SUBDIRS-y += xenpmd
   10.17  
    11.1 --- a/tools/blktap/drivers/blktapctrl.c	Fri Mar 27 10:54:08 2009 +0900
    11.2 +++ b/tools/blktap/drivers/blktapctrl.c	Fri Mar 27 11:07:11 2009 +0900
    11.3 @@ -148,7 +148,8 @@ static int get_tapdisk_pid(blkif_t *blki
    11.4   *   return 0 on success, -1 on error.
    11.5   */
    11.6  
    11.7 -static int test_path(char *path, char **dev, int *type, blkif_t **blkif)
    11.8 +static int test_path(char *path, char **dev, int *type, blkif_t **blkif,
    11.9 +	int* use_ioemu)
   11.10  {
   11.11  	char *ptr, handle[10];
   11.12  	int i, size, found = 0;
   11.13 @@ -158,6 +159,17 @@ static int test_path(char *path, char **
   11.14  	*type = MAX_DISK_TYPES + 1;
   11.15          *blkif = NULL;
   11.16  
   11.17 +	if (!strncmp(path, "tapdisk:", strlen("tapdisk:"))) {
   11.18 +		*use_ioemu = 0;
   11.19 +		path += strlen("tapdisk:");
   11.20 +	} else if (!strncmp(path, "ioemu:", strlen("ioemu:"))) {
   11.21 +		*use_ioemu = 1;
   11.22 +		path += strlen("ioemu:");
   11.23 +	} else {
   11.24 +		// Use the default for the image type
   11.25 +		*use_ioemu = -1;
   11.26 +	}
   11.27 +
   11.28  	if ( (ptr = strstr(path, ":"))!=NULL) {
   11.29  		handle_len = (ptr - path);
   11.30  		memcpy(handle, path, handle_len);
   11.31 @@ -174,6 +186,8 @@ static int test_path(char *path, char **
   11.32                          }
   11.33  
   11.34  			if (found) {
   11.35 +				if (*use_ioemu == -1)
   11.36 +					*use_ioemu = dtypes[i]->use_ioemu;
   11.37  				*type = dtypes[i]->idnum;
   11.38                          
   11.39                          if (dtypes[i]->single_handler == 1) {
   11.40 @@ -185,6 +199,7 @@ static int test_path(char *path, char **
   11.41                                          *blkif = active_disks[dtypes[i]
   11.42                                                               ->idnum]->blkif;
   11.43                          }
   11.44 +
   11.45                          return 0;
   11.46                  }
   11.47              }
   11.48 @@ -216,6 +231,24 @@ static void add_disktype(blkif_t *blkif,
   11.49  	entry->pprev = pprev;
   11.50  }
   11.51  
   11.52 +static int qemu_instance_has_disks(pid_t pid)
   11.53 +{
   11.54 +	int i;
   11.55 +	int count = 0;
   11.56 +	driver_list_entry_t *entry;
   11.57 +
   11.58 +	for (i = 0; i < MAX_DISK_TYPES; i++) {
   11.59 +		entry = active_disks[i];
   11.60 +		while (entry) {
   11.61 +			if ((entry->blkif->tappid == pid) && dtypes[i]->use_ioemu)
   11.62 +				count++;
   11.63 +			entry = entry->next;
   11.64 +		}
   11.65 +	}
   11.66 +
   11.67 +	return (count != 0);
   11.68 +}
   11.69 +
   11.70  static int del_disktype(blkif_t *blkif)
   11.71  {
   11.72  	driver_list_entry_t *entry, **pprev;
   11.73 @@ -240,6 +273,14 @@ static int del_disktype(blkif_t *blkif)
   11.74  	DPRINTF("DEL_DISKTYPE: Freeing entry\n");
   11.75  	free(entry);
   11.76  
   11.77 +	/*
   11.78 +	 * When using ioemu, all disks of one VM are connected to the same
   11.79 +	 * qemu-dm instance. We may close the file handle only if there is
   11.80 +	 * no other disk left for this domain.
   11.81 +	 */
   11.82 +	if (dtypes[type]->use_ioemu)
   11.83 +		return !qemu_instance_has_disks(blkif->tappid);
   11.84 +
   11.85  	/* Caller should close() if no single controller, or list is empty. */
   11.86  	return (!dtypes[type]->single_handler || (active_disks[type] == NULL));
   11.87  }
   11.88 @@ -504,7 +545,8 @@ static int connect_qemu(blkif_t *blkif, 
   11.89  	static int tapdisk_ioemu_pid = 0;
   11.90  	static int dom0_readfd = 0;
   11.91  	static int dom0_writefd = 0;
   11.92 -	
   11.93 +	int refresh_pid = 0;
   11.94 +
   11.95  	if (asprintf(&rdctldev, BLKTAP_CTRL_DIR "/qemu-read-%d", domid) < 0)
   11.96  		return -1;
   11.97  
   11.98 @@ -523,15 +565,23 @@ static int connect_qemu(blkif_t *blkif, 
   11.99  		if (tapdisk_ioemu_pid == 0 || kill(tapdisk_ioemu_pid, 0)) {
  11.100  			/* No device model and tapdisk-ioemu doesn't run yet */
  11.101  			DPRINTF("Launching tapdisk-ioemu\n");
  11.102 -			tapdisk_ioemu_pid = launch_tapdisk_ioemu();
  11.103 +			launch_tapdisk_ioemu();
  11.104  			
  11.105  			dom0_readfd = open_ctrl_socket(wrctldev);
  11.106  			dom0_writefd = open_ctrl_socket(rdctldev);
  11.107 +
  11.108 +			refresh_pid = 1;
  11.109  		}
  11.110  
  11.111  		DPRINTF("Using tapdisk-ioemu connection\n");
  11.112  		blkif->fds[READ] = dom0_readfd;
  11.113  		blkif->fds[WRITE] = dom0_writefd;
  11.114 +
  11.115 +		if (refresh_pid) {
  11.116 +			get_tapdisk_pid(blkif);
  11.117 +			tapdisk_ioemu_pid = blkif->tappid;
  11.118 +		}
  11.119 +
  11.120  	} else if (access(rdctldev, R_OK | W_OK) == 0) {
  11.121  		/* Use existing pipe to the device model */
  11.122  		DPRINTF("Using qemu-dm connection\n");
  11.123 @@ -605,13 +655,11 @@ static int blktapctrl_new_blkif(blkif_t 
  11.124  	image_t *image;
  11.125  	blkif_t *exist = NULL;
  11.126  	static uint16_t next_cookie = 0;
  11.127 +	int use_ioemu;
  11.128  
  11.129  	DPRINTF("Received a poll for a new vbd\n");
  11.130  	if ( ((blk=blkif->info) != NULL) && (blk->params != NULL) ) {
  11.131 -		if (blktap_interface_create(ctlfd, &major, &minor, blkif) < 0)
  11.132 -			return -1;
  11.133 -
  11.134 -		if (test_path(blk->params, &ptr, &type, &exist) != 0) {
  11.135 +		if (test_path(blk->params, &ptr, &type, &exist, &use_ioemu) != 0) {
  11.136                          DPRINTF("Error in blktap device string(%s).\n",
  11.137                                  blk->params);
  11.138                          goto fail;
  11.139 @@ -620,7 +668,7 @@ static int blktapctrl_new_blkif(blkif_t 
  11.140  		blkif->cookie = next_cookie++;
  11.141  
  11.142  		if (!exist) {
  11.143 -			if (type == DISK_TYPE_IOEMU) {
  11.144 +			if (use_ioemu) {
  11.145  				if (connect_qemu(blkif, blkif->domid))
  11.146  					goto fail;
  11.147  			} else {
  11.148 @@ -634,10 +682,6 @@ static int blktapctrl_new_blkif(blkif_t 
  11.149  			blkif->fds[WRITE] = exist->fds[WRITE];
  11.150  		}
  11.151  
  11.152 -		add_disktype(blkif, type);
  11.153 -		blkif->major = major;
  11.154 -		blkif->minor = minor;
  11.155 -
  11.156  		image = (image_t *)malloc(sizeof(image_t));
  11.157  		blkif->prv = (void *)image;
  11.158  		blkif->ops = &tapdisk_ops;
  11.159 @@ -661,11 +705,18 @@ static int blktapctrl_new_blkif(blkif_t 
  11.160  			goto fail;
  11.161  		}
  11.162  
  11.163 +		if (blktap_interface_create(ctlfd, &major, &minor, blkif) < 0)
  11.164 +			return -1;
  11.165 +
  11.166 +		blkif->major = major;
  11.167 +		blkif->minor = minor;
  11.168 +
  11.169 +		add_disktype(blkif, type);
  11.170 +
  11.171  	} else return -1;
  11.172  
  11.173  	return 0;
  11.174  fail:
  11.175 -	ioctl(ctlfd, BLKTAP_IOCTL_FREEINTF, minor);
  11.176  	return -EINVAL;
  11.177  }
  11.178  
  11.179 @@ -696,6 +747,7 @@ static int unmap_blktapctrl(blkif_t *blk
  11.180  	}
  11.181  
  11.182  	if (del_disktype(blkif)) {
  11.183 +		DPRINTF("Closing communication pipe to pid %d\n", blkif->tappid);
  11.184  		close(blkif->fds[WRITE]);
  11.185  		close(blkif->fds[READ]);
  11.186  	}
    12.1 --- a/tools/blktap/drivers/tapdisk.h	Fri Mar 27 10:54:08 2009 +0900
    12.2 +++ b/tools/blktap/drivers/tapdisk.h	Fri Mar 27 11:07:11 2009 +0900
    12.3 @@ -145,6 +145,8 @@ typedef struct disk_info {
    12.4  	char handle[10];     /* xend handle, e.g. 'ram' */
    12.5  	int  single_handler; /* is there a single controller for all */
    12.6  	                     /* instances of disk type? */
    12.7 +	int  use_ioemu;      /* backend provider: 0 = tapdisk; 1 = ioemu */
    12.8 +
    12.9  #ifdef TAPDISK
   12.10  	struct tap_disk *drv;	
   12.11  #endif
   12.12 @@ -159,16 +161,6 @@ extern struct tap_disk tapdisk_ram;
   12.13  extern struct tap_disk tapdisk_qcow;
   12.14  extern struct tap_disk tapdisk_qcow2;
   12.15  
   12.16 -#define MAX_DISK_TYPES     20
   12.17 -
   12.18 -#define DISK_TYPE_AIO      0
   12.19 -#define DISK_TYPE_SYNC     1
   12.20 -#define DISK_TYPE_VMDK     2
   12.21 -#define DISK_TYPE_RAM      3
   12.22 -#define DISK_TYPE_QCOW     4
   12.23 -#define DISK_TYPE_QCOW2    5
   12.24 -#define DISK_TYPE_IOEMU    6
   12.25 -
   12.26  
   12.27  /*Define Individual Disk Parameters here */
   12.28  static disk_info_t aio_disk = {
   12.29 @@ -176,6 +168,7 @@ static disk_info_t aio_disk = {
   12.30  	"raw image (aio)",
   12.31  	"aio",
   12.32  	0,
   12.33 +	0,
   12.34  #ifdef TAPDISK
   12.35  	&tapdisk_aio,
   12.36  #endif
   12.37 @@ -186,6 +179,7 @@ static disk_info_t sync_disk = {
   12.38  	"raw image (sync)",
   12.39  	"sync",
   12.40  	0,
   12.41 +	0,
   12.42  #ifdef TAPDISK
   12.43  	&tapdisk_sync,
   12.44  #endif
   12.45 @@ -196,6 +190,7 @@ static disk_info_t vmdk_disk = {
   12.46  	"vmware image (vmdk)",
   12.47  	"vmdk",
   12.48  	1,
   12.49 +	0,
   12.50  #ifdef TAPDISK
   12.51  	&tapdisk_vmdk,
   12.52  #endif
   12.53 @@ -206,6 +201,7 @@ static disk_info_t ram_disk = {
   12.54  	"ramdisk image (ram)",
   12.55  	"ram",
   12.56  	1,
   12.57 +	0,
   12.58  #ifdef TAPDISK
   12.59  	&tapdisk_ram,
   12.60  #endif
   12.61 @@ -216,6 +212,7 @@ static disk_info_t qcow_disk = {
   12.62  	"qcow disk (qcow)",
   12.63  	"qcow",
   12.64  	0,
   12.65 +	0,
   12.66  #ifdef TAPDISK
   12.67  	&tapdisk_qcow,
   12.68  #endif
   12.69 @@ -226,21 +223,12 @@ static disk_info_t qcow2_disk = {
   12.70  	"qcow2 disk (qcow2)",
   12.71  	"qcow2",
   12.72  	0,
   12.73 +	0,
   12.74  #ifdef TAPDISK
   12.75  	&tapdisk_qcow2,
   12.76  #endif
   12.77  };
   12.78  
   12.79 -static disk_info_t ioemu_disk = {
   12.80 -	DISK_TYPE_IOEMU,
   12.81 -	"ioemu disk",
   12.82 -	"ioemu",
   12.83 -	1,
   12.84 -#ifdef TAPDISK
   12.85 -	NULL
   12.86 -#endif
   12.87 -};
   12.88 -
   12.89  /*Main disk info array */
   12.90  static disk_info_t *dtypes[] = {
   12.91  	&aio_disk,
   12.92 @@ -249,7 +237,6 @@ static disk_info_t *dtypes[] = {
   12.93  	&ram_disk,
   12.94  	&qcow_disk,
   12.95  	&qcow2_disk,
   12.96 -	&ioemu_disk,
   12.97  };
   12.98  
   12.99  typedef struct driver_list_entry {
    13.1 --- a/tools/blktap/lib/blktaplib.h	Fri Mar 27 10:54:08 2009 +0900
    13.2 +++ b/tools/blktap/lib/blktaplib.h	Fri Mar 27 11:07:11 2009 +0900
    13.3 @@ -210,6 +210,16 @@ typedef struct msg_pid {
    13.4  #define CTLMSG_PID         9
    13.5  #define CTLMSG_PID_RSP     10
    13.6  
    13.7 +/* disk driver types */
    13.8 +#define MAX_DISK_TYPES     20
    13.9 +
   13.10 +#define DISK_TYPE_AIO      0
   13.11 +#define DISK_TYPE_SYNC     1
   13.12 +#define DISK_TYPE_VMDK     2
   13.13 +#define DISK_TYPE_RAM      3
   13.14 +#define DISK_TYPE_QCOW     4
   13.15 +#define DISK_TYPE_QCOW2    5
   13.16 +
   13.17  /* xenstore/xenbus: */
   13.18  #define DOMNAME "Domain-0"
   13.19  int setup_probe_watch(struct xs_handle *h);
    14.1 --- a/tools/blktap/lib/xenbus.c	Fri Mar 27 10:54:08 2009 +0900
    14.2 +++ b/tools/blktap/lib/xenbus.c	Fri Mar 27 11:07:11 2009 +0900
    14.3 @@ -48,6 +48,7 @@
    14.4  #include <poll.h>
    14.5  #include <time.h>
    14.6  #include <sys/time.h>
    14.7 +#include <unistd.h>
    14.8  #include "blktaplib.h"
    14.9  #include "list.h"
   14.10  #include "xs_api.h"
   14.11 @@ -149,6 +150,137 @@ static int backend_remove(struct xs_hand
   14.12  	return 0;
   14.13  }
   14.14  
   14.15 +static int check_sharing(struct xs_handle *h, struct backend_info *be)
   14.16 +{
   14.17 +	char *dom_uuid;
   14.18 +	char *cur_dom_uuid;
   14.19 +	char *path;
   14.20 +	char *mode;
   14.21 +	char *params;
   14.22 +	char **domains;
   14.23 +	char **devices;
   14.24 +	int i, j;
   14.25 +	unsigned int num_dom, num_dev;
   14.26 +	blkif_info_t *info;
   14.27 +	int ret = 0;
   14.28 +
   14.29 +	/* If the mode contains '!' or doesn't contain 'w' don't check anything */
   14.30 +	xs_gather(h, be->backpath, "mode", NULL, &mode, NULL);
   14.31 +	if (strchr(mode, '!'))
   14.32 +		goto out;
   14.33 +	if (strchr(mode, 'w') == NULL)
   14.34 +		goto out;
   14.35 +
   14.36 +	/* Get the UUID of the domain we want to attach to */
   14.37 +	if (asprintf(&path, "/local/domain/%ld", be->frontend_id) == -1)
   14.38 +		goto fail;
   14.39 +	xs_gather(h, path, "vm", NULL, &dom_uuid, NULL);
   14.40 +	free(path);
   14.41 +
   14.42 +	/* Iterate through the devices of all VMs */
   14.43 +	domains = xs_directory(h, XBT_NULL, "backend/tap", &num_dom);
   14.44 +	if (domains == NULL)
   14.45 +		num_dom = 0;
   14.46 +
   14.47 +	for (i = 0; !ret && (i < num_dom); i++) {
   14.48 +
   14.49 +		/* If it's the same VM, no action needed */
   14.50 +		if (asprintf(&path, "/local/domain/%s", domains[i]) == -1) {
   14.51 +			ret = -1;
   14.52 +			break;
   14.53 +		}
   14.54 +		xs_gather(h, path, "vm", NULL, &cur_dom_uuid, NULL);
   14.55 +		free(path);
   14.56 +
   14.57 +		if (!strcmp(cur_dom_uuid, dom_uuid)) {
   14.58 +			free(cur_dom_uuid);
   14.59 +			continue;
   14.60 +		}
   14.61 +
   14.62 +		/* Check the devices */
   14.63 +		if (asprintf(&path, "backend/tap/%s", domains[i]) == -1) {
   14.64 +			ret = -1;
   14.65 +			free(cur_dom_uuid);
   14.66 +			break;
   14.67 +		}
   14.68 +		devices = xs_directory(h, XBT_NULL, path, &num_dev);
   14.69 +		if (devices == NULL)
   14.70 +			num_dev = 0;
   14.71 +		free(path);
   14.72 +
   14.73 +		for (j = 0; !ret && (j < num_dev); j++) {
   14.74 +			if (asprintf(&path, "backend/tap/%s/%s", domains[i], devices[j]) == -1) {
   14.75 +				ret = -1;
   14.76 +				break;
   14.77 +			}
   14.78 +			xs_gather(h, path, "params", NULL, &params, NULL);
   14.79 +			free(path);
   14.80 +
   14.81 +			info =  be->blkif->info;
   14.82 +			if (strcmp(params, info->params)) {
   14.83 +				ret = -1;
   14.84 +			}
   14.85 +
   14.86 +			free(params);
   14.87 +		}
   14.88 +
   14.89 +		free(cur_dom_uuid);
   14.90 +		free(devices);
   14.91 +	}
   14.92 +	free(domains);
   14.93 +	free(dom_uuid);
   14.94 +	goto out;
   14.95 +
   14.96 +fail:
   14.97 +	ret = -1;
   14.98 +out:
   14.99 +	free(mode);
  14.100 +	return ret;
  14.101 +}
  14.102 +
  14.103 +static int check_image(struct xs_handle *h, struct backend_info *be,
  14.104 +	const char** errmsg)
  14.105 +{
  14.106 +	const char *tmp;
  14.107 +	const char *path;
  14.108 +	int mode;
  14.109 +	blkif_t *blkif = be->blkif;
  14.110 +	blkif_info_t *info = blkif->info;
  14.111 +
  14.112 +	/* Strip off the image type */
  14.113 +	path = info->params;
  14.114 +
  14.115 +	if (!strncmp(path, "tapdisk:", strlen("tapdisk:"))) {
  14.116 +		path += strlen("tapdisk:");
  14.117 +	} else if (!strncmp(path, "ioemu:", strlen("ioemu:"))) {
  14.118 +		path += strlen("ioemu:");
  14.119 +	}
  14.120 +
  14.121 +	tmp = strchr(path, ':');
  14.122 +	if (tmp != NULL)
  14.123 +		path = tmp + 1;
  14.124 +
  14.125 +	/* Check if the image exists and access is permitted */
  14.126 +	mode = R_OK;
  14.127 +	if (!be->readonly)
  14.128 +		mode |= W_OK;
  14.129 +	if (access(path, mode)) {
  14.130 +		if (errno == ENOENT)
  14.131 +			*errmsg = "File not found.";
  14.132 +		else
  14.133 +			*errmsg = "Insufficient file permissions.";
  14.134 +		return -1;
  14.135 +	}
  14.136 +
  14.137 +	/* Check that the image is not attached to a different VM */
  14.138 +	if (check_sharing(h, be)) {
  14.139 +		*errmsg = "File already in use by other domain";
  14.140 +		return -1;
  14.141 +	}
  14.142 +
  14.143 +	return 0;
  14.144 +}
  14.145 +
  14.146  static void ueblktap_setup(struct xs_handle *h, char *bepath)
  14.147  {
  14.148  	struct backend_info *be;
  14.149 @@ -156,6 +288,7 @@ static void ueblktap_setup(struct xs_han
  14.150  	int len, er, deverr;
  14.151  	long int pdev = 0, handle;
  14.152  	blkif_info_t *blk;
  14.153 +	const char* errmsg = NULL;
  14.154  	
  14.155  	be = be_lookup_be(bepath);
  14.156  	if (be == NULL)
  14.157 @@ -211,6 +344,9 @@ static void ueblktap_setup(struct xs_han
  14.158  			be->pdev = pdev;
  14.159  		}
  14.160  
  14.161 +		if (check_image(h, be, &errmsg))
  14.162 +			goto fail;
  14.163 +
  14.164  		er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
  14.165  		if (er != 0) {
  14.166  			DPRINTF("Unable to open device %s\n",blk->params);
  14.167 @@ -246,12 +382,21 @@ static void ueblktap_setup(struct xs_han
  14.168  	}
  14.169  
  14.170  	be->blkif->state = CONNECTED;
  14.171 +	xs_printf(h, be->backpath, "hotplug-status", "connected");
  14.172 +
  14.173  	DPRINTF("[SETUP] Complete\n\n");
  14.174  	goto close;
  14.175  	
  14.176  fail:
  14.177 -	if ( (be != NULL) && (be->blkif != NULL) ) 
  14.178 +	if (be) {
  14.179 +		if (errmsg == NULL)
  14.180 +			errmsg = "Setting up the backend failed. See the log "
  14.181 +				"files in /var/log/xen/ for details.";
  14.182 +		xs_printf(h, be->backpath, "hotplug-error", errmsg);
  14.183 +		xs_printf(h, be->backpath, "hotplug-status", "error");
  14.184 +
  14.185  		backend_remove(h, be);
  14.186 +	}
  14.187  close:
  14.188  	if (path)
  14.189  		free(path);
  14.190 @@ -286,7 +431,8 @@ static void ueblktap_probe(struct xs_han
  14.191  	len = strsep_len(bepath, '/', 7);
  14.192  	if (len < 0) 
  14.193  		goto free_be;
  14.194 -	bepath[len] = '\0';
  14.195 +	if (bepath[len] != '\0')
  14.196 +		goto free_be;
  14.197  	
  14.198  	be = malloc(sizeof(*be));
  14.199  	if (!be) {
    15.1 --- a/tools/console/client/main.c	Fri Mar 27 10:54:08 2009 +0900
    15.2 +++ b/tools/console/client/main.c	Fri Mar 27 11:07:11 2009 +0900
    15.3 @@ -35,6 +35,9 @@
    15.4  #include <err.h>
    15.5  #include <errno.h>
    15.6  #include <string.h>
    15.7 +#ifdef __sun__
    15.8 +#include <sys/stropts.h>
    15.9 +#endif
   15.10  
   15.11  #include "xs.h"
   15.12  
   15.13 @@ -71,6 +74,21 @@ static void usage(const char *program) {
   15.14  	       , program);
   15.15  }
   15.16  
   15.17 +#ifdef	__sun__
   15.18 +void cfmakeraw(struct termios *termios_p)
   15.19 +{
   15.20 +	termios_p->c_iflag &=
   15.21 +	    ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
   15.22 +	termios_p->c_oflag &= ~OPOST;
   15.23 +	termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
   15.24 +	termios_p->c_cflag &= ~(CSIZE|PARENB);
   15.25 +	termios_p->c_cflag |= CS8;
   15.26 +
   15.27 +	termios_p->c_cc[VMIN] = 0;
   15.28 +	termios_p->c_cc[VTIME] = 0;
   15.29 +}
   15.30 +#endif
   15.31 +
   15.32  static int get_pty_fd(struct xs_handle *xs, char *path, int seconds)
   15.33  /* Check for a pty in xenstore, open it and return its fd.
   15.34   * Assumes there is already a watch set in the store for this path. */
   15.35 @@ -80,7 +98,7 @@ static int get_pty_fd(struct xs_handle *
   15.36  	int xs_fd = xs_fileno(xs), pty_fd = -1;
   15.37  	int start, now;
   15.38  	unsigned int len = 0;
   15.39 -	char *pty_path, **watch_paths;;
   15.40 +	char *pty_path, **watch_paths;
   15.41  
   15.42  	start = now = time(NULL);
   15.43  	do {
   15.44 @@ -104,6 +122,29 @@ static int get_pty_fd(struct xs_handle *
   15.45  			}
   15.46  		}
   15.47  	} while (pty_fd == -1 && (now = time(NULL)) < start + seconds);
   15.48 +
   15.49 +#ifdef __sun__
   15.50 +	if (pty_fd != -1) {
   15.51 +		struct termios term;
   15.52 +
   15.53 +		/*
   15.54 +		 * The pty may come from either xend (with pygrub) or
   15.55 +		 * xenconsoled.  It may have tty semantics set up, or not.
   15.56 +		 * While it isn't strictly necessary to have those
   15.57 +		 * semantics here, it is good to have a consistent
   15.58 +		 * state that is the same as under Linux.
   15.59 +		 *
   15.60 +		 * If tcgetattr fails, they have not been set up,
   15.61 +		 * so go ahead and set them up now, by pushing the
   15.62 +		 * ptem and ldterm streams modules.
   15.63 +		 */
   15.64 +		if (tcgetattr(pty_fd, &term) < 0) {
   15.65 +			ioctl(pty_fd, I_PUSH, "ptem");
   15.66 +			ioctl(pty_fd, I_PUSH, "ldterm");
   15.67 +		}
   15.68 +	}
   15.69 +#endif
   15.70 +
   15.71  	return pty_fd;
   15.72  }
   15.73  
   15.74 @@ -119,12 +160,12 @@ static void init_term(int fd, struct ter
   15.75  	new_term = *old;
   15.76  	cfmakeraw(&new_term);
   15.77  
   15.78 -	tcsetattr(fd, TCSAFLUSH, &new_term);
   15.79 +	tcsetattr(fd, TCSANOW, &new_term);
   15.80  }
   15.81  
   15.82  static void restore_term(int fd, struct termios *old)
   15.83  {
   15.84 -	tcsetattr(fd, TCSAFLUSH, old);
   15.85 +	tcsetattr(fd, TCSANOW, old);
   15.86  }
   15.87  
   15.88  static int console_loop(int fd, struct xs_handle *xs, char *pty_path)
   15.89 @@ -152,7 +193,8 @@ static int console_loop(int fd, struct x
   15.90  
   15.91  		if (FD_ISSET(xs_fileno(xs), &fds)) {
   15.92  			int newfd = get_pty_fd(xs, pty_path, 0);
   15.93 -			close(fd);
   15.94 +			if (fd != -1)
   15.95 +				close(fd);
   15.96                          if (newfd == -1) 
   15.97  				/* Console PTY has become invalid */
   15.98  				return 0;
    16.1 --- a/tools/console/daemon/main.c	Fri Mar 27 10:54:08 2009 +0900
    16.2 +++ b/tools/console/daemon/main.c	Fri Mar 27 11:07:11 2009 +0900
    16.3 @@ -86,7 +86,9 @@ int main(int argc, char **argv)
    16.4  			version(argv[0]);
    16.5  			exit(0);
    16.6  		case 'v':
    16.7 +#ifndef __sun__
    16.8  			syslog_option |= LOG_PERROR;
    16.9 +#endif
   16.10  			syslog_mask = LOG_DEBUG;
   16.11  			break;
   16.12  		case 'i':
    17.1 --- a/tools/examples/xend-config.sxp	Fri Mar 27 10:54:08 2009 +0900
    17.2 +++ b/tools/examples/xend-config.sxp	Fri Mar 27 11:07:11 2009 +0900
    17.3 @@ -64,6 +64,7 @@
    17.4  #(xend-relocation-server no)
    17.5  (xend-relocation-server yes)
    17.6  #(xend-relocation-ssl-server no)
    17.7 +#(xend-udev-event-server no)
    17.8  
    17.9  #(xend-unix-path /var/lib/xend/xend-socket)
   17.10  
    18.1 --- a/tools/examples/xmexample.hvm	Fri Mar 27 10:54:08 2009 +0900
    18.2 +++ b/tools/examples/xmexample.hvm	Fri Mar 27 11:07:11 2009 +0900
    18.3 @@ -225,6 +225,10 @@ serial='pty'
    18.4  #keymap='ja'
    18.5  
    18.6  #-----------------------------------------------------------------------------
    18.7 +#   Enable/disable xen platform PCI device, default=1 (enabled)
    18.8 +#xen_platform_pci=1
    18.9 +
   18.10 +#-----------------------------------------------------------------------------
   18.11  #   Configure guest CPUID responses:
   18.12  #
   18.13  #cpuid=[ '1:ecx=xxxxxxxxxxx00xxxxxxxxxxxxxxxxxxx,
   18.14 @@ -264,8 +268,8 @@ serial='pty'
   18.15  # Look like a generic 686 :
   18.16  # cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
   18.17  #           '1:eax=0x06b1,
   18.18 -#              ecx=xxxxxxxxxx0000xx00xxx0000000xx0,
   18.19 -#              edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx',
   18.20 +#              ecx=xxxxxxxxxxx0000xx00xxx0000000xx0,
   18.21 +#              edx=xxx00000xxxxxxx0xxxxxxxxx0xxxxxx',
   18.22  #           '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
   18.23  #  '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0']
   18.24  #  with the highest leaf
    19.1 --- a/tools/firmware/Makefile	Fri Mar 27 10:54:08 2009 +0900
    19.2 +++ b/tools/firmware/Makefile	Fri Mar 27 11:07:11 2009 +0900
    19.3 @@ -2,9 +2,8 @@ XEN_ROOT = ../..
    19.4  include $(XEN_ROOT)/tools/Rules.mk
    19.5  
    19.6  # hvmloader is a 32-bit protected mode binary.
    19.7 -# It belongs in /usr/lib, not /usr/lib64.
    19.8  TARGET      := hvmloader/hvmloader
    19.9 -INST_DIR := $(DESTDIR)/usr/lib/xen/boot
   19.10 +INST_DIR := $(DESTDIR)$(LIBDIR_x86_32)/xen/boot
   19.11  
   19.12  SUBDIRS :=
   19.13  SUBDIRS += rombios
    20.1 --- a/tools/firmware/hvmloader/acpi/dsdt.asl	Fri Mar 27 10:54:08 2009 +0900
    20.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl	Fri Mar 27 11:07:11 2009 +0900
    20.3 @@ -981,60 +981,1027 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
    20.4               * handle the hotplug action and status, which is beyond the ACPI
    20.5               * scope.
    20.6               */
    20.7 -
    20.8 -            Device (S1F0)
    20.9 +            Device(S00)
   20.10              {
   20.11 -                Name (_ADR, 0x00060000) /* Dev 6, Func 0 */
   20.12 -                Name (_SUN, 0x00000001)
   20.13 +                Name (_ADR, 0x00000000) /* Dev 0, Func 0 */
   20.14 +                Name (_SUN, 0x00000000)
   20.15  
   20.16                  Method (_PS0, 0)
   20.17                  {
   20.18 +                    Store (0x00, \_GPE.DPT1)
   20.19                      Store (0x80, \_GPE.DPT2)
   20.20                  }
   20.21  
   20.22                  Method (_PS3, 0)
   20.23                  {
   20.24 +                    Store (0x00, \_GPE.DPT1)
   20.25                      Store (0x83, \_GPE.DPT2)
   20.26                  }
   20.27  
   20.28                  Method (_EJ0, 1)
   20.29                  {
   20.30 +                    Store (0x00, \_GPE.DPT1)
   20.31                      Store (0x88, \_GPE.DPT2)
   20.32 -                    Store (0x1, \_GPE.PHP1) /* eject php slot 1*/
   20.33 +                    Store (0x1, \_GPE.PH00) /* eject php slot 0x00 */
   20.34                  }
   20.35  
   20.36                  Method (_STA, 0)
   20.37                  {
   20.38 +                    Store (0x00, \_GPE.DPT1)
   20.39                      Store (0x89, \_GPE.DPT2)
   20.40 -                    Return ( \_GPE.PHP1 )   /* IN status as the _STA */
   20.41 +                    Return (\_GPE.PH00) /* IN status as the _STA */
   20.42                  }
   20.43              }
   20.44  
   20.45 -            Device (S2F0)
   20.46 +            Device(S01)
   20.47              {
   20.48 -                Name (_ADR, 0x00070000) /* Dev 7, Func 0 */
   20.49 +                Name (_ADR, 0x00010000) /* Dev 1, Func 0 */
   20.50 +                Name (_SUN, 0x00000001)
   20.51 +
   20.52 +                Method (_PS0, 0)
   20.53 +                {
   20.54 +                    Store (0x01, \_GPE.DPT1)
   20.55 +                    Store (0x80, \_GPE.DPT2)
   20.56 +                }
   20.57 +
   20.58 +                Method (_PS3, 0)
   20.59 +                {
   20.60 +                    Store (0x01, \_GPE.DPT1)
   20.61 +                    Store (0x83, \_GPE.DPT2)
   20.62 +                }
   20.63 +
   20.64 +                Method (_EJ0, 1)
   20.65 +                {
   20.66 +                    Store (0x01, \_GPE.DPT1)
   20.67 +                    Store (0x88, \_GPE.DPT2)
   20.68 +                    Store (0x1, \_GPE.PH01) /* eject php slot 0x01 */
   20.69 +                }
   20.70 +
   20.71 +                Method (_STA, 0)
   20.72 +                {
   20.73 +                    Store (0x01, \_GPE.DPT1)
   20.74 +                    Store (0x89, \_GPE.DPT2)
   20.75 +                    Return (\_GPE.PH01) /* IN status as the _STA */
   20.76 +                }
   20.77 +            }
   20.78 +
   20.79 +            Device(S02)
   20.80 +            {
   20.81 +                Name (_ADR, 0x00020000) /* Dev 2, Func 0 */
   20.82                  Name (_SUN, 0x00000002)
   20.83  
   20.84                  Method (_PS0, 0)
   20.85                  {
   20.86 -                    Store (0x90, \_GPE.DPT2)
   20.87 +                    Store (0x02, \_GPE.DPT1)
   20.88 +                    Store (0x80, \_GPE.DPT2)
   20.89                  }
   20.90  
   20.91                  Method (_PS3, 0)
   20.92                  {
   20.93 -                    Store (0x93, \_GPE.DPT2)
   20.94 +                    Store (0x02, \_GPE.DPT1)
   20.95 +                    Store (0x83, \_GPE.DPT2)
   20.96                  }
   20.97  
   20.98                  Method (_EJ0, 1)
   20.99                  {
  20.100 -                    Store (0x98, \_GPE.DPT2)
  20.101 -                    Store (0x1, \_GPE.PHP2) /* eject php slot 1*/
  20.102 +                    Store (0x02, \_GPE.DPT1)
  20.103 +                    Store (0x88, \_GPE.DPT2)
  20.104 +                    Store (0x1, \_GPE.PH02) /* eject php slot 0x02 */
  20.105                  }
  20.106  
  20.107                  Method (_STA, 0)
  20.108                  {
  20.109 -                    Store (0x99, \_GPE.DPT2)
  20.110 -                    Return ( \_GPE.PHP2 )   /* IN status as the _STA */
  20.111 +                    Store (0x02, \_GPE.DPT1)
  20.112 +                    Store (0x89, \_GPE.DPT2)
  20.113 +                    Return (\_GPE.PH02) /* IN status as the _STA */
  20.114 +                }
  20.115 +            }
  20.116 +
  20.117 +            Device(S03)
  20.118 +            {
  20.119 +                Name (_ADR, 0x00030000) /* Dev 3, Func 0 */
  20.120 +                Name (_SUN, 0x00000003)
  20.121 +
  20.122 +                Method (_PS0, 0)
  20.123 +                {
  20.124 +                    Store (0x03, \_GPE.DPT1)
  20.125 +                    Store (0x80, \_GPE.DPT2)
  20.126 +                }
  20.127 +
  20.128 +                Method (_PS3, 0)
  20.129 +                {
  20.130 +                    Store (0x03, \_GPE.DPT1)
  20.131 +                    Store (0x83, \_GPE.DPT2)
  20.132 +                }
  20.133 +
  20.134 +                Method (_EJ0, 1)
  20.135 +                {
  20.136 +                    Store (0x03, \_GPE.DPT1)
  20.137 +                    Store (0x88, \_GPE.DPT2)
  20.138 +                    Store (0x1, \_GPE.PH03) /* eject php slot 0x03 */
  20.139 +                }
  20.140 +
  20.141 +                Method (_STA, 0)
  20.142 +                {
  20.143 +                    Store (0x03, \_GPE.DPT1)
  20.144 +                    Store (0x89, \_GPE.DPT2)
  20.145 +                    Return (\_GPE.PH03) /* IN status as the _STA */
  20.146 +                }
  20.147 +            }
  20.148 +
  20.149 +            Device(S04)
  20.150 +            {
  20.151 +                Name (_ADR, 0x00040000) /* Dev 4, Func 0 */
  20.152 +                Name (_SUN, 0x00000004)
  20.153 +
  20.154 +                Method (_PS0, 0)
  20.155 +                {
  20.156 +                    Store (0x04, \_GPE.DPT1)
  20.157 +                    Store (0x80, \_GPE.DPT2)
  20.158 +                }
  20.159 +
  20.160 +                Method (_PS3, 0)
  20.161 +                {
  20.162 +                    Store (0x04, \_GPE.DPT1)
  20.163 +                    Store (0x83, \_GPE.DPT2)
  20.164 +                }
  20.165 +
  20.166 +                Method (_EJ0, 1)
  20.167 +                {
  20.168 +                    Store (0x04, \_GPE.DPT1)
  20.169 +                    Store (0x88, \_GPE.DPT2)
  20.170 +                    Store (0x1, \_GPE.PH04) /* eject php slot 0x04 */
  20.171 +                }
  20.172 +
  20.173 +                Method (_STA, 0)
  20.174 +                {
  20.175 +                    Store (0x04, \_GPE.DPT1)
  20.176 +                    Store (0x89, \_GPE.DPT2)
  20.177 +                    Return (\_GPE.PH04) /* IN status as the _STA */
  20.178 +                }
  20.179 +            }
  20.180 +
  20.181 +            Device(S05)
  20.182 +            {
  20.183 +                Name (_ADR, 0x00050000) /* Dev 5, Func 0 */
  20.184 +                Name (_SUN, 0x00000005)
  20.185 +
  20.186 +                Method (_PS0, 0)
  20.187 +                {
  20.188 +                    Store (0x05, \_GPE.DPT1)
  20.189 +                    Store (0x80, \_GPE.DPT2)
  20.190 +                }
  20.191 +
  20.192 +                Method (_PS3, 0)
  20.193 +                {
  20.194 +                    Store (0x05, \_GPE.DPT1)
  20.195 +                    Store (0x83, \_GPE.DPT2)
  20.196 +                }
  20.197 +
  20.198 +                Method (_EJ0, 1)
  20.199 +                {
  20.200 +                    Store (0x05, \_GPE.DPT1)
  20.201 +                    Store (0x88, \_GPE.DPT2)
  20.202 +                    Store (0x1, \_GPE.PH05) /* eject php slot 0x05 */
  20.203 +                }
  20.204 +
  20.205 +                Method (_STA, 0)
  20.206 +                {
  20.207 +                    Store (0x05, \_GPE.DPT1)
  20.208 +                    Store (0x89, \_GPE.DPT2)
  20.209 +                    Return (\_GPE.PH05) /* IN status as the _STA */
  20.210 +                }
  20.211 +            }
  20.212 +
  20.213 +            Device(S06)
  20.214 +            {
  20.215 +                Name (_ADR, 0x00060000) /* Dev 6, Func 0 */
  20.216 +                Name (_SUN, 0x00000006)
  20.217 +
  20.218 +                Method (_PS0, 0)
  20.219 +                {
  20.220 +                    Store (0x06, \_GPE.DPT1)
  20.221 +                    Store (0x80, \_GPE.DPT2)
  20.222 +                }
  20.223 +
  20.224 +                Method (_PS3, 0)
  20.225 +                {
  20.226 +                    Store (0x06, \_GPE.DPT1)
  20.227 +                    Store (0x83, \_GPE.DPT2)
  20.228 +                }
  20.229 +
  20.230 +                Method (_EJ0, 1)
  20.231 +                {
  20.232 +                    Store (0x06, \_GPE.DPT1)
  20.233 +                    Store (0x88, \_GPE.DPT2)
  20.234 +                    Store (0x1, \_GPE.PH06) /* eject php slot 0x06 */
  20.235 +                }
  20.236 +
  20.237 +                Method (_STA, 0)
  20.238 +                {
  20.239 +                    Store (0x06, \_GPE.DPT1)
  20.240 +                    Store (0x89, \_GPE.DPT2)
  20.241 +                    Return (\_GPE.PH06) /* IN status as the _STA */
  20.242 +                }
  20.243 +            }
  20.244 +
  20.245 +            Device(S07)
  20.246 +            {
  20.247 +                Name (_ADR, 0x00070000) /* Dev 7, Func 0 */
  20.248 +                Name (_SUN, 0x00000007)
  20.249 +
  20.250 +                Method (_PS0, 0)
  20.251 +                {
  20.252 +                    Store (0x07, \_GPE.DPT1)
  20.253 +                    Store (0x80, \_GPE.DPT2)
  20.254 +                }
  20.255 +
  20.256 +                Method (_PS3, 0)
  20.257 +                {
  20.258 +                    Store (0x07, \_GPE.DPT1)
  20.259 +                    Store (0x83, \_GPE.DPT2)
  20.260 +                }
  20.261 +
  20.262 +                Method (_EJ0, 1)
  20.263 +                {
  20.264 +                    Store (0x07, \_GPE.DPT1)
  20.265 +                    Store (0x88, \_GPE.DPT2)
  20.266 +                    Store (0x1, \_GPE.PH07) /* eject php slot 0x07 */
  20.267 +                }
  20.268 +
  20.269 +                Method (_STA, 0)
  20.270 +                {
  20.271 +                    Store (0x07, \_GPE.DPT1)
  20.272 +                    Store (0x89, \_GPE.DPT2)
  20.273 +                    Return (\_GPE.PH07) /* IN status as the _STA */
  20.274 +                }
  20.275 +            }
  20.276 +
  20.277 +            Device(S08)
  20.278 +            {
  20.279 +                Name (_ADR, 0x00080000) /* Dev 8, Func 0 */
  20.280 +                Name (_SUN, 0x00000008)
  20.281 +
  20.282 +                Method (_PS0, 0)
  20.283 +                {
  20.284 +                    Store (0x08, \_GPE.DPT1)
  20.285 +                    Store (0x80, \_GPE.DPT2)
  20.286 +                }
  20.287 +
  20.288 +                Method (_PS3, 0)
  20.289 +                {
  20.290 +                    Store (0x08, \_GPE.DPT1)
  20.291 +                    Store (0x83, \_GPE.DPT2)
  20.292 +                }
  20.293 +
  20.294 +                Method (_EJ0, 1)
  20.295 +                {
  20.296 +                    Store (0x08, \_GPE.DPT1)
  20.297 +                    Store (0x88, \_GPE.DPT2)
  20.298 +                    Store (0x1, \_GPE.PH08) /* eject php slot 0x08 */
  20.299 +                }
  20.300 +
  20.301 +                Method (_STA, 0)
  20.302 +                {
  20.303 +                    Store (0x08, \_GPE.DPT1)
  20.304 +                    Store (0x89, \_GPE.DPT2)
  20.305 +                    Return (\_GPE.PH08) /* IN status as the _STA */
  20.306 +                }
  20.307 +            }
  20.308 +
  20.309 +            Device(S09)
  20.310 +            {
  20.311 +                Name (_ADR, 0x00090000) /* Dev 9, Func 0 */
  20.312 +                Name (_SUN, 0x00000009)
  20.313 +
  20.314 +                Method (_PS0, 0)
  20.315 +                {
  20.316 +                    Store (0x09, \_GPE.DPT1)
  20.317 +                    Store (0x80, \_GPE.DPT2)
  20.318 +                }
  20.319 +
  20.320 +                Method (_PS3, 0)
  20.321 +                {
  20.322 +                    Store (0x09, \_GPE.DPT1)
  20.323 +                    Store (0x83, \_GPE.DPT2)
  20.324 +                }
  20.325 +
  20.326 +                Method (_EJ0, 1)
  20.327 +                {
  20.328 +                    Store (0x09, \_GPE.DPT1)
  20.329 +                    Store (0x88, \_GPE.DPT2)
  20.330 +                    Store (0x1, \_GPE.PH09) /* eject php slot 0x09 */
  20.331 +                }
  20.332 +
  20.333 +                Method (_STA, 0)
  20.334 +                {
  20.335 +                    Store (0x09, \_GPE.DPT1)
  20.336 +                    Store (0x89, \_GPE.DPT2)
  20.337 +                    Return (\_GPE.PH09) /* IN status as the _STA */
  20.338 +                }
  20.339 +            }
  20.340 +
  20.341 +            Device(S0A)
  20.342 +            {
  20.343 +                Name (_ADR, 0x000a0000) /* Dev 10, Func 0 */
  20.344 +                Name (_SUN, 0x0000000a)
  20.345 +
  20.346 +                Method (_PS0, 0)
  20.347 +                {
  20.348 +                    Store (0x0a, \_GPE.DPT1)
  20.349 +                    Store (0x80, \_GPE.DPT2)
  20.350 +                }
  20.351 +
  20.352 +                Method (_PS3, 0)
  20.353 +                {
  20.354 +                    Store (0x0a, \_GPE.DPT1)
  20.355 +                    Store (0x83, \_GPE.DPT2)
  20.356 +                }
  20.357 +
  20.358 +                Method (_EJ0, 1)
  20.359 +                {
  20.360 +                    Store (0x0a, \_GPE.DPT1)
  20.361 +                    Store (0x88, \_GPE.DPT2)
  20.362 +                    Store (0x1, \_GPE.PH0A) /* eject php slot 0x0a */
  20.363 +                }
  20.364 +
  20.365 +                Method (_STA, 0)
  20.366 +                {
  20.367 +                    Store (0x0a, \_GPE.DPT1)
  20.368 +                    Store (0x89, \_GPE.DPT2)
  20.369 +                    Return (\_GPE.PH0A) /* IN status as the _STA */
  20.370 +                }
  20.371 +            }
  20.372 +
  20.373 +            Device(S0B)
  20.374 +            {
  20.375 +                Name (_ADR, 0x000b0000) /* Dev 11, Func 0 */
  20.376 +                Name (_SUN, 0x0000000b)
  20.377 +
  20.378 +                Method (_PS0, 0)
  20.379 +                {
  20.380 +                    Store (0x0b, \_GPE.DPT1)
  20.381 +                    Store (0x80, \_GPE.DPT2)
  20.382 +                }
  20.383 +
  20.384 +                Method (_PS3, 0)
  20.385 +                {
  20.386 +                    Store (0x0b, \_GPE.DPT1)
  20.387 +                    Store (0x83, \_GPE.DPT2)
  20.388 +                }
  20.389 +
  20.390 +                Method (_EJ0, 1)
  20.391 +                {
  20.392 +                    Store (0x0b, \_GPE.DPT1)
  20.393 +                    Store (0x88, \_GPE.DPT2)
  20.394 +                    Store (0x1, \_GPE.PH0B) /* eject php slot 0x0b */
  20.395 +                }
  20.396 +
  20.397 +                Method (_STA, 0)
  20.398 +                {
  20.399 +                    Store (0x0b, \_GPE.DPT1)
  20.400 +                    Store (0x89, \_GPE.DPT2)
  20.401 +                    Return (\_GPE.PH0B) /* IN status as the _STA */
  20.402 +                }
  20.403 +            }
  20.404 +
  20.405 +            Device(S0C)
  20.406 +            {
  20.407 +                Name (_ADR, 0x000c0000) /* Dev 12, Func 0 */
  20.408 +                Name (_SUN, 0x0000000c)
  20.409 +
  20.410 +                Method (_PS0, 0)
  20.411 +                {
  20.412 +                    Store (0x0c, \_GPE.DPT1)
  20.413 +                    Store (0x80, \_GPE.DPT2)
  20.414 +                }
  20.415 +
  20.416 +                Method (_PS3, 0)
  20.417 +                {
  20.418 +                    Store (0x0c, \_GPE.DPT1)
  20.419 +                    Store (0x83, \_GPE.DPT2)
  20.420 +                }
  20.421 +
  20.422 +                Method (_EJ0, 1)
  20.423 +                {
  20.424 +                    Store (0x0c, \_GPE.DPT1)
  20.425 +                    Store (0x88, \_GPE.DPT2)
  20.426 +                    Store (0x1, \_GPE.PH0C) /* eject php slot 0x0c */
  20.427 +                }
  20.428 +
  20.429 +                Method (_STA, 0)
  20.430 +                {
  20.431 +                    Store (0x0c, \_GPE.DPT1)
  20.432 +                    Store (0x89, \_GPE.DPT2)
  20.433 +                    Return (\_GPE.PH0C) /* IN status as the _STA */
  20.434 +                }
  20.435 +            }
  20.436 +
  20.437 +            Device(S0D)
  20.438 +            {
  20.439 +                Name (_ADR, 0x000d0000) /* Dev 13, Func 0 */
  20.440 +                Name (_SUN, 0x0000000d)
  20.441 +
  20.442 +                Method (_PS0, 0)
  20.443 +                {
  20.444 +                    Store (0x0d, \_GPE.DPT1)
  20.445 +                    Store (0x80, \_GPE.DPT2)
  20.446 +                }
  20.447 +
  20.448 +                Method (_PS3, 0)
  20.449 +                {
  20.450 +                    Store (0x0d, \_GPE.DPT1)
  20.451 +                    Store (0x83, \_GPE.DPT2)
  20.452 +                }
  20.453 +
  20.454 +                Method (_EJ0, 1)
  20.455 +                {
  20.456 +                    Store (0x0d, \_GPE.DPT1)
  20.457 +                    Store (0x88, \_GPE.DPT2)
  20.458 +                    Store (0x1, \_GPE.PH0D) /* eject php slot 0x0d */
  20.459 +                }
  20.460 +
  20.461 +                Method (_STA, 0)
  20.462 +                {
  20.463 +                    Store (0x0d, \_GPE.DPT1)
  20.464 +                    Store (0x89, \_GPE.DPT2)
  20.465 +                    Return (\_GPE.PH0D) /* IN status as the _STA */
  20.466 +                }
  20.467 +            }
  20.468 +
  20.469 +            Device(S0E)
  20.470 +            {
  20.471 +                Name (_ADR, 0x000e0000) /* Dev 14, Func 0 */
  20.472 +                Name (_SUN, 0x0000000e)
  20.473 +
  20.474 +                Method (_PS0, 0)
  20.475 +                {
  20.476 +                    Store (0x0e, \_GPE.DPT1)
  20.477 +                    Store (0x80, \_GPE.DPT2)
  20.478 +                }
  20.479 +
  20.480 +                Method (_PS3, 0)
  20.481 +                {
  20.482 +                    Store (0x0e, \_GPE.DPT1)
  20.483 +                    Store (0x83, \_GPE.DPT2)
  20.484 +                }
  20.485 +
  20.486 +                Method (_EJ0, 1)
  20.487 +                {
  20.488 +                    Store (0x0e, \_GPE.DPT1)
  20.489 +                    Store (0x88, \_GPE.DPT2)
  20.490 +                    Store (0x1, \_GPE.PH0E) /* eject php slot 0x0e */
  20.491 +                }
  20.492 +
  20.493 +                Method (_STA, 0)
  20.494 +                {
  20.495 +                    Store (0x0e, \_GPE.DPT1)
  20.496 +                    Store (0x89, \_GPE.DPT2)
  20.497 +                    Return (\_GPE.PH0E) /* IN status as the _STA */
  20.498 +                }
  20.499 +            }
  20.500 +
  20.501 +            Device(S0F)
  20.502 +            {
  20.503 +                Name (_ADR, 0x000f0000) /* Dev 15, Func 0 */
  20.504 +                Name (_SUN, 0x0000000f)
  20.505 +
  20.506 +                Method (_PS0, 0)
  20.507 +                {
  20.508 +                    Store (0x0f, \_GPE.DPT1)
  20.509 +                    Store (0x80, \_GPE.DPT2)
  20.510 +                }
  20.511 +
  20.512 +                Method (_PS3, 0)
  20.513 +                {
  20.514 +                    Store (0x0f, \_GPE.DPT1)
  20.515 +                    Store (0x83, \_GPE.DPT2)
  20.516 +                }
  20.517 +
  20.518 +                Method (_EJ0, 1)
  20.519 +                {
  20.520 +                    Store (0x0f, \_GPE.DPT1)
  20.521 +                    Store (0x88, \_GPE.DPT2)
  20.522 +                    Store (0x1, \_GPE.PH0F) /* eject php slot 0x0f */
  20.523 +                }
  20.524 +
  20.525 +                Method (_STA, 0)
  20.526 +                {
  20.527 +                    Store (0x0f, \_GPE.DPT1)
  20.528 +                    Store (0x89, \_GPE.DPT2)
  20.529 +                    Return (\_GPE.PH0F) /* IN status as the _STA */
  20.530 +                }
  20.531 +            }
  20.532 +
  20.533 +            Device(S10)
  20.534 +            {
  20.535 +                Name (_ADR, 0x00100000) /* Dev 16, Func 0 */
  20.536 +                Name (_SUN, 0x00000010)
  20.537 +
  20.538 +                Method (_PS0, 0)
  20.539 +                {
  20.540 +                    Store (0x10, \_GPE.DPT1)
  20.541 +                    Store (0x80, \_GPE.DPT2)
  20.542 +                }
  20.543 +
  20.544 +                Method (_PS3, 0)
  20.545 +                {
  20.546 +                    Store (0x10, \_GPE.DPT1)
  20.547 +                    Store (0x83, \_GPE.DPT2)
  20.548 +                }
  20.549 +
  20.550 +                Method (_EJ0, 1)
  20.551 +                {
  20.552 +                    Store (0x10, \_GPE.DPT1)
  20.553 +                    Store (0x88, \_GPE.DPT2)
  20.554 +                    Store (0x1, \_GPE.PH10) /* eject php slot 0x10 */
  20.555 +                }
  20.556 +
  20.557 +                Method (_STA, 0)
  20.558 +                {
  20.559 +                    Store (0x10, \_GPE.DPT1)
  20.560 +                    Store (0x89, \_GPE.DPT2)
  20.561 +                    Return (\_GPE.PH10) /* IN status as the _STA */
  20.562 +                }
  20.563 +            }
  20.564 +
  20.565 +            Device(S11)
  20.566 +            {
  20.567 +                Name (_ADR, 0x00110000) /* Dev 17, Func 0 */
  20.568 +                Name (_SUN, 0x00000011)
  20.569 +
  20.570 +                Method (_PS0, 0)
  20.571 +                {
  20.572 +                    Store (0x11, \_GPE.DPT1)
  20.573 +                    Store (0x80, \_GPE.DPT2)
  20.574 +                }
  20.575 +
  20.576 +                Method (_PS3, 0)
  20.577 +                {
  20.578 +                    Store (0x11, \_GPE.DPT1)
  20.579 +                    Store (0x83, \_GPE.DPT2)
  20.580 +                }
  20.581 +
  20.582 +                Method (_EJ0, 1)
  20.583 +                {
  20.584 +                    Store (0x11, \_GPE.DPT1)
  20.585 +                    Store (0x88, \_GPE.DPT2)
  20.586 +                    Store (0x1, \_GPE.PH11) /* eject php slot 0x11 */
  20.587 +                }
  20.588 +
  20.589 +                Method (_STA, 0)
  20.590 +                {
  20.591 +                    Store (0x11, \_GPE.DPT1)
  20.592 +                    Store (0x89, \_GPE.DPT2)
  20.593 +                    Return (\_GPE.PH11) /* IN status as the _STA */
  20.594 +                }
  20.595 +            }
  20.596 +
  20.597 +            Device(S12)
  20.598 +            {
  20.599 +                Name (_ADR, 0x00120000) /* Dev 18, Func 0 */
  20.600 +                Name (_SUN, 0x00000012)
  20.601 +
  20.602 +                Method (_PS0, 0)
  20.603 +                {
  20.604 +                    Store (0x12, \_GPE.DPT1)
  20.605 +                    Store (0x80, \_GPE.DPT2)
  20.606 +                }
  20.607 +
  20.608 +                Method (_PS3, 0)
  20.609 +                {
  20.610 +                    Store (0x12, \_GPE.DPT1)
  20.611 +                    Store (0x83, \_GPE.DPT2)
  20.612 +                }
  20.613 +
  20.614 +                Method (_EJ0, 1)
  20.615 +                {
  20.616 +                    Store (0x12, \_GPE.DPT1)
  20.617 +                    Store (0x88, \_GPE.DPT2)
  20.618 +                    Store (0x1, \_GPE.PH12) /* eject php slot 0x12 */
  20.619 +                }
  20.620 +
  20.621 +                Method (_STA, 0)
  20.622 +                {
  20.623 +                    Store (0x12, \_GPE.DPT1)
  20.624 +                    Store (0x89, \_GPE.DPT2)
  20.625 +                    Return (\_GPE.PH12) /* IN status as the _STA */
  20.626 +                }
  20.627 +            }
  20.628 +
  20.629 +            Device(S13)
  20.630 +            {
  20.631 +                Name (_ADR, 0x00130000) /* Dev 19, Func 0 */
  20.632 +                Name (_SUN, 0x00000013)
  20.633 +
  20.634 +                Method (_PS0, 0)
  20.635 +                {
  20.636 +                    Store (0x13, \_GPE.DPT1)
  20.637 +                    Store (0x80, \_GPE.DPT2)
  20.638 +                }
  20.639 +
  20.640 +                Method (_PS3, 0)
  20.641 +                {
  20.642 +                    Store (0x13, \_GPE.DPT1)
  20.643 +                    Store (0x83, \_GPE.DPT2)
  20.644 +                }
  20.645 +
  20.646 +                Method (_EJ0, 1)
  20.647 +                {
  20.648 +                    Store (0x13, \_GPE.DPT1)
  20.649 +                    Store (0x88, \_GPE.DPT2)
  20.650 +                    Store (0x1, \_GPE.PH13) /* eject php slot 0x13 */
  20.651 +                }
  20.652 +
  20.653 +                Method (_STA, 0)
  20.654 +                {
  20.655 +                    Store (0x13, \_GPE.DPT1)
  20.656 +                    Store (0x89, \_GPE.DPT2)
  20.657 +                    Return (\_GPE.PH13) /* IN status as the _STA */
  20.658 +                }
  20.659 +            }
  20.660 +
  20.661 +            Device(S14)
  20.662 +            {
  20.663 +                Name (_ADR, 0x00140000) /* Dev 20, Func 0 */
  20.664 +                Name (_SUN, 0x00000014)
  20.665 +
  20.666 +                Method (_PS0, 0)
  20.667 +                {
  20.668 +                    Store (0x14, \_GPE.DPT1)
  20.669 +                    Store (0x80, \_GPE.DPT2)
  20.670 +                }
  20.671 +
  20.672 +                Method (_PS3, 0)
  20.673 +                {
  20.674 +                    Store (0x14, \_GPE.DPT1)
  20.675 +                    Store (0x83, \_GPE.DPT2)
  20.676 +                }
  20.677 +
  20.678 +                Method (_EJ0, 1)
  20.679 +                {
  20.680 +                    Store (0x14, \_GPE.DPT1)
  20.681 +                    Store (0x88, \_GPE.DPT2)
  20.682 +                    Store (0x1, \_GPE.PH14) /* eject php slot 0x14 */
  20.683 +                }
  20.684 +
  20.685 +                Method (_STA, 0)
  20.686 +                {
  20.687 +                    Store (0x14, \_GPE.DPT1)
  20.688 +                    Store (0x89, \_GPE.DPT2)
  20.689 +                    Return (\_GPE.PH14) /* IN status as the _STA */
  20.690 +                }
  20.691 +            }
  20.692 +
  20.693 +            Device(S15)
  20.694 +            {
  20.695 +                Name (_ADR, 0x00150000) /* Dev 21, Func 0 */
  20.696 +                Name (_SUN, 0x00000015)
  20.697 +
  20.698 +                Method (_PS0, 0)
  20.699 +                {
  20.700 +                    Store (0x15, \_GPE.DPT1)
  20.701 +                    Store (0x80, \_GPE.DPT2)
  20.702 +                }
  20.703 +
  20.704 +                Method (_PS3, 0)
  20.705 +                {
  20.706 +                    Store (0x15, \_GPE.DPT1)
  20.707 +                    Store (0x83, \_GPE.DPT2)
  20.708 +                }
  20.709 +
  20.710 +                Method (_EJ0, 1)
  20.711 +                {
  20.712 +                    Store (0x15, \_GPE.DPT1)
  20.713 +                    Store (0x88, \_GPE.DPT2)
  20.714 +                    Store (0x1, \_GPE.PH15) /* eject php slot 0x15 */
  20.715 +                }
  20.716 +
  20.717 +                Method (_STA, 0)
  20.718 +                {
  20.719 +                    Store (0x15, \_GPE.DPT1)
  20.720 +                    Store (0x89, \_GPE.DPT2)
  20.721 +                    Return (\_GPE.PH15) /* IN status as the _STA */
  20.722 +                }
  20.723 +            }
  20.724 +
  20.725 +            Device(S16)
  20.726 +            {
  20.727 +                Name (_ADR, 0x00160000) /* Dev 22, Func 0 */
  20.728 +                Name (_SUN, 0x00000016)
  20.729 +
  20.730 +                Method (_PS0, 0)
  20.731 +                {
  20.732 +                    Store (0x16, \_GPE.DPT1)
  20.733 +                    Store (0x80, \_GPE.DPT2)
  20.734 +                }
  20.735 +
  20.736 +                Method (_PS3, 0)
  20.737 +                {
  20.738 +                    Store (0x16, \_GPE.DPT1)
  20.739 +                    Store (0x83, \_GPE.DPT2)
  20.740 +                }
  20.741 +
  20.742 +                Method (_EJ0, 1)
  20.743 +                {
  20.744 +                    Store (0x16, \_GPE.DPT1)
  20.745 +                    Store (0x88, \_GPE.DPT2)
  20.746 +                    Store (0x1, \_GPE.PH16) /* eject php slot 0x16 */
  20.747 +                }
  20.748 +
  20.749 +                Method (_STA, 0)
  20.750 +                {
  20.751 +                    Store (0x16, \_GPE.DPT1)
  20.752 +                    Store (0x89, \_GPE.DPT2)
  20.753 +                    Return (\_GPE.PH16) /* IN status as the _STA */
  20.754 +                }
  20.755 +            }
  20.756 +
  20.757 +            Device(S17)
  20.758 +            {
  20.759 +                Name (_ADR, 0x00170000) /* Dev 23, Func 0 */
  20.760 +                Name (_SUN, 0x00000017)
  20.761 +
  20.762 +                Method (_PS0, 0)
  20.763 +                {
  20.764 +                    Store (0x17, \_GPE.DPT1)
  20.765 +                    Store (0x80, \_GPE.DPT2)
  20.766 +                }
  20.767 +
  20.768 +                Method (_PS3, 0)
  20.769 +                {
  20.770 +                    Store (0x17, \_GPE.DPT1)
  20.771 +                    Store (0x83, \_GPE.DPT2)
  20.772 +                }
  20.773 +
  20.774 +                Method (_EJ0, 1)
  20.775 +                {
  20.776 +                    Store (0x17, \_GPE.DPT1)
  20.777 +                    Store (0x88, \_GPE.DPT2)
  20.778 +                    Store (0x1, \_GPE.PH17) /* eject php slot 0x17 */
  20.779 +                }
  20.780 +
  20.781 +                Method (_STA, 0)
  20.782 +                {
  20.783 +                    Store (0x17, \_GPE.DPT1)
  20.784 +                    Store (0x89, \_GPE.DPT2)
  20.785 +                    Return (\_GPE.PH17) /* IN status as the _STA */
  20.786 +                }
  20.787 +            }
  20.788 +
  20.789 +            Device(S18)
  20.790 +            {
  20.791 +                Name (_ADR, 0x00180000) /* Dev 24, Func 0 */
  20.792 +                Name (_SUN, 0x00000018)
  20.793 +
  20.794 +                Method (_PS0, 0)
  20.795 +                {
  20.796 +                    Store (0x18, \_GPE.DPT1)
  20.797 +                    Store (0x80, \_GPE.DPT2)
  20.798 +                }
  20.799 +
  20.800 +                Method (_PS3, 0)
  20.801 +                {
  20.802 +                    Store (0x18, \_GPE.DPT1)
  20.803 +                    Store (0x83, \_GPE.DPT2)
  20.804 +                }
  20.805 +
  20.806 +                Method (_EJ0, 1)
  20.807 +                {
  20.808 +                    Store (0x18, \_GPE.DPT1)
  20.809 +                    Store (0x88, \_GPE.DPT2)
  20.810 +                    Store (0x1, \_GPE.PH18) /* eject php slot 0x18 */
  20.811 +                }
  20.812 +
  20.813 +                Method (_STA, 0)
  20.814 +                {
  20.815 +                    Store (0x18, \_GPE.DPT1)
  20.816 +                    Store (0x89, \_GPE.DPT2)
  20.817 +                    Return (\_GPE.PH18) /* IN status as the _STA */
  20.818 +                }
  20.819 +            }
  20.820 +
  20.821 +            Device(S19)
  20.822 +            {
  20.823 +                Name (_ADR, 0x00190000) /* Dev 25, Func 0 */
  20.824 +                Name (_SUN, 0x00000019)
  20.825 +
  20.826 +                Method (_PS0, 0)
  20.827 +                {
  20.828 +                    Store (0x19, \_GPE.DPT1)
  20.829 +                    Store (0x80, \_GPE.DPT2)
  20.830 +                }
  20.831 +
  20.832 +                Method (_PS3, 0)
  20.833 +                {
  20.834 +                    Store (0x19, \_GPE.DPT1)
  20.835 +                    Store (0x83, \_GPE.DPT2)
  20.836 +                }
  20.837 +
  20.838 +                Method (_EJ0, 1)
  20.839 +                {
  20.840 +                    Store (0x19, \_GPE.DPT1)
  20.841 +                    Store (0x88, \_GPE.DPT2)
  20.842 +                    Store (0x1, \_GPE.PH19) /* eject php slot 0x19 */
  20.843 +                }
  20.844 +
  20.845 +                Method (_STA, 0)
  20.846 +                {
  20.847 +                    Store (0x19, \_GPE.DPT1)
  20.848 +                    Store (0x89, \_GPE.DPT2)
  20.849 +                    Return (\_GPE.PH19) /* IN status as the _STA */
  20.850 +                }
  20.851 +            }
  20.852 +
  20.853 +            Device(S1A)
  20.854 +            {
  20.855 +                Name (_ADR, 0x001a0000) /* Dev 26, Func 0 */
  20.856 +                Name (_SUN, 0x0000001a)
  20.857 +
  20.858 +                Method (_PS0, 0)
  20.859 +                {
  20.860 +                    Store (0x1a, \_GPE.DPT1)
  20.861 +                    Store (0x80, \_GPE.DPT2)
  20.862 +                }
  20.863 +
  20.864 +                Method (_PS3, 0)
  20.865 +                {
  20.866 +                    Store (0x1a, \_GPE.DPT1)
  20.867 +                    Store (0x83, \_GPE.DPT2)
  20.868 +                }
  20.869 +
  20.870 +                Method (_EJ0, 1)
  20.871 +                {
  20.872 +                    Store (0x1a, \_GPE.DPT1)
  20.873 +                    Store (0x88, \_GPE.DPT2)
  20.874 +                    Store (0x1, \_GPE.PH1A) /* eject php slot 0x1a */
  20.875 +                }
  20.876 +
  20.877 +                Method (_STA, 0)
  20.878 +                {
  20.879 +                    Store (0x1a, \_GPE.DPT1)
  20.880 +                    Store (0x89, \_GPE.DPT2)
  20.881 +                    Return (\_GPE.PH1A) /* IN status as the _STA */
  20.882 +                }
  20.883 +            }
  20.884 +
  20.885 +            Device(S1B)
  20.886 +            {
  20.887 +                Name (_ADR, 0x001b0000) /* Dev 27, Func 0 */
  20.888 +                Name (_SUN, 0x0000001b)
  20.889 +
  20.890 +                Method (_PS0, 0)
  20.891 +                {
  20.892 +                    Store (0x1b, \_GPE.DPT1)
  20.893 +                    Store (0x80, \_GPE.DPT2)
  20.894 +                }
  20.895 +
  20.896 +                Method (_PS3, 0)
  20.897 +                {
  20.898 +                    Store (0x1b, \_GPE.DPT1)
  20.899 +                    Store (0x83, \_GPE.DPT2)
  20.900 +                }
  20.901 +
  20.902 +                Method (_EJ0, 1)
  20.903 +                {
  20.904 +                    Store (0x1b, \_GPE.DPT1)
  20.905 +                    Store (0x88, \_GPE.DPT2)
  20.906 +                    Store (0x1, \_GPE.PH1B) /* eject php slot 0x1b */
  20.907 +                }
  20.908 +
  20.909 +                Method (_STA, 0)
  20.910 +                {
  20.911 +                    Store (0x1b, \_GPE.DPT1)
  20.912 +                    Store (0x89, \_GPE.DPT2)
  20.913 +                    Return (\_GPE.PH1B) /* IN status as the _STA */
  20.914 +                }
  20.915 +            }
  20.916 +
  20.917 +            Device(S1C)
  20.918 +            {
  20.919 +                Name (_ADR, 0x001c0000) /* Dev 28, Func 0 */
  20.920 +                Name (_SUN, 0x0000001c)
  20.921 +
  20.922 +                Method (_PS0, 0)
  20.923 +                {
  20.924 +                    Store (0x1c, \_GPE.DPT1)
  20.925 +                    Store (0x80, \_GPE.DPT2)
  20.926 +                }
  20.927 +
  20.928 +                Method (_PS3, 0)
  20.929 +                {
  20.930 +                    Store (0x1c, \_GPE.DPT1)
  20.931 +                    Store (0x83, \_GPE.DPT2)
  20.932 +                }
  20.933 +
  20.934 +                Method (_EJ0, 1)
  20.935 +                {
  20.936 +                    Store (0x1c, \_GPE.DPT1)
  20.937 +                    Store (0x88, \_GPE.DPT2)
  20.938 +                    Store (0x1, \_GPE.PH1C) /* eject php slot 0x1c */
  20.939 +                }
  20.940 +
  20.941 +                Method (_STA, 0)
  20.942 +                {
  20.943 +                    Store (0x1c, \_GPE.DPT1)
  20.944 +                    Store (0x89, \_GPE.DPT2)
  20.945 +                    Return (\_GPE.PH1C) /* IN status as the _STA */
  20.946 +                }
  20.947 +            }
  20.948 +
  20.949 +            Device(S1D)
  20.950 +            {
  20.951 +                Name (_ADR, 0x001d0000) /* Dev 29, Func 0 */
  20.952 +                Name (_SUN, 0x0000001d)
  20.953 +
  20.954 +                Method (_PS0, 0)
  20.955 +                {
  20.956 +                    Store (0x1d, \_GPE.DPT1)
  20.957 +                    Store (0x80, \_GPE.DPT2)
  20.958 +                }
  20.959 +
  20.960 +                Method (_PS3, 0)
  20.961 +                {
  20.962 +                    Store (0x1d, \_GPE.DPT1)
  20.963 +                    Store (0x83, \_GPE.DPT2)
  20.964 +                }
  20.965 +
  20.966 +                Method (_EJ0, 1)
  20.967 +                {
  20.968 +                    Store (0x1d, \_GPE.DPT1)
  20.969 +                    Store (0x88, \_GPE.DPT2)
  20.970 +                    Store (0x1, \_GPE.PH1D) /* eject php slot 0x1d */
  20.971 +                }
  20.972 +
  20.973 +                Method (_STA, 0)
  20.974 +                {
  20.975 +                    Store (0x1d, \_GPE.DPT1)
  20.976 +                    Store (0x89, \_GPE.DPT2)
  20.977 +                    Return (\_GPE.PH1D) /* IN status as the _STA */
  20.978 +                }
  20.979 +            }
  20.980 +
  20.981 +            Device(S1E)
  20.982 +            {
  20.983 +                Name (_ADR, 0x001e0000) /* Dev 30, Func 0 */
  20.984 +                Name (_SUN, 0x0000001e)
  20.985 +
  20.986 +                Method (_PS0, 0)
  20.987 +                {
  20.988 +                    Store (0x1e, \_GPE.DPT1)
  20.989 +                    Store (0x80, \_GPE.DPT2)
  20.990 +                }
  20.991 +
  20.992 +                Method (_PS3, 0)
  20.993 +                {
  20.994 +                    Store (0x1e, \_GPE.DPT1)
  20.995 +                    Store (0x83, \_GPE.DPT2)
  20.996 +                }
  20.997 +
  20.998 +                Method (_EJ0, 1)
  20.999 +                {
 20.1000 +                    Store (0x1e, \_GPE.DPT1)
 20.1001 +                    Store (0x88, \_GPE.DPT2)
 20.1002 +                    Store (0x1, \_GPE.PH1E) /* eject php slot 0x1e */
 20.1003 +                }
 20.1004 +
 20.1005 +                Method (_STA, 0)
 20.1006 +                {
 20.1007 +                    Store (0x1e, \_GPE.DPT1)
 20.1008 +                    Store (0x89, \_GPE.DPT2)
 20.1009 +                    Return (\_GPE.PH1E) /* IN status as the _STA */
 20.1010 +                }
 20.1011 +            }
 20.1012 +
 20.1013 +            Device(S1F)
 20.1014 +            {
 20.1015 +                Name (_ADR, 0x001f0000) /* Dev 31, Func 0 */
 20.1016 +                Name (_SUN, 0x0000001f)
 20.1017 +
 20.1018 +                Method (_PS0, 0)
 20.1019 +                {
 20.1020 +                    Store (0x1f, \_GPE.DPT1)
 20.1021 +                    Store (0x80, \_GPE.DPT2)
 20.1022 +                }
 20.1023 +
 20.1024 +                Method (_PS3, 0)
 20.1025 +                {
 20.1026 +                    Store (0x1f, \_GPE.DPT1)
 20.1027 +                    Store (0x83, \_GPE.DPT2)
 20.1028 +                }
 20.1029 +
 20.1030 +                Method (_EJ0, 1)
 20.1031 +                {
 20.1032 +                    Store (0x1f, \_GPE.DPT1)
 20.1033 +                    Store (0x88, \_GPE.DPT2)
 20.1034 +                    Store (0x1, \_GPE.PH1F) /* eject php slot 0x1f */
 20.1035 +                }
 20.1036 +
 20.1037 +                Method (_STA, 0)
 20.1038 +                {
 20.1039 +                    Store (0x1f, \_GPE.DPT1)
 20.1040 +                    Store (0x89, \_GPE.DPT2)
 20.1041 +                    Return (\_GPE.PH1F) /* IN status as the _STA */
 20.1042                  }
 20.1043              }
 20.1044          }
 20.1045 @@ -1042,39 +2009,162 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
 20.1046  
 20.1047      Scope (\_GPE)
 20.1048      {
 20.1049 -        OperationRegion (PHP, SystemIO, 0x10c0, 0x03)
 20.1050 +        OperationRegion (PHP, SystemIO, 0x10c0, 0x22)
 20.1051          Field (PHP, ByteAcc, NoLock, Preserve)
 20.1052          {
 20.1053 -            PSTA,   8, /* hotplug controller status reg */
 20.1054 -            PHP1,   8, /* hotplug slot 1 control reg */
 20.1055 -            PHP2,   8  /* hotplug slot 2 control reg */
 20.1056 -        }
 20.1057 +            PSTA,  8, /* hotplug controller event reg */
 20.1058 +            PSTB,  8, /* hotplug controller slot  reg */
 20.1059 +            PH00,  8, /* hotplug slot 0x00 control reg */
 20.1060 +            PH01,  8, /* hotplug slot 0x01 control reg */
 20.1061 +            PH02,  8, /* hotplug slot 0x02 control reg */
 20.1062 +            PH03,  8, /* hotplug slot 0x03 control reg */
 20.1063 +            PH04,  8, /* hotplug slot 0x04 control reg */
 20.1064 +            PH05,  8, /* hotplug slot 0x05 control reg */
 20.1065 +            PH06,  8, /* hotplug slot 0x06 control reg */
 20.1066 +            PH07,  8, /* hotplug slot 0x07 control reg */
 20.1067 +            PH08,  8, /* hotplug slot 0x08 control reg */
 20.1068 +            PH09,  8, /* hotplug slot 0x09 control reg */
 20.1069 +            PH0A,  8, /* hotplug slot 0x0a control reg */
 20.1070 +            PH0B,  8, /* hotplug slot 0x0b control reg */
 20.1071 +            PH0C,  8, /* hotplug slot 0x0c control reg */
 20.1072 +            PH0D,  8, /* hotplug slot 0x0d control reg */
 20.1073 +            PH0E,  8, /* hotplug slot 0x0e control reg */
 20.1074 +            PH0F,  8, /* hotplug slot 0x0f control reg */
 20.1075 +            PH10,  8, /* hotplug slot 0x10 control reg */
 20.1076 +            PH11,  8, /* hotplug slot 0x11 control reg */
 20.1077 +            PH12,  8, /* hotplug slot 0x12 control reg */
 20.1078 +            PH13,  8, /* hotplug slot 0x13 control reg */
 20.1079 +            PH14,  8, /* hotplug slot 0x14 control reg */
 20.1080 +            PH15,  8, /* hotplug slot 0x15 control reg */
 20.1081 +            PH16,  8, /* hotplug slot 0x16 control reg */
 20.1082 +            PH17,  8, /* hotplug slot 0x17 control reg */
 20.1083 +            PH18,  8, /* hotplug slot 0x18 control reg */
 20.1084 +            PH19,  8, /* hotplug slot 0x19 control reg */
 20.1085 +            PH1A,  8, /* hotplug slot 0x1a control reg */
 20.1086 +            PH1B,  8, /* hotplug slot 0x1b control reg */
 20.1087 +            PH1C,  8, /* hotplug slot 0x1c control reg */
 20.1088 +            PH1D,  8, /* hotplug slot 0x1d control reg */
 20.1089 +            PH1E,  8, /* hotplug slot 0x1e control reg */
 20.1090 +            PH1F,  8  /* hotplug slot 0x1f control reg */
 20.1091 +       }
 20.1092          OperationRegion (DG1, SystemIO, 0xb044, 0x04)
 20.1093          Field (DG1, ByteAcc, NoLock, Preserve)
 20.1094          {
 20.1095              DPT1,   8,
 20.1096              DPT2,   8
 20.1097          }
 20.1098 -        Method (_L03, 0, NotSerialized)
 20.1099 +        Method (_L03, 0, Serialized)
 20.1100          {
 20.1101              /* detect slot and event(remove/add) */
 20.1102              Name (SLT, 0x0)
 20.1103              Name (EVT, 0x0)
 20.1104              Store (PSTA, Local1)
 20.1105 -            ShiftRight (Local1, 0x4, SLT)
 20.1106              And (Local1, 0xf, EVT)
 20.1107 +            Store (PSTB, Local1)           /* XXX: Store (PSTB, SLT) ? */
 20.1108 +            And (Local1, 0xff, SLT)
 20.1109  
 20.1110              /* debug */
 20.1111              Store (SLT, DPT1)
 20.1112              Store (EVT, DPT2)
 20.1113  
 20.1114 -            If ( LEqual(SLT, 0x1) )
 20.1115 +            Switch (SLT)
 20.1116              {
 20.1117 -                Notify (\_SB.PCI0.S1F0, EVT)
 20.1118 -            }
 20.1119 -            ElseIf ( LEqual(SLT, 0x2) )
 20.1120 -            {
 20.1121 -                Notify (\_SB.PCI0.S2F0, EVT)
 20.1122 +                Case (0x00) {
 20.1123 +                    Notify (\_SB.PCI0.S00, EVT)
 20.1124 +                }
 20.1125 +                Case (0x01) {
 20.1126 +                    Notify (\_SB.PCI0.S01, EVT)
 20.1127 +                }
 20.1128 +                Case (0x02) {
 20.1129 +                    Notify (\_SB.PCI0.S02, EVT)
 20.1130 +                }
 20.1131 +                Case (0x03) {
 20.1132 +                    Notify (\_SB.PCI0.S03, EVT)
 20.1133 +                }
 20.1134 +                Case (0x04) {
 20.1135 +                    Notify (\_SB.PCI0.S04, EVT)
 20.1136 +                }
 20.1137 +                Case (0x05) {
 20.1138 +                    Notify (\_SB.PCI0.S05, EVT)
 20.1139 +                }
 20.1140 +                Case (0x06) {
 20.1141 +                    Notify (\_SB.PCI0.S06, EVT)
 20.1142 +                }
 20.1143 +                Case (0x07) {
 20.1144 +                    Notify (\_SB.PCI0.S07, EVT)
 20.1145 +                }
 20.1146 +                Case (0x08) {
 20.1147 +                    Notify (\_SB.PCI0.S08, EVT)
 20.1148 +                }
 20.1149 +                Case (0x09) {
 20.1150 +                    Notify (\_SB.PCI0.S09, EVT)
 20.1151 +                }
 20.1152 +                Case (0x0a) {
 20.1153 +                    Notify (\_SB.PCI0.S0A, EVT)
 20.1154 +                }
 20.1155 +                Case (0x0b) {
 20.1156 +                    Notify (\_SB.PCI0.S0B, EVT)
 20.1157 +                }
 20.1158 +                Case (0x0c) {
 20.1159 +                    Notify (\_SB.PCI0.S0C, EVT)
 20.1160 +                }
 20.1161 +                Case (0x0d) {
 20.1162 +                    Notify (\_SB.PCI0.S0D, EVT)
 20.1163 +                }
 20.1164 +                Case (0x0e) {
 20.1165 +                    Notify (\_SB.PCI0.S0E, EVT)
 20.1166 +                }
 20.1167 +                Case (0x0f) {
 20.1168 +                    Notify (\_SB.PCI0.S0F, EVT)
 20.1169 +                }
 20.1170 +                Case (0x10) {
 20.1171 +                    Notify (\_SB.PCI0.S10, EVT)
 20.1172 +                }
 20.1173 +                Case (0x11) {
 20.1174 +                    Notify (\_SB.PCI0.S11, EVT)
 20.1175 +                }
 20.1176 +                Case (0x12) {
 20.1177 +                    Notify (\_SB.PCI0.S12, EVT)
 20.1178 +                }
 20.1179 +                Case (0x13) {
 20.1180 +                    Notify (\_SB.PCI0.S13, EVT)
 20.1181 +                }
 20.1182 +                Case (0x14) {
 20.1183 +                    Notify (\_SB.PCI0.S14, EVT)
 20.1184 +                }
 20.1185 +                Case (0x15) {
 20.1186 +                    Notify (\_SB.PCI0.S15, EVT)
 20.1187 +                }
 20.1188 +                Case (0x16) {
 20.1189 +                    Notify (\_SB.PCI0.S16, EVT)
 20.1190 +                }
 20.1191 +                Case (0x17) {
 20.1192 +                    Notify (\_SB.PCI0.S17, EVT)
 20.1193 +                }
 20.1194 +                Case (0x18) {
 20.1195 +                    Notify (\_SB.PCI0.S18, EVT)
 20.1196 +                }
 20.1197 +                Case (0x19) {
 20.1198 +                    Notify (\_SB.PCI0.S19, EVT)
 20.1199 +                }
 20.1200 +                Case (0x1a) {
 20.1201 +                    Notify (\_SB.PCI0.S1A, EVT)
 20.1202 +                }
 20.1203 +                Case (0x1b) {
 20.1204 +                    Notify (\_SB.PCI0.S1B, EVT)
 20.1205 +                }
 20.1206 +                Case (0x1c) {
 20.1207 +                    Notify (\_SB.PCI0.S1C, EVT)
 20.1208 +                }
 20.1209 +                Case (0x1d) {
 20.1210 +                    Notify (\_SB.PCI0.S1D, EVT)
 20.1211 +                }
 20.1212 +                Case (0x1e) {
 20.1213 +                    Notify (\_SB.PCI0.S1E, EVT)
 20.1214 +                }
 20.1215 +                Case (0x1f) {
 20.1216 +                    Notify (\_SB.PCI0.S1F, EVT)
 20.1217 +                }
 20.1218              }
 20.1219          }
 20.1220      }
    21.1 --- a/tools/firmware/hvmloader/acpi/dsdt.c	Fri Mar 27 10:54:08 2009 +0900
    21.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.c	Fri Mar 27 11:07:11 2009 +0900
    21.3 @@ -5,15 +5,15 @@
    21.4   * Copyright (C) 2000 - 2009 Intel Corporation
    21.5   * Supports ACPI Specification Revision 3.0a
    21.6   * 
    21.7 - * Compilation of "dsdt.asl" - Mon Mar  9 09:11:00 2009
    21.8 + * Compilation of "dsdt.asl" - Tue Mar 17 10:44:21 2009
    21.9   * 
   21.10   * C source code output
   21.11   *
   21.12   */
   21.13  unsigned char AmlCode[] =
   21.14  {
   21.15 -    0x44,0x53,0x44,0x54,0x20,0x18,0x00,0x00,  /* 00000000    "DSDT ..." */
   21.16 -    0x02,0x5B,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    ".[Xen..." */
   21.17 +    0x44,0x53,0x44,0x54,0x02,0x32,0x00,0x00,  /* 00000000    "DSDT.2.." */
   21.18 +    0x02,0xC6,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
   21.19      0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00,  /* 00000010    "HVM....." */
   21.20      0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
   21.21      0x20,0x02,0x09,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    " .. .PMB" */
   21.22 @@ -56,7 +56,7 @@ unsigned char AmlCode[] =
   21.23      0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49,  /* 00000148    "......PI" */
   21.24      0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,  /* 00000150    "CD..._PI" */
   21.25      0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44,  /* 00000158    "C.phPICD" */
   21.26 -    0x10,0x80,0x60,0x01,0x5F,0x53,0x42,0x5F,  /* 00000160    "..`._SB_" */
   21.27 +    0x10,0x83,0xB7,0x02,0x5F,0x53,0x42,0x5F,  /* 00000160    "...._SB_" */
   21.28      0x5B,0x80,0x42,0x49,0x4F,0x53,0x00,0x0C,  /* 00000168    "[.BIOS.." */
   21.29      0x00,0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81,  /* 00000170    "......[." */
   21.30      0x21,0x42,0x49,0x4F,0x53,0x01,0x55,0x41,  /* 00000178    "!BIOS.UA" */
   21.31 @@ -72,8 +72,8 @@ unsigned char AmlCode[] =
   21.32      0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000001C8    "........" */
   21.33      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001D0    "........" */
   21.34      0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,  /* 000001D8    "........" */
   21.35 -    0x00,0x00,0x79,0x00,0x5B,0x82,0x8B,0x57,  /* 000001E0    "..y.[..W" */
   21.36 -    0x01,0x50,0x43,0x49,0x30,0x08,0x5F,0x48,  /* 000001E8    ".PCI0._H" */
   21.37 +    0x00,0x00,0x79,0x00,0x5B,0x82,0x8E,0xAE,  /* 000001E0    "..y.[..." */
   21.38 +    0x02,0x50,0x43,0x49,0x30,0x08,0x5F,0x48,  /* 000001E8    ".PCI0._H" */
   21.39      0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,  /* 000001F0    "ID.A...." */
   21.40      0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,0x41,  /* 000001F8    "_UID.._A" */
   21.41      0x44,0x52,0x00,0x08,0x5F,0x42,0x42,0x4E,  /* 00000200    "DR.._BBN" */
   21.42 @@ -728,62 +728,890 @@ unsigned char AmlCode[] =
   21.43      0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00001648    "....._CR" */
   21.44      0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x78,  /* 00001650    "S....G.x" */
   21.45      0x03,0x78,0x03,0x08,0x08,0x22,0x80,0x00,  /* 00001658    ".x...".." */
   21.46 -    0x79,0x00,0x5B,0x82,0x4D,0x07,0x53,0x31,  /* 00001660    "y.[.M.S1" */
   21.47 -    0x46,0x30,0x08,0x5F,0x41,0x44,0x52,0x0C,  /* 00001668    "F0._ADR." */
   21.48 -    0x00,0x00,0x06,0x00,0x08,0x5F,0x53,0x55,  /* 00001670    "....._SU" */
   21.49 -    0x4E,0x01,0x14,0x13,0x5F,0x50,0x53,0x30,  /* 00001678    "N..._PS0" */
   21.50 -    0x00,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001680    ".p..\._G" */
   21.51 -    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x13,  /* 00001688    "PEDPT2.." */
   21.52 -    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x83,  /* 00001690    "_PS3.p.." */
   21.53 -    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001698    "\._GPEDP" */
   21.54 -    0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,0x30,  /* 000016A0    "T2.._EJ0" */
   21.55 -    0x01,0x70,0x0A,0x88,0x5C,0x2E,0x5F,0x47,  /* 000016A8    ".p..\._G" */
   21.56 -    0x50,0x45,0x44,0x50,0x54,0x32,0x70,0x01,  /* 000016B0    "PEDPT2p." */
   21.57 -    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 000016B8    "\._GPEPH" */
   21.58 -    0x50,0x31,0x14,0x1E,0x5F,0x53,0x54,0x41,  /* 000016C0    "P1.._STA" */
   21.59 -    0x00,0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,  /* 000016C8    ".p..\._G" */
   21.60 -    0x50,0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,  /* 000016D0    "PEDPT2.\" */
   21.61 -    0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,0x50,  /* 000016D8    "._GPEPHP" */
   21.62 -    0x31,0x5B,0x82,0x4E,0x07,0x53,0x32,0x46,  /* 000016E0    "1[.N.S2F" */
   21.63 -    0x30,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,  /* 000016E8    "0._ADR.." */
   21.64 -    0x00,0x07,0x00,0x08,0x5F,0x53,0x55,0x4E,  /* 000016F0    "...._SUN" */
   21.65 -    0x0A,0x02,0x14,0x13,0x5F,0x50,0x53,0x30,  /* 000016F8    "...._PS0" */
   21.66 -    0x00,0x70,0x0A,0x90,0x5C,0x2E,0x5F,0x47,  /* 00001700    ".p..\._G" */
   21.67 -    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x13,  /* 00001708    "PEDPT2.." */
   21.68 -    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x93,  /* 00001710    "_PS3.p.." */
   21.69 -    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001718    "\._GPEDP" */
   21.70 -    0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,0x30,  /* 00001720    "T2.._EJ0" */
   21.71 -    0x01,0x70,0x0A,0x98,0x5C,0x2E,0x5F,0x47,  /* 00001728    ".p..\._G" */
   21.72 -    0x50,0x45,0x44,0x50,0x54,0x32,0x70,0x01,  /* 00001730    "PEDPT2p." */
   21.73 -    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 00001738    "\._GPEPH" */
   21.74 -    0x50,0x32,0x14,0x1E,0x5F,0x53,0x54,0x41,  /* 00001740    "P2.._STA" */
   21.75 -    0x00,0x70,0x0A,0x99,0x5C,0x2E,0x5F,0x47,  /* 00001748    ".p..\._G" */
   21.76 -    0x50,0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,  /* 00001750    "PEDPT2.\" */
   21.77 -    0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,0x50,  /* 00001758    "._GPEPHP" */
   21.78 -    0x32,0x10,0x4E,0x0B,0x5F,0x47,0x50,0x45,  /* 00001760    "2.N._GPE" */
   21.79 -    0x5B,0x80,0x50,0x48,0x50,0x5F,0x01,0x0B,  /* 00001768    "[.PHP_.." */
   21.80 -    0xC0,0x10,0x0A,0x03,0x5B,0x81,0x15,0x50,  /* 00001770    "....[..P" */
   21.81 -    0x48,0x50,0x5F,0x01,0x50,0x53,0x54,0x41,  /* 00001778    "HP_.PSTA" */
   21.82 -    0x08,0x50,0x48,0x50,0x31,0x08,0x50,0x48,  /* 00001780    ".PHP1.PH" */
   21.83 -    0x50,0x32,0x08,0x5B,0x80,0x44,0x47,0x31,  /* 00001788    "P2.[.DG1" */
   21.84 -    0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B,  /* 00001790    "_..D...[" */
   21.85 -    0x81,0x10,0x44,0x47,0x31,0x5F,0x01,0x44,  /* 00001798    "..DG1_.D" */
   21.86 -    0x50,0x54,0x31,0x08,0x44,0x50,0x54,0x32,  /* 000017A0    "PT1.DPT2" */
   21.87 -    0x08,0x14,0x46,0x07,0x5F,0x4C,0x30,0x33,  /* 000017A8    "..F._L03" */
   21.88 -    0x00,0x08,0x53,0x4C,0x54,0x5F,0x00,0x08,  /* 000017B0    "..SLT_.." */
   21.89 -    0x45,0x56,0x54,0x5F,0x00,0x70,0x50,0x53,  /* 000017B8    "EVT_.pPS" */
   21.90 -    0x54,0x41,0x61,0x7A,0x61,0x0A,0x04,0x53,  /* 000017C0    "TAaza..S" */
   21.91 -    0x4C,0x54,0x5F,0x7B,0x61,0x0A,0x0F,0x45,  /* 000017C8    "LT_{a..E" */
   21.92 -    0x56,0x54,0x5F,0x70,0x53,0x4C,0x54,0x5F,  /* 000017D0    "VT_pSLT_" */
   21.93 -    0x44,0x50,0x54,0x31,0x70,0x45,0x56,0x54,  /* 000017D8    "DPT1pEVT" */
   21.94 -    0x5F,0x44,0x50,0x54,0x32,0xA0,0x1B,0x93,  /* 000017E0    "_DPT2..." */
   21.95 -    0x53,0x4C,0x54,0x5F,0x01,0x86,0x5C,0x2F,  /* 000017E8    "SLT_..\/" */
   21.96 -    0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,  /* 000017F0    "._SB_PCI" */
   21.97 -    0x30,0x53,0x31,0x46,0x30,0x45,0x56,0x54,  /* 000017F8    "0S1F0EVT" */
   21.98 -    0x5F,0xA1,0x1E,0xA0,0x1C,0x93,0x53,0x4C,  /* 00001800    "_.....SL" */
   21.99 -    0x54,0x5F,0x0A,0x02,0x86,0x5C,0x2F,0x03,  /* 00001808    "T_...\/." */
  21.100 -    0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30,  /* 00001810    "_SB_PCI0" */
  21.101 -    0x53,0x32,0x46,0x30,0x45,0x56,0x54,0x5F,  /* 00001818    "S2F0EVT_" */
  21.102 -
  21.103 +    0x79,0x00,0x5B,0x82,0x49,0x0A,0x53,0x30,  /* 00001660    "y.[.I.S0" */
  21.104 +    0x30,0x5F,0x08,0x5F,0x41,0x44,0x52,0x00,  /* 00001668    "0_._ADR." */
  21.105 +    0x08,0x5F,0x53,0x55,0x4E,0x00,0x14,0x1F,  /* 00001670    "._SUN..." */
  21.106 +    0x5F,0x50,0x53,0x30,0x00,0x70,0x00,0x5C,  /* 00001678    "_PS0.p.\" */
  21.107 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001680    "._GPEDPT" */
  21.108 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001688    "1p..\._G" */
  21.109 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x1F,  /* 00001690    "PEDPT2.." */
  21.110 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x00,0x5C,  /* 00001698    "_PS3.p.\" */
  21.111 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000016A0    "._GPEDPT" */
  21.112 +    0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,0x47,  /* 000016A8    "1p..\._G" */
  21.113 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x2B,  /* 000016B0    "PEDPT2.+" */
  21.114 +    0x5F,0x45,0x4A,0x30,0x01,0x70,0x00,0x5C,  /* 000016B8    "_EJ0.p.\" */
  21.115 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000016C0    "._GPEDPT" */
  21.116 +    0x31,0x70,0x0A,0x88,0x5C,0x2E,0x5F,0x47,  /* 000016C8    "1p..\._G" */
  21.117 +    0x50,0x45,0x44,0x50,0x54,0x32,0x70,0x01,  /* 000016D0    "PEDPT2p." */
  21.118 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 000016D8    "\._GPEPH" */
  21.119 +    0x30,0x30,0x14,0x2A,0x5F,0x53,0x54,0x41,  /* 000016E0    "00.*_STA" */
  21.120 +    0x00,0x70,0x00,0x5C,0x2E,0x5F,0x47,0x50,  /* 000016E8    ".p.\._GP" */
  21.121 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x89,  /* 000016F0    "EDPT1p.." */
  21.122 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000016F8    "\._GPEDP" */
  21.123 +    0x54,0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001700    "T2.\._GP" */
  21.124 +    0x45,0x50,0x48,0x30,0x30,0x5B,0x82,0x4D,  /* 00001708    "EPH00[.M" */
  21.125 +    0x0A,0x53,0x30,0x31,0x5F,0x08,0x5F,0x41,  /* 00001710    ".S01_._A" */
  21.126 +    0x44,0x52,0x0C,0x00,0x00,0x01,0x00,0x08,  /* 00001718    "DR......" */
  21.127 +    0x5F,0x53,0x55,0x4E,0x01,0x14,0x1F,0x5F,  /* 00001720    "_SUN..._" */
  21.128 +    0x50,0x53,0x30,0x00,0x70,0x01,0x5C,0x2E,  /* 00001728    "PS0.p.\." */
  21.129 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001730    "_GPEDPT1" */
  21.130 +    0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001738    "p..\._GP" */
  21.131 +    0x45,0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,  /* 00001740    "EDPT2.._" */
  21.132 +    0x50,0x53,0x33,0x00,0x70,0x01,0x5C,0x2E,  /* 00001748    "PS3.p.\." */
  21.133 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001750    "_GPEDPT1" */
  21.134 +    0x70,0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001758    "p..\._GP" */
  21.135 +    0x45,0x44,0x50,0x54,0x32,0x14,0x2B,0x5F,  /* 00001760    "EDPT2.+_" */
  21.136 +    0x45,0x4A,0x30,0x01,0x70,0x01,0x5C,0x2E,  /* 00001768    "EJ0.p.\." */
  21.137 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001770    "_GPEDPT1" */
  21.138 +    0x70,0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001778    "p..\._GP" */
  21.139 +    0x45,0x44,0x50,0x54,0x32,0x70,0x01,0x5C,  /* 00001780    "EDPT2p.\" */
  21.140 +    0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,0x30,  /* 00001788    "._GPEPH0" */
  21.141 +    0x31,0x14,0x2A,0x5F,0x53,0x54,0x41,0x00,  /* 00001790    "1.*_STA." */
  21.142 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001798    "p.\._GPE" */
  21.143 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 000017A0    "DPT1p..\" */
  21.144 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000017A8    "._GPEDPT" */
  21.145 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000017B0    "2.\._GPE" */
  21.146 +    0x50,0x48,0x30,0x31,0x5B,0x82,0x42,0x0B,  /* 000017B8    "PH01[.B." */
  21.147 +    0x53,0x30,0x32,0x5F,0x08,0x5F,0x41,0x44,  /* 000017C0    "S02_._AD" */
  21.148 +    0x52,0x0C,0x00,0x00,0x02,0x00,0x08,0x5F,  /* 000017C8    "R......_" */
  21.149 +    0x53,0x55,0x4E,0x0A,0x02,0x14,0x20,0x5F,  /* 000017D0    "SUN... _" */
  21.150 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x02,0x5C,  /* 000017D8    "PS0.p..\" */
  21.151 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000017E0    "._GPEDPT" */
  21.152 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 000017E8    "1p..\._G" */
  21.153 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 000017F0    "PEDPT2. " */
  21.154 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x02,  /* 000017F8    "_PS3.p.." */
  21.155 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001800    "\._GPEDP" */
  21.156 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00001808    "T1p..\._" */
  21.157 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001810    "GPEDPT2." */
  21.158 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00001818    ",_EJ0.p." */
  21.159 +    0x02,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001820    ".\._GPED" */
  21.160 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00001828    "PT1p..\." */
  21.161 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00001830    "_GPEDPT2" */
  21.162 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001838    "p.\._GPE" */
  21.163 +    0x50,0x48,0x30,0x32,0x14,0x2B,0x5F,0x53,  /* 00001840    "PH02.+_S" */
  21.164 +    0x54,0x41,0x00,0x70,0x0A,0x02,0x5C,0x2E,  /* 00001848    "TA.p..\." */
  21.165 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001850    "_GPEDPT1" */
  21.166 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001858    "p..\._GP" */
  21.167 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00001860    "EDPT2.\." */
  21.168 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x32,  /* 00001868    "_GPEPH02" */
  21.169 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x33,0x5F,  /* 00001870    "[.B.S03_" */
  21.170 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00001878    "._ADR..." */
  21.171 +    0x03,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00001880    "..._SUN." */
  21.172 +    0x03,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00001888    ".. _PS0." */
  21.173 +    0x70,0x0A,0x03,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001890    "p..\._GP" */
  21.174 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00001898    "EDPT1p.." */
  21.175 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000018A0    "\._GPEDP" */
  21.176 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 000018A8    "T2. _PS3" */
  21.177 +    0x00,0x70,0x0A,0x03,0x5C,0x2E,0x5F,0x47,  /* 000018B0    ".p..\._G" */
  21.178 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 000018B8    "PEDPT1p." */
  21.179 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 000018C0    ".\._GPED" */
  21.180 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 000018C8    "PT2.,_EJ" */
  21.181 +    0x30,0x01,0x70,0x0A,0x03,0x5C,0x2E,0x5F,  /* 000018D0    "0.p..\._" */
  21.182 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 000018D8    "GPEDPT1p" */
  21.183 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000018E0    "..\._GPE" */
  21.184 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 000018E8    "DPT2p.\." */
  21.185 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x33,  /* 000018F0    "_GPEPH03" */
  21.186 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 000018F8    ".+_STA.p" */
  21.187 +    0x0A,0x03,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001900    "..\._GPE" */
  21.188 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00001908    "DPT1p..\" */
  21.189 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001910    "._GPEDPT" */
  21.190 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001918    "2.\._GPE" */
  21.191 +    0x50,0x48,0x30,0x33,0x5B,0x82,0x42,0x0B,  /* 00001920    "PH03[.B." */
  21.192 +    0x53,0x30,0x34,0x5F,0x08,0x5F,0x41,0x44,  /* 00001928    "S04_._AD" */
  21.193 +    0x52,0x0C,0x00,0x00,0x04,0x00,0x08,0x5F,  /* 00001930    "R......_" */
  21.194 +    0x53,0x55,0x4E,0x0A,0x04,0x14,0x20,0x5F,  /* 00001938    "SUN... _" */
  21.195 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x04,0x5C,  /* 00001940    "PS0.p..\" */
  21.196 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001948    "._GPEDPT" */
  21.197 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001950    "1p..\._G" */
  21.198 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00001958    "PEDPT2. " */
  21.199 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x04,  /* 00001960    "_PS3.p.." */
  21.200 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001968    "\._GPEDP" */
  21.201 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00001970    "T1p..\._" */
  21.202 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001978    "GPEDPT2." */
  21.203 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00001980    ",_EJ0.p." */
  21.204 +    0x04,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001988    ".\._GPED" */
  21.205 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00001990    "PT1p..\." */
  21.206 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00001998    "_GPEDPT2" */
  21.207 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000019A0    "p.\._GPE" */
  21.208 +    0x50,0x48,0x30,0x34,0x14,0x2B,0x5F,0x53,  /* 000019A8    "PH04.+_S" */
  21.209 +    0x54,0x41,0x00,0x70,0x0A,0x04,0x5C,0x2E,  /* 000019B0    "TA.p..\." */
  21.210 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 000019B8    "_GPEDPT1" */
  21.211 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 000019C0    "p..\._GP" */
  21.212 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 000019C8    "EDPT2.\." */
  21.213 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x34,  /* 000019D0    "_GPEPH04" */
  21.214 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x35,0x5F,  /* 000019D8    "[.B.S05_" */
  21.215 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 000019E0    "._ADR..." */
  21.216 +    0x05,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 000019E8    "..._SUN." */
  21.217 +    0x05,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 000019F0    ".. _PS0." */
  21.218 +    0x70,0x0A,0x05,0x5C,0x2E,0x5F,0x47,0x50,  /* 000019F8    "p..\._GP" */
  21.219 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00001A00    "EDPT1p.." */
  21.220 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001A08    "\._GPEDP" */
  21.221 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00001A10    "T2. _PS3" */
  21.222 +    0x00,0x70,0x0A,0x05,0x5C,0x2E,0x5F,0x47,  /* 00001A18    ".p..\._G" */
  21.223 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00001A20    "PEDPT1p." */
  21.224 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001A28    ".\._GPED" */
  21.225 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00001A30    "PT2.,_EJ" */
  21.226 +    0x30,0x01,0x70,0x0A,0x05,0x5C,0x2E,0x5F,  /* 00001A38    "0.p..\._" */
  21.227 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00001A40    "GPEDPT1p" */
  21.228 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001A48    "..\._GPE" */
  21.229 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00001A50    "DPT2p.\." */
  21.230 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x35,  /* 00001A58    "_GPEPH05" */
  21.231 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00001A60    ".+_STA.p" */
  21.232 +    0x0A,0x05,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001A68    "..\._GPE" */
  21.233 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00001A70    "DPT1p..\" */
  21.234 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001A78    "._GPEDPT" */
  21.235 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001A80    "2.\._GPE" */
  21.236 +    0x50,0x48,0x30,0x35,0x5B,0x82,0x42,0x0B,  /* 00001A88    "PH05[.B." */
  21.237 +    0x53,0x30,0x36,0x5F,0x08,0x5F,0x41,0x44,  /* 00001A90    "S06_._AD" */
  21.238 +    0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,  /* 00001A98    "R......_" */
  21.239 +    0x53,0x55,0x4E,0x0A,0x06,0x14,0x20,0x5F,  /* 00001AA0    "SUN... _" */
  21.240 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x06,0x5C,  /* 00001AA8    "PS0.p..\" */
  21.241 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001AB0    "._GPEDPT" */
  21.242 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001AB8    "1p..\._G" */
  21.243 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00001AC0    "PEDPT2. " */
  21.244 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x06,  /* 00001AC8    "_PS3.p.." */
  21.245 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001AD0    "\._GPEDP" */
  21.246 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00001AD8    "T1p..\._" */
  21.247 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001AE0    "GPEDPT2." */
  21.248 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00001AE8    ",_EJ0.p." */
  21.249 +    0x06,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001AF0    ".\._GPED" */
  21.250 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00001AF8    "PT1p..\." */
  21.251 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00001B00    "_GPEDPT2" */
  21.252 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001B08    "p.\._GPE" */
  21.253 +    0x50,0x48,0x30,0x36,0x14,0x2B,0x5F,0x53,  /* 00001B10    "PH06.+_S" */
  21.254 +    0x54,0x41,0x00,0x70,0x0A,0x06,0x5C,0x2E,  /* 00001B18    "TA.p..\." */
  21.255 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001B20    "_GPEDPT1" */
  21.256 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001B28    "p..\._GP" */
  21.257 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00001B30    "EDPT2.\." */
  21.258 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x36,  /* 00001B38    "_GPEPH06" */
  21.259 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x37,0x5F,  /* 00001B40    "[.B.S07_" */
  21.260 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00001B48    "._ADR..." */
  21.261 +    0x07,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00001B50    "..._SUN." */
  21.262 +    0x07,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00001B58    ".. _PS0." */
  21.263 +    0x70,0x0A,0x07,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001B60    "p..\._GP" */
  21.264 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00001B68    "EDPT1p.." */
  21.265 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001B70    "\._GPEDP" */
  21.266 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00001B78    "T2. _PS3" */
  21.267 +    0x00,0x70,0x0A,0x07,0x5C,0x2E,0x5F,0x47,  /* 00001B80    ".p..\._G" */
  21.268 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00001B88    "PEDPT1p." */
  21.269 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001B90    ".\._GPED" */
  21.270 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00001B98    "PT2.,_EJ" */
  21.271 +    0x30,0x01,0x70,0x0A,0x07,0x5C,0x2E,0x5F,  /* 00001BA0    "0.p..\._" */
  21.272 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00001BA8    "GPEDPT1p" */
  21.273 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001BB0    "..\._GPE" */
  21.274 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00001BB8    "DPT2p.\." */
  21.275 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x37,  /* 00001BC0    "_GPEPH07" */
  21.276 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00001BC8    ".+_STA.p" */
  21.277 +    0x0A,0x07,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001BD0    "..\._GPE" */
  21.278 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00001BD8    "DPT1p..\" */
  21.279 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001BE0    "._GPEDPT" */
  21.280 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001BE8    "2.\._GPE" */
  21.281 +    0x50,0x48,0x30,0x37,0x5B,0x82,0x42,0x0B,  /* 00001BF0    "PH07[.B." */
  21.282 +    0x53,0x30,0x38,0x5F,0x08,0x5F,0x41,0x44,  /* 00001BF8    "S08_._AD" */
  21.283 +    0x52,0x0C,0x00,0x00,0x08,0x00,0x08,0x5F,  /* 00001C00    "R......_" */
  21.284 +    0x53,0x55,0x4E,0x0A,0x08,0x14,0x20,0x5F,  /* 00001C08    "SUN... _" */
  21.285 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x08,0x5C,  /* 00001C10    "PS0.p..\" */
  21.286 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001C18    "._GPEDPT" */
  21.287 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001C20    "1p..\._G" */
  21.288 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00001C28    "PEDPT2. " */
  21.289 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x08,  /* 00001C30    "_PS3.p.." */
  21.290 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001C38    "\._GPEDP" */
  21.291 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00001C40    "T1p..\._" */
  21.292 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001C48    "GPEDPT2." */
  21.293 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00001C50    ",_EJ0.p." */
  21.294 +    0x08,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001C58    ".\._GPED" */
  21.295 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00001C60    "PT1p..\." */
  21.296 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00001C68    "_GPEDPT2" */
  21.297 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001C70    "p.\._GPE" */
  21.298 +    0x50,0x48,0x30,0x38,0x14,0x2B,0x5F,0x53,  /* 00001C78    "PH08.+_S" */
  21.299 +    0x54,0x41,0x00,0x70,0x0A,0x08,0x5C,0x2E,  /* 00001C80    "TA.p..\." */
  21.300 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001C88    "_GPEDPT1" */
  21.301 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001C90    "p..\._GP" */
  21.302 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00001C98    "EDPT2.\." */
  21.303 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x38,  /* 00001CA0    "_GPEPH08" */
  21.304 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x39,0x5F,  /* 00001CA8    "[.B.S09_" */
  21.305 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00001CB0    "._ADR..." */
  21.306 +    0x09,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00001CB8    "..._SUN." */
  21.307 +    0x09,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00001CC0    ".. _PS0." */
  21.308 +    0x70,0x0A,0x09,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001CC8    "p..\._GP" */
  21.309 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00001CD0    "EDPT1p.." */
  21.310 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001CD8    "\._GPEDP" */
  21.311 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00001CE0    "T2. _PS3" */
  21.312 +    0x00,0x70,0x0A,0x09,0x5C,0x2E,0x5F,0x47,  /* 00001CE8    ".p..\._G" */
  21.313 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00001CF0    "PEDPT1p." */
  21.314 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001CF8    ".\._GPED" */
  21.315 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00001D00    "PT2.,_EJ" */
  21.316 +    0x30,0x01,0x70,0x0A,0x09,0x5C,0x2E,0x5F,  /* 00001D08    "0.p..\._" */
  21.317 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00001D10    "GPEDPT1p" */
  21.318 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001D18    "..\._GPE" */
  21.319 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00001D20    "DPT2p.\." */
  21.320 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x39,  /* 00001D28    "_GPEPH09" */
  21.321 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00001D30    ".+_STA.p" */
  21.322 +    0x0A,0x09,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001D38    "..\._GPE" */
  21.323 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00001D40    "DPT1p..\" */
  21.324 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001D48    "._GPEDPT" */
  21.325 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001D50    "2.\._GPE" */
  21.326 +    0x50,0x48,0x30,0x39,0x5B,0x82,0x42,0x0B,  /* 00001D58    "PH09[.B." */
  21.327 +    0x53,0x30,0x41,0x5F,0x08,0x5F,0x41,0x44,  /* 00001D60    "S0A_._AD" */
  21.328 +    0x52,0x0C,0x00,0x00,0x0A,0x00,0x08,0x5F,  /* 00001D68    "R......_" */
  21.329 +    0x53,0x55,0x4E,0x0A,0x0A,0x14,0x20,0x5F,  /* 00001D70    "SUN... _" */
  21.330 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x0A,0x5C,  /* 00001D78    "PS0.p..\" */
  21.331 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001D80    "._GPEDPT" */
  21.332 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001D88    "1p..\._G" */
  21.333 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00001D90    "PEDPT2. " */
  21.334 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x0A,  /* 00001D98    "_PS3.p.." */
  21.335 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001DA0    "\._GPEDP" */
  21.336 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00001DA8    "T1p..\._" */
  21.337 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001DB0    "GPEDPT2." */
  21.338 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00001DB8    ",_EJ0.p." */
  21.339 +    0x0A,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001DC0    ".\._GPED" */
  21.340 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00001DC8    "PT1p..\." */
  21.341 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00001DD0    "_GPEDPT2" */
  21.342 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001DD8    "p.\._GPE" */
  21.343 +    0x50,0x48,0x30,0x41,0x14,0x2B,0x5F,0x53,  /* 00001DE0    "PH0A.+_S" */
  21.344 +    0x54,0x41,0x00,0x70,0x0A,0x0A,0x5C,0x2E,  /* 00001DE8    "TA.p..\." */
  21.345 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001DF0    "_GPEDPT1" */
  21.346 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001DF8    "p..\._GP" */
  21.347 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00001E00    "EDPT2.\." */
  21.348 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x41,  /* 00001E08    "_GPEPH0A" */
  21.349 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x42,0x5F,  /* 00001E10    "[.B.S0B_" */
  21.350 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00001E18    "._ADR..." */
  21.351 +    0x0B,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00001E20    "..._SUN." */
  21.352 +    0x0B,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00001E28    ".. _PS0." */
  21.353 +    0x70,0x0A,0x0B,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001E30    "p..\._GP" */
  21.354 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00001E38    "EDPT1p.." */
  21.355 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001E40    "\._GPEDP" */
  21.356 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00001E48    "T2. _PS3" */
  21.357 +    0x00,0x70,0x0A,0x0B,0x5C,0x2E,0x5F,0x47,  /* 00001E50    ".p..\._G" */
  21.358 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00001E58    "PEDPT1p." */
  21.359 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001E60    ".\._GPED" */
  21.360 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00001E68    "PT2.,_EJ" */
  21.361 +    0x30,0x01,0x70,0x0A,0x0B,0x5C,0x2E,0x5F,  /* 00001E70    "0.p..\._" */
  21.362 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00001E78    "GPEDPT1p" */
  21.363 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001E80    "..\._GPE" */
  21.364 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00001E88    "DPT2p.\." */
  21.365 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x42,  /* 00001E90    "_GPEPH0B" */
  21.366 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00001E98    ".+_STA.p" */
  21.367 +    0x0A,0x0B,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001EA0    "..\._GPE" */
  21.368 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00001EA8    "DPT1p..\" */
  21.369 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001EB0    "._GPEDPT" */
  21.370 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001EB8    "2.\._GPE" */
  21.371 +    0x50,0x48,0x30,0x42,0x5B,0x82,0x42,0x0B,  /* 00001EC0    "PH0B[.B." */
  21.372 +    0x53,0x30,0x43,0x5F,0x08,0x5F,0x41,0x44,  /* 00001EC8    "S0C_._AD" */
  21.373 +    0x52,0x0C,0x00,0x00,0x0C,0x00,0x08,0x5F,  /* 00001ED0    "R......_" */
  21.374 +    0x53,0x55,0x4E,0x0A,0x0C,0x14,0x20,0x5F,  /* 00001ED8    "SUN... _" */
  21.375 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x0C,0x5C,  /* 00001EE0    "PS0.p..\" */
  21.376 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00001EE8    "._GPEDPT" */
  21.377 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00001EF0    "1p..\._G" */
  21.378 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00001EF8    "PEDPT2. " */
  21.379 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x0C,  /* 00001F00    "_PS3.p.." */
  21.380 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001F08    "\._GPEDP" */
  21.381 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00001F10    "T1p..\._" */
  21.382 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001F18    "GPEDPT2." */
  21.383 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00001F20    ",_EJ0.p." */
  21.384 +    0x0C,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001F28    ".\._GPED" */
  21.385 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00001F30    "PT1p..\." */
  21.386 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00001F38    "_GPEDPT2" */
  21.387 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001F40    "p.\._GPE" */
  21.388 +    0x50,0x48,0x30,0x43,0x14,0x2B,0x5F,0x53,  /* 00001F48    "PH0C.+_S" */
  21.389 +    0x54,0x41,0x00,0x70,0x0A,0x0C,0x5C,0x2E,  /* 00001F50    "TA.p..\." */
  21.390 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00001F58    "_GPEDPT1" */
  21.391 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001F60    "p..\._GP" */
  21.392 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00001F68    "EDPT2.\." */
  21.393 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x43,  /* 00001F70    "_GPEPH0C" */
  21.394 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x44,0x5F,  /* 00001F78    "[.B.S0D_" */
  21.395 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00001F80    "._ADR..." */
  21.396 +    0x0D,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00001F88    "..._SUN." */
  21.397 +    0x0D,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00001F90    ".. _PS0." */
  21.398 +    0x70,0x0A,0x0D,0x5C,0x2E,0x5F,0x47,0x50,  /* 00001F98    "p..\._GP" */
  21.399 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00001FA0    "EDPT1p.." */
  21.400 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00001FA8    "\._GPEDP" */
  21.401 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00001FB0    "T2. _PS3" */
  21.402 +    0x00,0x70,0x0A,0x0D,0x5C,0x2E,0x5F,0x47,  /* 00001FB8    ".p..\._G" */
  21.403 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00001FC0    "PEDPT1p." */
  21.404 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001FC8    ".\._GPED" */
  21.405 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00001FD0    "PT2.,_EJ" */
  21.406 +    0x30,0x01,0x70,0x0A,0x0D,0x5C,0x2E,0x5F,  /* 00001FD8    "0.p..\._" */
  21.407 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00001FE0    "GPEDPT1p" */
  21.408 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00001FE8    "..\._GPE" */
  21.409 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00001FF0    "DPT2p.\." */
  21.410 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x44,  /* 00001FF8    "_GPEPH0D" */
  21.411 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002000    ".+_STA.p" */
  21.412 +    0x0A,0x0D,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002008    "..\._GPE" */
  21.413 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002010    "DPT1p..\" */
  21.414 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002018    "._GPEDPT" */
  21.415 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002020    "2.\._GPE" */
  21.416 +    0x50,0x48,0x30,0x44,0x5B,0x82,0x42,0x0B,  /* 00002028    "PH0D[.B." */
  21.417 +    0x53,0x30,0x45,0x5F,0x08,0x5F,0x41,0x44,  /* 00002030    "S0E_._AD" */
  21.418 +    0x52,0x0C,0x00,0x00,0x0E,0x00,0x08,0x5F,  /* 00002038    "R......_" */
  21.419 +    0x53,0x55,0x4E,0x0A,0x0E,0x14,0x20,0x5F,  /* 00002040    "SUN... _" */
  21.420 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x0E,0x5C,  /* 00002048    "PS0.p..\" */
  21.421 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002050    "._GPEDPT" */
  21.422 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00002058    "1p..\._G" */
  21.423 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002060    "PEDPT2. " */
  21.424 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x0E,  /* 00002068    "_PS3.p.." */
  21.425 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002070    "\._GPEDP" */
  21.426 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00002078    "T1p..\._" */
  21.427 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00002080    "GPEDPT2." */
  21.428 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00002088    ",_EJ0.p." */
  21.429 +    0x0E,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002090    ".\._GPED" */
  21.430 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002098    "PT1p..\." */
  21.431 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 000020A0    "_GPEDPT2" */
  21.432 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000020A8    "p.\._GPE" */
  21.433 +    0x50,0x48,0x30,0x45,0x14,0x2B,0x5F,0x53,  /* 000020B0    "PH0E.+_S" */
  21.434 +    0x54,0x41,0x00,0x70,0x0A,0x0E,0x5C,0x2E,  /* 000020B8    "TA.p..\." */
  21.435 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 000020C0    "_GPEDPT1" */
  21.436 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 000020C8    "p..\._GP" */
  21.437 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 000020D0    "EDPT2.\." */
  21.438 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x45,  /* 000020D8    "_GPEPH0E" */
  21.439 +    0x5B,0x82,0x42,0x0B,0x53,0x30,0x46,0x5F,  /* 000020E0    "[.B.S0F_" */
  21.440 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 000020E8    "._ADR..." */
  21.441 +    0x0F,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 000020F0    "..._SUN." */
  21.442 +    0x0F,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 000020F8    ".. _PS0." */
  21.443 +    0x70,0x0A,0x0F,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002100    "p..\._GP" */
  21.444 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002108    "EDPT1p.." */
  21.445 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002110    "\._GPEDP" */
  21.446 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002118    "T2. _PS3" */
  21.447 +    0x00,0x70,0x0A,0x0F,0x5C,0x2E,0x5F,0x47,  /* 00002120    ".p..\._G" */
  21.448 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002128    "PEDPT1p." */
  21.449 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002130    ".\._GPED" */
  21.450 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00002138    "PT2.,_EJ" */
  21.451 +    0x30,0x01,0x70,0x0A,0x0F,0x5C,0x2E,0x5F,  /* 00002140    "0.p..\._" */
  21.452 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00002148    "GPEDPT1p" */
  21.453 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002150    "..\._GPE" */
  21.454 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00002158    "DPT2p.\." */
  21.455 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x46,  /* 00002160    "_GPEPH0F" */
  21.456 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002168    ".+_STA.p" */
  21.457 +    0x0A,0x0F,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002170    "..\._GPE" */
  21.458 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002178    "DPT1p..\" */
  21.459 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002180    "._GPEDPT" */
  21.460 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002188    "2.\._GPE" */
  21.461 +    0x50,0x48,0x30,0x46,0x5B,0x82,0x42,0x0B,  /* 00002190    "PH0F[.B." */
  21.462 +    0x53,0x31,0x30,0x5F,0x08,0x5F,0x41,0x44,  /* 00002198    "S10_._AD" */
  21.463 +    0x52,0x0C,0x00,0x00,0x10,0x00,0x08,0x5F,  /* 000021A0    "R......_" */
  21.464 +    0x53,0x55,0x4E,0x0A,0x10,0x14,0x20,0x5F,  /* 000021A8    "SUN... _" */
  21.465 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x10,0x5C,  /* 000021B0    "PS0.p..\" */
  21.466 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000021B8    "._GPEDPT" */
  21.467 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 000021C0    "1p..\._G" */
  21.468 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 000021C8    "PEDPT2. " */
  21.469 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x10,  /* 000021D0    "_PS3.p.." */
  21.470 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000021D8    "\._GPEDP" */
  21.471 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 000021E0    "T1p..\._" */
  21.472 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 000021E8    "GPEDPT2." */
  21.473 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 000021F0    ",_EJ0.p." */
  21.474 +    0x10,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 000021F8    ".\._GPED" */
  21.475 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002200    "PT1p..\." */
  21.476 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00002208    "_GPEDPT2" */
  21.477 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002210    "p.\._GPE" */
  21.478 +    0x50,0x48,0x31,0x30,0x14,0x2B,0x5F,0x53,  /* 00002218    "PH10.+_S" */
  21.479 +    0x54,0x41,0x00,0x70,0x0A,0x10,0x5C,0x2E,  /* 00002220    "TA.p..\." */
  21.480 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00002228    "_GPEDPT1" */
  21.481 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002230    "p..\._GP" */
  21.482 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00002238    "EDPT2.\." */
  21.483 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x30,  /* 00002240    "_GPEPH10" */
  21.484 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x31,0x5F,  /* 00002248    "[.B.S11_" */
  21.485 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00002250    "._ADR..." */
  21.486 +    0x11,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00002258    "..._SUN." */
  21.487 +    0x11,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002260    ".. _PS0." */
  21.488 +    0x70,0x0A,0x11,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002268    "p..\._GP" */
  21.489 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002270    "EDPT1p.." */
  21.490 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002278    "\._GPEDP" */
  21.491 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002280    "T2. _PS3" */
  21.492 +    0x00,0x70,0x0A,0x11,0x5C,0x2E,0x5F,0x47,  /* 00002288    ".p..\._G" */
  21.493 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002290    "PEDPT1p." */
  21.494 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002298    ".\._GPED" */
  21.495 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 000022A0    "PT2.,_EJ" */
  21.496 +    0x30,0x01,0x70,0x0A,0x11,0x5C,0x2E,0x5F,  /* 000022A8    "0.p..\._" */
  21.497 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 000022B0    "GPEDPT1p" */
  21.498 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000022B8    "..\._GPE" */
  21.499 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 000022C0    "DPT2p.\." */
  21.500 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x31,  /* 000022C8    "_GPEPH11" */
  21.501 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 000022D0    ".+_STA.p" */
  21.502 +    0x0A,0x11,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000022D8    "..\._GPE" */
  21.503 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 000022E0    "DPT1p..\" */
  21.504 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000022E8    "._GPEDPT" */
  21.505 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000022F0    "2.\._GPE" */
  21.506 +    0x50,0x48,0x31,0x31,0x5B,0x82,0x42,0x0B,  /* 000022F8    "PH11[.B." */
  21.507 +    0x53,0x31,0x32,0x5F,0x08,0x5F,0x41,0x44,  /* 00002300    "S12_._AD" */
  21.508 +    0x52,0x0C,0x00,0x00,0x12,0x00,0x08,0x5F,  /* 00002308    "R......_" */
  21.509 +    0x53,0x55,0x4E,0x0A,0x12,0x14,0x20,0x5F,  /* 00002310    "SUN... _" */
  21.510 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x12,0x5C,  /* 00002318    "PS0.p..\" */
  21.511 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002320    "._GPEDPT" */
  21.512 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00002328    "1p..\._G" */
  21.513 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002330    "PEDPT2. " */
  21.514 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x12,  /* 00002338    "_PS3.p.." */
  21.515 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002340    "\._GPEDP" */
  21.516 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00002348    "T1p..\._" */
  21.517 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00002350    "GPEDPT2." */
  21.518 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00002358    ",_EJ0.p." */
  21.519 +    0x12,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002360    ".\._GPED" */
  21.520 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002368    "PT1p..\." */
  21.521 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00002370    "_GPEDPT2" */
  21.522 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002378    "p.\._GPE" */
  21.523 +    0x50,0x48,0x31,0x32,0x14,0x2B,0x5F,0x53,  /* 00002380    "PH12.+_S" */
  21.524 +    0x54,0x41,0x00,0x70,0x0A,0x12,0x5C,0x2E,  /* 00002388    "TA.p..\." */
  21.525 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00002390    "_GPEDPT1" */
  21.526 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002398    "p..\._GP" */
  21.527 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 000023A0    "EDPT2.\." */
  21.528 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x32,  /* 000023A8    "_GPEPH12" */
  21.529 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x33,0x5F,  /* 000023B0    "[.B.S13_" */
  21.530 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 000023B8    "._ADR..." */
  21.531 +    0x13,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 000023C0    "..._SUN." */
  21.532 +    0x13,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 000023C8    ".. _PS0." */
  21.533 +    0x70,0x0A,0x13,0x5C,0x2E,0x5F,0x47,0x50,  /* 000023D0    "p..\._GP" */
  21.534 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 000023D8    "EDPT1p.." */
  21.535 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000023E0    "\._GPEDP" */
  21.536 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 000023E8    "T2. _PS3" */
  21.537 +    0x00,0x70,0x0A,0x13,0x5C,0x2E,0x5F,0x47,  /* 000023F0    ".p..\._G" */
  21.538 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 000023F8    "PEDPT1p." */
  21.539 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002400    ".\._GPED" */
  21.540 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00002408    "PT2.,_EJ" */
  21.541 +    0x30,0x01,0x70,0x0A,0x13,0x5C,0x2E,0x5F,  /* 00002410    "0.p..\._" */
  21.542 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00002418    "GPEDPT1p" */
  21.543 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002420    "..\._GPE" */
  21.544 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00002428    "DPT2p.\." */
  21.545 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x33,  /* 00002430    "_GPEPH13" */
  21.546 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002438    ".+_STA.p" */
  21.547 +    0x0A,0x13,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002440    "..\._GPE" */
  21.548 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002448    "DPT1p..\" */
  21.549 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002450    "._GPEDPT" */
  21.550 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002458    "2.\._GPE" */
  21.551 +    0x50,0x48,0x31,0x33,0x5B,0x82,0x42,0x0B,  /* 00002460    "PH13[.B." */
  21.552 +    0x53,0x31,0x34,0x5F,0x08,0x5F,0x41,0x44,  /* 00002468    "S14_._AD" */
  21.553 +    0x52,0x0C,0x00,0x00,0x14,0x00,0x08,0x5F,  /* 00002470    "R......_" */
  21.554 +    0x53,0x55,0x4E,0x0A,0x14,0x14,0x20,0x5F,  /* 00002478    "SUN... _" */
  21.555 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x14,0x5C,  /* 00002480    "PS0.p..\" */
  21.556 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002488    "._GPEDPT" */
  21.557 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00002490    "1p..\._G" */
  21.558 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002498    "PEDPT2. " */
  21.559 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x14,  /* 000024A0    "_PS3.p.." */
  21.560 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000024A8    "\._GPEDP" */
  21.561 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 000024B0    "T1p..\._" */
  21.562 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 000024B8    "GPEDPT2." */
  21.563 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 000024C0    ",_EJ0.p." */
  21.564 +    0x14,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 000024C8    ".\._GPED" */
  21.565 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 000024D0    "PT1p..\." */
  21.566 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 000024D8    "_GPEDPT2" */
  21.567 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000024E0    "p.\._GPE" */
  21.568 +    0x50,0x48,0x31,0x34,0x14,0x2B,0x5F,0x53,  /* 000024E8    "PH14.+_S" */
  21.569 +    0x54,0x41,0x00,0x70,0x0A,0x14,0x5C,0x2E,  /* 000024F0    "TA.p..\." */
  21.570 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 000024F8    "_GPEDPT1" */
  21.571 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002500    "p..\._GP" */
  21.572 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00002508    "EDPT2.\." */
  21.573 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x34,  /* 00002510    "_GPEPH14" */
  21.574 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x35,0x5F,  /* 00002518    "[.B.S15_" */
  21.575 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00002520    "._ADR..." */
  21.576 +    0x15,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00002528    "..._SUN." */
  21.577 +    0x15,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002530    ".. _PS0." */
  21.578 +    0x70,0x0A,0x15,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002538    "p..\._GP" */
  21.579 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002540    "EDPT1p.." */
  21.580 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002548    "\._GPEDP" */
  21.581 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002550    "T2. _PS3" */
  21.582 +    0x00,0x70,0x0A,0x15,0x5C,0x2E,0x5F,0x47,  /* 00002558    ".p..\._G" */
  21.583 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002560    "PEDPT1p." */
  21.584 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002568    ".\._GPED" */
  21.585 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00002570    "PT2.,_EJ" */
  21.586 +    0x30,0x01,0x70,0x0A,0x15,0x5C,0x2E,0x5F,  /* 00002578    "0.p..\._" */
  21.587 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00002580    "GPEDPT1p" */
  21.588 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002588    "..\._GPE" */
  21.589 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00002590    "DPT2p.\." */
  21.590 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x35,  /* 00002598    "_GPEPH15" */
  21.591 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 000025A0    ".+_STA.p" */
  21.592 +    0x0A,0x15,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000025A8    "..\._GPE" */
  21.593 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 000025B0    "DPT1p..\" */
  21.594 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000025B8    "._GPEDPT" */
  21.595 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000025C0    "2.\._GPE" */
  21.596 +    0x50,0x48,0x31,0x35,0x5B,0x82,0x42,0x0B,  /* 000025C8    "PH15[.B." */
  21.597 +    0x53,0x31,0x36,0x5F,0x08,0x5F,0x41,0x44,  /* 000025D0    "S16_._AD" */
  21.598 +    0x52,0x0C,0x00,0x00,0x16,0x00,0x08,0x5F,  /* 000025D8    "R......_" */
  21.599 +    0x53,0x55,0x4E,0x0A,0x16,0x14,0x20,0x5F,  /* 000025E0    "SUN... _" */
  21.600 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x16,0x5C,  /* 000025E8    "PS0.p..\" */
  21.601 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000025F0    "._GPEDPT" */
  21.602 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 000025F8    "1p..\._G" */
  21.603 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002600    "PEDPT2. " */
  21.604 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x16,  /* 00002608    "_PS3.p.." */
  21.605 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002610    "\._GPEDP" */
  21.606 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00002618    "T1p..\._" */
  21.607 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00002620    "GPEDPT2." */
  21.608 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00002628    ",_EJ0.p." */
  21.609 +    0x16,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002630    ".\._GPED" */
  21.610 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002638    "PT1p..\." */
  21.611 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00002640    "_GPEDPT2" */
  21.612 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002648    "p.\._GPE" */
  21.613 +    0x50,0x48,0x31,0x36,0x14,0x2B,0x5F,0x53,  /* 00002650    "PH16.+_S" */
  21.614 +    0x54,0x41,0x00,0x70,0x0A,0x16,0x5C,0x2E,  /* 00002658    "TA.p..\." */
  21.615 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00002660    "_GPEDPT1" */
  21.616 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002668    "p..\._GP" */
  21.617 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00002670    "EDPT2.\." */
  21.618 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x36,  /* 00002678    "_GPEPH16" */
  21.619 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x37,0x5F,  /* 00002680    "[.B.S17_" */
  21.620 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00002688    "._ADR..." */
  21.621 +    0x17,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00002690    "..._SUN." */
  21.622 +    0x17,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002698    ".. _PS0." */
  21.623 +    0x70,0x0A,0x17,0x5C,0x2E,0x5F,0x47,0x50,  /* 000026A0    "p..\._GP" */
  21.624 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 000026A8    "EDPT1p.." */
  21.625 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000026B0    "\._GPEDP" */
  21.626 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 000026B8    "T2. _PS3" */
  21.627 +    0x00,0x70,0x0A,0x17,0x5C,0x2E,0x5F,0x47,  /* 000026C0    ".p..\._G" */
  21.628 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 000026C8    "PEDPT1p." */
  21.629 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 000026D0    ".\._GPED" */
  21.630 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 000026D8    "PT2.,_EJ" */
  21.631 +    0x30,0x01,0x70,0x0A,0x17,0x5C,0x2E,0x5F,  /* 000026E0    "0.p..\._" */
  21.632 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 000026E8    "GPEDPT1p" */
  21.633 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000026F0    "..\._GPE" */
  21.634 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 000026F8    "DPT2p.\." */
  21.635 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x37,  /* 00002700    "_GPEPH17" */
  21.636 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002708    ".+_STA.p" */
  21.637 +    0x0A,0x17,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002710    "..\._GPE" */
  21.638 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002718    "DPT1p..\" */
  21.639 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002720    "._GPEDPT" */
  21.640 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002728    "2.\._GPE" */
  21.641 +    0x50,0x48,0x31,0x37,0x5B,0x82,0x42,0x0B,  /* 00002730    "PH17[.B." */
  21.642 +    0x53,0x31,0x38,0x5F,0x08,0x5F,0x41,0x44,  /* 00002738    "S18_._AD" */
  21.643 +    0x52,0x0C,0x00,0x00,0x18,0x00,0x08,0x5F,  /* 00002740    "R......_" */
  21.644 +    0x53,0x55,0x4E,0x0A,0x18,0x14,0x20,0x5F,  /* 00002748    "SUN... _" */
  21.645 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x18,0x5C,  /* 00002750    "PS0.p..\" */
  21.646 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002758    "._GPEDPT" */
  21.647 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00002760    "1p..\._G" */
  21.648 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002768    "PEDPT2. " */
  21.649 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x18,  /* 00002770    "_PS3.p.." */
  21.650 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002778    "\._GPEDP" */
  21.651 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00002780    "T1p..\._" */
  21.652 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00002788    "GPEDPT2." */
  21.653 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00002790    ",_EJ0.p." */
  21.654 +    0x18,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002798    ".\._GPED" */
  21.655 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 000027A0    "PT1p..\." */
  21.656 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 000027A8    "_GPEDPT2" */
  21.657 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000027B0    "p.\._GPE" */
  21.658 +    0x50,0x48,0x31,0x38,0x14,0x2B,0x5F,0x53,  /* 000027B8    "PH18.+_S" */
  21.659 +    0x54,0x41,0x00,0x70,0x0A,0x18,0x5C,0x2E,  /* 000027C0    "TA.p..\." */
  21.660 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 000027C8    "_GPEDPT1" */
  21.661 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 000027D0    "p..\._GP" */
  21.662 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 000027D8    "EDPT2.\." */
  21.663 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x38,  /* 000027E0    "_GPEPH18" */
  21.664 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x39,0x5F,  /* 000027E8    "[.B.S19_" */
  21.665 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 000027F0    "._ADR..." */
  21.666 +    0x19,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 000027F8    "..._SUN." */
  21.667 +    0x19,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002800    ".. _PS0." */
  21.668 +    0x70,0x0A,0x19,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002808    "p..\._GP" */
  21.669 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002810    "EDPT1p.." */
  21.670 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002818    "\._GPEDP" */
  21.671 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002820    "T2. _PS3" */
  21.672 +    0x00,0x70,0x0A,0x19,0x5C,0x2E,0x5F,0x47,  /* 00002828    ".p..\._G" */
  21.673 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002830    "PEDPT1p." */
  21.674 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002838    ".\._GPED" */
  21.675 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00002840    "PT2.,_EJ" */
  21.676 +    0x30,0x01,0x70,0x0A,0x19,0x5C,0x2E,0x5F,  /* 00002848    "0.p..\._" */
  21.677 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00002850    "GPEDPT1p" */
  21.678 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002858    "..\._GPE" */
  21.679 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00002860    "DPT2p.\." */
  21.680 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x39,  /* 00002868    "_GPEPH19" */
  21.681 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002870    ".+_STA.p" */
  21.682 +    0x0A,0x19,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002878    "..\._GPE" */
  21.683 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002880    "DPT1p..\" */
  21.684 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002888    "._GPEDPT" */
  21.685 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002890    "2.\._GPE" */
  21.686 +    0x50,0x48,0x31,0x39,0x5B,0x82,0x42,0x0B,  /* 00002898    "PH19[.B." */
  21.687 +    0x53,0x31,0x41,0x5F,0x08,0x5F,0x41,0x44,  /* 000028A0    "S1A_._AD" */
  21.688 +    0x52,0x0C,0x00,0x00,0x1A,0x00,0x08,0x5F,  /* 000028A8    "R......_" */
  21.689 +    0x53,0x55,0x4E,0x0A,0x1A,0x14,0x20,0x5F,  /* 000028B0    "SUN... _" */
  21.690 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x1A,0x5C,  /* 000028B8    "PS0.p..\" */
  21.691 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000028C0    "._GPEDPT" */
  21.692 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 000028C8    "1p..\._G" */
  21.693 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 000028D0    "PEDPT2. " */
  21.694 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x1A,  /* 000028D8    "_PS3.p.." */
  21.695 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 000028E0    "\._GPEDP" */
  21.696 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 000028E8    "T1p..\._" */
  21.697 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 000028F0    "GPEDPT2." */
  21.698 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 000028F8    ",_EJ0.p." */
  21.699 +    0x1A,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002900    ".\._GPED" */
  21.700 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002908    "PT1p..\." */
  21.701 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00002910    "_GPEDPT2" */
  21.702 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002918    "p.\._GPE" */
  21.703 +    0x50,0x48,0x31,0x41,0x14,0x2B,0x5F,0x53,  /* 00002920    "PH1A.+_S" */
  21.704 +    0x54,0x41,0x00,0x70,0x0A,0x1A,0x5C,0x2E,  /* 00002928    "TA.p..\." */
  21.705 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00002930    "_GPEDPT1" */
  21.706 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002938    "p..\._GP" */
  21.707 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00002940    "EDPT2.\." */
  21.708 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x41,  /* 00002948    "_GPEPH1A" */
  21.709 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x42,0x5F,  /* 00002950    "[.B.S1B_" */
  21.710 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00002958    "._ADR..." */
  21.711 +    0x1B,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00002960    "..._SUN." */
  21.712 +    0x1B,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002968    ".. _PS0." */
  21.713 +    0x70,0x0A,0x1B,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002970    "p..\._GP" */
  21.714 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002978    "EDPT1p.." */
  21.715 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002980    "\._GPEDP" */
  21.716 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002988    "T2. _PS3" */
  21.717 +    0x00,0x70,0x0A,0x1B,0x5C,0x2E,0x5F,0x47,  /* 00002990    ".p..\._G" */
  21.718 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002998    "PEDPT1p." */
  21.719 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 000029A0    ".\._GPED" */
  21.720 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 000029A8    "PT2.,_EJ" */
  21.721 +    0x30,0x01,0x70,0x0A,0x1B,0x5C,0x2E,0x5F,  /* 000029B0    "0.p..\._" */
  21.722 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 000029B8    "GPEDPT1p" */
  21.723 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000029C0    "..\._GPE" */
  21.724 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 000029C8    "DPT2p.\." */
  21.725 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x42,  /* 000029D0    "_GPEPH1B" */
  21.726 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 000029D8    ".+_STA.p" */
  21.727 +    0x0A,0x1B,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000029E0    "..\._GPE" */
  21.728 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 000029E8    "DPT1p..\" */
  21.729 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 000029F0    "._GPEDPT" */
  21.730 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 000029F8    "2.\._GPE" */
  21.731 +    0x50,0x48,0x31,0x42,0x5B,0x82,0x42,0x0B,  /* 00002A00    "PH1B[.B." */
  21.732 +    0x53,0x31,0x43,0x5F,0x08,0x5F,0x41,0x44,  /* 00002A08    "S1C_._AD" */
  21.733 +    0x52,0x0C,0x00,0x00,0x1C,0x00,0x08,0x5F,  /* 00002A10    "R......_" */
  21.734 +    0x53,0x55,0x4E,0x0A,0x1C,0x14,0x20,0x5F,  /* 00002A18    "SUN... _" */
  21.735 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x1C,0x5C,  /* 00002A20    "PS0.p..\" */
  21.736 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002A28    "._GPEDPT" */
  21.737 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00002A30    "1p..\._G" */
  21.738 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002A38    "PEDPT2. " */
  21.739 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x1C,  /* 00002A40    "_PS3.p.." */
  21.740 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002A48    "\._GPEDP" */
  21.741 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00002A50    "T1p..\._" */
  21.742 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00002A58    "GPEDPT2." */
  21.743 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00002A60    ",_EJ0.p." */
  21.744 +    0x1C,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002A68    ".\._GPED" */
  21.745 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002A70    "PT1p..\." */
  21.746 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00002A78    "_GPEDPT2" */
  21.747 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002A80    "p.\._GPE" */
  21.748 +    0x50,0x48,0x31,0x43,0x14,0x2B,0x5F,0x53,  /* 00002A88    "PH1C.+_S" */
  21.749 +    0x54,0x41,0x00,0x70,0x0A,0x1C,0x5C,0x2E,  /* 00002A90    "TA.p..\." */
  21.750 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00002A98    "_GPEDPT1" */
  21.751 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002AA0    "p..\._GP" */
  21.752 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00002AA8    "EDPT2.\." */
  21.753 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x43,  /* 00002AB0    "_GPEPH1C" */
  21.754 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x44,0x5F,  /* 00002AB8    "[.B.S1D_" */
  21.755 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00002AC0    "._ADR..." */
  21.756 +    0x1D,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00002AC8    "..._SUN." */
  21.757 +    0x1D,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002AD0    ".. _PS0." */
  21.758 +    0x70,0x0A,0x1D,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002AD8    "p..\._GP" */
  21.759 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002AE0    "EDPT1p.." */
  21.760 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002AE8    "\._GPEDP" */
  21.761 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002AF0    "T2. _PS3" */
  21.762 +    0x00,0x70,0x0A,0x1D,0x5C,0x2E,0x5F,0x47,  /* 00002AF8    ".p..\._G" */
  21.763 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002B00    "PEDPT1p." */
  21.764 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002B08    ".\._GPED" */
  21.765 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00002B10    "PT2.,_EJ" */
  21.766 +    0x30,0x01,0x70,0x0A,0x1D,0x5C,0x2E,0x5F,  /* 00002B18    "0.p..\._" */
  21.767 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00002B20    "GPEDPT1p" */
  21.768 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002B28    "..\._GPE" */
  21.769 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00002B30    "DPT2p.\." */
  21.770 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x44,  /* 00002B38    "_GPEPH1D" */
  21.771 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002B40    ".+_STA.p" */
  21.772 +    0x0A,0x1D,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002B48    "..\._GPE" */
  21.773 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002B50    "DPT1p..\" */
  21.774 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002B58    "._GPEDPT" */
  21.775 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002B60    "2.\._GPE" */
  21.776 +    0x50,0x48,0x31,0x44,0x5B,0x82,0x42,0x0B,  /* 00002B68    "PH1D[.B." */
  21.777 +    0x53,0x31,0x45,0x5F,0x08,0x5F,0x41,0x44,  /* 00002B70    "S1E_._AD" */
  21.778 +    0x52,0x0C,0x00,0x00,0x1E,0x00,0x08,0x5F,  /* 00002B78    "R......_" */
  21.779 +    0x53,0x55,0x4E,0x0A,0x1E,0x14,0x20,0x5F,  /* 00002B80    "SUN... _" */
  21.780 +    0x50,0x53,0x30,0x00,0x70,0x0A,0x1E,0x5C,  /* 00002B88    "PS0.p..\" */
  21.781 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002B90    "._GPEDPT" */
  21.782 +    0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,  /* 00002B98    "1p..\._G" */
  21.783 +    0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20,  /* 00002BA0    "PEDPT2. " */
  21.784 +    0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x1E,  /* 00002BA8    "_PS3.p.." */
  21.785 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002BB0    "\._GPEDP" */
  21.786 +    0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,  /* 00002BB8    "T1p..\._" */
  21.787 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00002BC0    "GPEDPT2." */
  21.788 +    0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A,  /* 00002BC8    ",_EJ0.p." */
  21.789 +    0x1E,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002BD0    ".\._GPED" */
  21.790 +    0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E,  /* 00002BD8    "PT1p..\." */
  21.791 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00002BE0    "_GPEDPT2" */
  21.792 +    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002BE8    "p.\._GPE" */
  21.793 +    0x50,0x48,0x31,0x45,0x14,0x2B,0x5F,0x53,  /* 00002BF0    "PH1E.+_S" */
  21.794 +    0x54,0x41,0x00,0x70,0x0A,0x1E,0x5C,0x2E,  /* 00002BF8    "TA.p..\." */
  21.795 +    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31,  /* 00002C00    "_GPEDPT1" */
  21.796 +    0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002C08    "p..\._GP" */
  21.797 +    0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E,  /* 00002C10    "EDPT2.\." */
  21.798 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x45,  /* 00002C18    "_GPEPH1E" */
  21.799 +    0x5B,0x82,0x42,0x0B,0x53,0x31,0x46,0x5F,  /* 00002C20    "[.B.S1F_" */
  21.800 +    0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,  /* 00002C28    "._ADR..." */
  21.801 +    0x1F,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A,  /* 00002C30    "..._SUN." */
  21.802 +    0x1F,0x14,0x20,0x5F,0x50,0x53,0x30,0x00,  /* 00002C38    ".. _PS0." */
  21.803 +    0x70,0x0A,0x1F,0x5C,0x2E,0x5F,0x47,0x50,  /* 00002C40    "p..\._GP" */
  21.804 +    0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80,  /* 00002C48    "EDPT1p.." */
  21.805 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,  /* 00002C50    "\._GPEDP" */
  21.806 +    0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33,  /* 00002C58    "T2. _PS3" */
  21.807 +    0x00,0x70,0x0A,0x1F,0x5C,0x2E,0x5F,0x47,  /* 00002C60    ".p..\._G" */
  21.808 +    0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A,  /* 00002C68    "PEDPT1p." */
  21.809 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00002C70    ".\._GPED" */
  21.810 +    0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A,  /* 00002C78    "PT2.,_EJ" */
  21.811 +    0x30,0x01,0x70,0x0A,0x1F,0x5C,0x2E,0x5F,  /* 00002C80    "0.p..\._" */
  21.812 +    0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70,  /* 00002C88    "GPEDPT1p" */
  21.813 +    0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002C90    "..\._GPE" */
  21.814 +    0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E,  /* 00002C98    "DPT2p.\." */
  21.815 +    0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x46,  /* 00002CA0    "_GPEPH1F" */
  21.816 +    0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70,  /* 00002CA8    ".+_STA.p" */
  21.817 +    0x0A,0x1F,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002CB0    "..\._GPE" */
  21.818 +    0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C,  /* 00002CB8    "DPT1p..\" */
  21.819 +    0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54,  /* 00002CC0    "._GPEDPT" */
  21.820 +    0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00002CC8    "2.\._GPE" */
  21.821 +    0x50,0x48,0x31,0x46,0x10,0x4D,0x52,0x5F,  /* 00002CD0    "PH1F.MR_" */
  21.822 +    0x47,0x50,0x45,0x5B,0x80,0x50,0x48,0x50,  /* 00002CD8    "GPE[.PHP" */
  21.823 +    0x5F,0x01,0x0B,0xC0,0x10,0x0A,0x22,0x5B,  /* 00002CE0    "_....."[" */
  21.824 +    0x81,0x41,0x0B,0x50,0x48,0x50,0x5F,0x01,  /* 00002CE8    ".A.PHP_." */
  21.825 +    0x50,0x53,0x54,0x41,0x08,0x50,0x53,0x54,  /* 00002CF0    "PSTA.PST" */
  21.826 +    0x42,0x08,0x50,0x48,0x30,0x30,0x08,0x50,  /* 00002CF8    "B.PH00.P" */
  21.827 +    0x48,0x30,0x31,0x08,0x50,0x48,0x30,0x32,  /* 00002D00    "H01.PH02" */
  21.828 +    0x08,0x50,0x48,0x30,0x33,0x08,0x50,0x48,  /* 00002D08    ".PH03.PH" */
  21.829 +    0x30,0x34,0x08,0x50,0x48,0x30,0x35,0x08,  /* 00002D10    "04.PH05." */
  21.830 +    0x50,0x48,0x30,0x36,0x08,0x50,0x48,0x30,  /* 00002D18    "PH06.PH0" */
  21.831 +    0x37,0x08,0x50,0x48,0x30,0x38,0x08,0x50,  /* 00002D20    "7.PH08.P" */
  21.832 +    0x48,0x30,0x39,0x08,0x50,0x48,0x30,0x41,  /* 00002D28    "H09.PH0A" */
  21.833 +    0x08,0x50,0x48,0x30,0x42,0x08,0x50,0x48,  /* 00002D30    ".PH0B.PH" */
  21.834 +    0x30,0x43,0x08,0x50,0x48,0x30,0x44,0x08,  /* 00002D38    "0C.PH0D." */
  21.835 +    0x50,0x48,0x30,0x45,0x08,0x50,0x48,0x30,  /* 00002D40    "PH0E.PH0" */
  21.836 +    0x46,0x08,0x50,0x48,0x31,0x30,0x08,0x50,  /* 00002D48    "F.PH10.P" */
  21.837 +    0x48,0x31,0x31,0x08,0x50,0x48,0x31,0x32,  /* 00002D50    "H11.PH12" */
  21.838 +    0x08,0x50,0x48,0x31,0x33,0x08,0x50,0x48,  /* 00002D58    ".PH13.PH" */
  21.839 +    0x31,0x34,0x08,0x50,0x48,0x31,0x35,0x08,  /* 00002D60    "14.PH15." */
  21.840 +    0x50,0x48,0x31,0x36,0x08,0x50,0x48,0x31,  /* 00002D68    "PH16.PH1" */
  21.841 +    0x37,0x08,0x50,0x48,0x31,0x38,0x08,0x50,  /* 00002D70    "7.PH18.P" */
  21.842 +    0x48,0x31,0x39,0x08,0x50,0x48,0x31,0x41,  /* 00002D78    "H19.PH1A" */
  21.843 +    0x08,0x50,0x48,0x31,0x42,0x08,0x50,0x48,  /* 00002D80    ".PH1B.PH" */
  21.844 +    0x31,0x43,0x08,0x50,0x48,0x31,0x44,0x08,  /* 00002D88    "1C.PH1D." */
  21.845 +    0x50,0x48,0x31,0x45,0x08,0x50,0x48,0x31,  /* 00002D90    "PH1E.PH1" */
  21.846 +    0x46,0x08,0x5B,0x80,0x44,0x47,0x31,0x5F,  /* 00002D98    "F.[.DG1_" */
  21.847 +    0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B,0x81,  /* 00002DA0    "..D...[." */
  21.848 +    0x10,0x44,0x47,0x31,0x5F,0x01,0x44,0x50,  /* 00002DA8    ".DG1_.DP" */
  21.849 +    0x54,0x31,0x08,0x44,0x50,0x54,0x32,0x08,  /* 00002DB0    "T1.DPT2." */
  21.850 +    0x14,0x49,0x44,0x5F,0x4C,0x30,0x33,0x08,  /* 00002DB8    ".ID_L03." */
  21.851 +    0x08,0x5F,0x54,0x5F,0x30,0x00,0x08,0x53,  /* 00002DC0    "._T_0..S" */
  21.852 +    0x4C,0x54,0x5F,0x00,0x08,0x45,0x56,0x54,  /* 00002DC8    "LT_..EVT" */
  21.853 +    0x5F,0x00,0x70,0x50,0x53,0x54,0x41,0x61,  /* 00002DD0    "_.pPSTAa" */
  21.854 +    0x7B,0x61,0x0A,0x0F,0x45,0x56,0x54,0x5F,  /* 00002DD8    "{a..EVT_" */
  21.855 +    0x70,0x50,0x53,0x54,0x42,0x61,0x7B,0x61,  /* 00002DE0    "pPSTBa{a" */
  21.856 +    0x0A,0xFF,0x53,0x4C,0x54,0x5F,0x70,0x53,  /* 00002DE8    "..SLT_pS" */
  21.857 +    0x4C,0x54,0x5F,0x44,0x50,0x54,0x31,0x70,  /* 00002DF0    "LT_DPT1p" */
  21.858 +    0x45,0x56,0x54,0x5F,0x44,0x50,0x54,0x32,  /* 00002DF8    "EVT_DPT2" */
  21.859 +    0x70,0x53,0x4C,0x54,0x5F,0x5F,0x54,0x5F,  /* 00002E00    "pSLT__T_" */
  21.860 +    0x30,0xA0,0x1B,0x93,0x5F,0x54,0x5F,0x30,  /* 00002E08    "0..._T_0" */
  21.861 +    0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,  /* 00002E10    "..\/._SB" */
  21.862 +    0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x30,  /* 00002E18    "_PCI0S00" */
  21.863 +    0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4C,0x3D,  /* 00002E20    "_EVT_.L=" */
  21.864 +    0xA0,0x1B,0x93,0x5F,0x54,0x5F,0x30,0x01,  /* 00002E28    "..._T_0." */
  21.865 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002E30    ".\/._SB_" */
  21.866 +    0x50,0x43,0x49,0x30,0x53,0x30,0x31,0x5F,  /* 00002E38    "PCI0S01_" */
  21.867 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x3B,0xA0,  /* 00002E40    "EVT_.M;." */
  21.868 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x02,  /* 00002E48    ".._T_0.." */
  21.869 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002E50    ".\/._SB_" */
  21.870 +    0x50,0x43,0x49,0x30,0x53,0x30,0x32,0x5F,  /* 00002E58    "PCI0S02_" */
  21.871 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x39,0xA0,  /* 00002E60    "EVT_.M9." */
  21.872 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x03,  /* 00002E68    ".._T_0.." */
  21.873 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002E70    ".\/._SB_" */
  21.874 +    0x50,0x43,0x49,0x30,0x53,0x30,0x33,0x5F,  /* 00002E78    "PCI0S03_" */
  21.875 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x37,0xA0,  /* 00002E80    "EVT_.M7." */
  21.876 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x04,  /* 00002E88    ".._T_0.." */
  21.877 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002E90    ".\/._SB_" */
  21.878 +    0x50,0x43,0x49,0x30,0x53,0x30,0x34,0x5F,  /* 00002E98    "PCI0S04_" */
  21.879 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x35,0xA0,  /* 00002EA0    "EVT_.M5." */
  21.880 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x05,  /* 00002EA8    ".._T_0.." */
  21.881 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002EB0    ".\/._SB_" */
  21.882 +    0x50,0x43,0x49,0x30,0x53,0x30,0x35,0x5F,  /* 00002EB8    "PCI0S05_" */
  21.883 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x33,0xA0,  /* 00002EC0    "EVT_.M3." */
  21.884 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x06,  /* 00002EC8    ".._T_0.." */
  21.885 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002ED0    ".\/._SB_" */
  21.886 +    0x50,0x43,0x49,0x30,0x53,0x30,0x36,0x5F,  /* 00002ED8    "PCI0S06_" */
  21.887 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x31,0xA0,  /* 00002EE0    "EVT_.M1." */
  21.888 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x07,  /* 00002EE8    ".._T_0.." */
  21.889 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002EF0    ".\/._SB_" */
  21.890 +    0x50,0x43,0x49,0x30,0x53,0x30,0x37,0x5F,  /* 00002EF8    "PCI0S07_" */
  21.891 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2F,0xA0,  /* 00002F00    "EVT_.M/." */
  21.892 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x08,  /* 00002F08    ".._T_0.." */
  21.893 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002F10    ".\/._SB_" */
  21.894 +    0x50,0x43,0x49,0x30,0x53,0x30,0x38,0x5F,  /* 00002F18    "PCI0S08_" */
  21.895 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2D,0xA0,  /* 00002F20    "EVT_.M-." */
  21.896 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x09,  /* 00002F28    ".._T_0.." */
  21.897 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002F30    ".\/._SB_" */
  21.898 +    0x50,0x43,0x49,0x30,0x53,0x30,0x39,0x5F,  /* 00002F38    "PCI0S09_" */
  21.899 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2B,0xA0,  /* 00002F40    "EVT_.M+." */
  21.900 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0A,  /* 00002F48    ".._T_0.." */
  21.901 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002F50    ".\/._SB_" */
  21.902 +    0x50,0x43,0x49,0x30,0x53,0x30,0x41,0x5F,  /* 00002F58    "PCI0S0A_" */
  21.903 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x29,0xA0,  /* 00002F60    "EVT_.M)." */
  21.904 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0B,  /* 00002F68    ".._T_0.." */
  21.905 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002F70    ".\/._SB_" */
  21.906 +    0x50,0x43,0x49,0x30,0x53,0x30,0x42,0x5F,  /* 00002F78    "PCI0S0B_" */
  21.907 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x27,0xA0,  /* 00002F80    "EVT_.M'." */
  21.908 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0C,  /* 00002F88    ".._T_0.." */
  21.909 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002F90    ".\/._SB_" */
  21.910 +    0x50,0x43,0x49,0x30,0x53,0x30,0x43,0x5F,  /* 00002F98    "PCI0S0C_" */
  21.911 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x25,0xA0,  /* 00002FA0    "EVT_.M%." */
  21.912 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0D,  /* 00002FA8    ".._T_0.." */
  21.913 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002FB0    ".\/._SB_" */
  21.914 +    0x50,0x43,0x49,0x30,0x53,0x30,0x44,0x5F,  /* 00002FB8    "PCI0S0D_" */
  21.915 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x23,0xA0,  /* 00002FC0    "EVT_.M#." */
  21.916 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0E,  /* 00002FC8    ".._T_0.." */
  21.917 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002FD0    ".\/._SB_" */
  21.918 +    0x50,0x43,0x49,0x30,0x53,0x30,0x45,0x5F,  /* 00002FD8    "PCI0S0E_" */
  21.919 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x21,0xA0,  /* 00002FE0    "EVT_.M!." */
  21.920 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0F,  /* 00002FE8    ".._T_0.." */
  21.921 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00002FF0    ".\/._SB_" */
  21.922 +    0x50,0x43,0x49,0x30,0x53,0x30,0x46,0x5F,  /* 00002FF8    "PCI0S0F_" */
  21.923 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1F,0xA0,  /* 00003000    "EVT_.M.." */
  21.924 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x10,  /* 00003008    ".._T_0.." */
  21.925 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003010    ".\/._SB_" */
  21.926 +    0x50,0x43,0x49,0x30,0x53,0x31,0x30,0x5F,  /* 00003018    "PCI0S10_" */
  21.927 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1D,0xA0,  /* 00003020    "EVT_.M.." */
  21.928 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x11,  /* 00003028    ".._T_0.." */
  21.929 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003030    ".\/._SB_" */
  21.930 +    0x50,0x43,0x49,0x30,0x53,0x31,0x31,0x5F,  /* 00003038    "PCI0S11_" */
  21.931 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1B,0xA0,  /* 00003040    "EVT_.M.." */
  21.932 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x12,  /* 00003048    ".._T_0.." */
  21.933 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003050    ".\/._SB_" */
  21.934 +    0x50,0x43,0x49,0x30,0x53,0x31,0x32,0x5F,  /* 00003058    "PCI0S12_" */
  21.935 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x19,0xA0,  /* 00003060    "EVT_.M.." */
  21.936 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x13,  /* 00003068    ".._T_0.." */
  21.937 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003070    ".\/._SB_" */
  21.938 +    0x50,0x43,0x49,0x30,0x53,0x31,0x33,0x5F,  /* 00003078    "PCI0S13_" */
  21.939 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x17,0xA0,  /* 00003080    "EVT_.M.." */
  21.940 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x14,  /* 00003088    ".._T_0.." */
  21.941 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003090    ".\/._SB_" */
  21.942 +    0x50,0x43,0x49,0x30,0x53,0x31,0x34,0x5F,  /* 00003098    "PCI0S14_" */
  21.943 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x15,0xA0,  /* 000030A0    "EVT_.M.." */
  21.944 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x15,  /* 000030A8    ".._T_0.." */
  21.945 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 000030B0    ".\/._SB_" */
  21.946 +    0x50,0x43,0x49,0x30,0x53,0x31,0x35,0x5F,  /* 000030B8    "PCI0S15_" */
  21.947 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x13,0xA0,  /* 000030C0    "EVT_.M.." */
  21.948 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x16,  /* 000030C8    ".._T_0.." */
  21.949 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 000030D0    ".\/._SB_" */
  21.950 +    0x50,0x43,0x49,0x30,0x53,0x31,0x36,0x5F,  /* 000030D8    "PCI0S16_" */
  21.951 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x11,0xA0,  /* 000030E0    "EVT_.M.." */
  21.952 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x17,  /* 000030E8    ".._T_0.." */
  21.953 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 000030F0    ".\/._SB_" */
  21.954 +    0x50,0x43,0x49,0x30,0x53,0x31,0x37,0x5F,  /* 000030F8    "PCI0S17_" */
  21.955 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0F,0xA0,  /* 00003100    "EVT_.M.." */
  21.956 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x18,  /* 00003108    ".._T_0.." */
  21.957 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003110    ".\/._SB_" */
  21.958 +    0x50,0x43,0x49,0x30,0x53,0x31,0x38,0x5F,  /* 00003118    "PCI0S18_" */
  21.959 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0D,0xA0,  /* 00003120    "EVT_.M.." */
  21.960 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x19,  /* 00003128    ".._T_0.." */
  21.961 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003130    ".\/._SB_" */
  21.962 +    0x50,0x43,0x49,0x30,0x53,0x31,0x39,0x5F,  /* 00003138    "PCI0S19_" */
  21.963 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0B,0xA0,  /* 00003140    "EVT_.M.." */
  21.964 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1A,  /* 00003148    ".._T_0.." */
  21.965 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003150    ".\/._SB_" */
  21.966 +    0x50,0x43,0x49,0x30,0x53,0x31,0x41,0x5F,  /* 00003158    "PCI0S1A_" */
  21.967 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x09,0xA0,  /* 00003160    "EVT_.M.." */
  21.968 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1B,  /* 00003168    ".._T_0.." */
  21.969 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003170    ".\/._SB_" */
  21.970 +    0x50,0x43,0x49,0x30,0x53,0x31,0x42,0x5F,  /* 00003178    "PCI0S1B_" */
  21.971 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x07,0xA0,  /* 00003180    "EVT_.M.." */
  21.972 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1C,  /* 00003188    ".._T_0.." */
  21.973 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 00003190    ".\/._SB_" */
  21.974 +    0x50,0x43,0x49,0x30,0x53,0x31,0x43,0x5F,  /* 00003198    "PCI0S1C_" */
  21.975 +    0x45,0x56,0x54,0x5F,0xA1,0x4D,0x05,0xA0,  /* 000031A0    "EVT_.M.." */
  21.976 +    0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1D,  /* 000031A8    ".._T_0.." */
  21.977 +    0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,  /* 000031B0    ".\/._SB_" */
  21.978 +    0x50,0x43,0x49,0x30,0x53,0x31,0x44,0x5F,  /* 000031B8    "PCI0S1D_" */
  21.979 +    0x45,0x56,0x54,0x5F,0xA1,0x3D,0xA0,0x1C,  /* 000031C0    "EVT_.=.." */
  21.980 +    0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1E,0x86,  /* 000031C8    "._T_0..." */
  21.981 +    0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,  /* 000031D0    "\/._SB_P" */
  21.982 +    0x43,0x49,0x30,0x53,0x31,0x45,0x5F,0x45,  /* 000031D8    "CI0S1E_E" */
  21.983 +    0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,  /* 000031E0    "VT_....." */
  21.984 +    0x5F,0x54,0x5F,0x30,0x0A,0x1F,0x86,0x5C,  /* 000031E8    "_T_0...\" */
  21.985 +    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 000031F0    "/._SB_PC" */
  21.986 +    0x49,0x30,0x53,0x31,0x46,0x5F,0x45,0x56,  /* 000031F8    "I0S1F_EV" */
  21.987 +    0x54,0x5F,
  21.988  };
  21.989  int DsdtLen=sizeof(AmlCode);
    22.1 --- a/tools/firmware/hvmloader/config.h	Fri Mar 27 10:54:08 2009 +0900
    22.2 +++ b/tools/firmware/hvmloader/config.h	Fri Mar 27 11:07:11 2009 +0900
    22.3 @@ -47,6 +47,7 @@ extern unsigned long pci_mem_start, pci_
    22.4  #define E820_OFFSET                   0x8
    22.5  
    22.6  /* Xen Platform Device */
    22.7 +#define XEN_PF_IOBASE   0x10
    22.8  #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
    22.9  
   22.10  /* Located at BIOS_INFO_PHYSICAL_ADDRESS. */
   22.11 @@ -56,9 +57,7 @@ struct bios_info {
   22.12      uint8_t  hpet_present:1;    /* 0[2] - System has HPET? */
   22.13      uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
   22.14      uint32_t bios32_entry;      /* 12   - Entry point for 32-bit BIOS */
   22.15 -    uint16_t xen_pfiob;         /* 16   - Xen platform device I/O ports */
   22.16  };
   22.17  #define BIOSINFO_OFF_bios32_entry 12
   22.18 -#define BIOSINFO_OFF_xen_pfiob    16
   22.19  
   22.20  #endif /* __HVMLOADER_CONFIG_H__ */
    23.1 --- a/tools/firmware/hvmloader/hvmloader.c	Fri Mar 27 10:54:08 2009 +0900
    23.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Fri Mar 27 11:07:11 2009 +0900
    23.3 @@ -539,25 +539,6 @@ static void cmos_write_memory_size(void)
    23.4      cmos_outb(0x35, (uint8_t)( alt_mem >> 8));
    23.5  }
    23.6  
    23.7 -static uint16_t xen_platform_io_base(void)
    23.8 -{
    23.9 -    uint32_t devfn, bar_data;
   23.10 -    uint16_t vendor_id, device_id;
   23.11 -
   23.12 -    for ( devfn = 0; devfn < 128; devfn++ )
   23.13 -    {
   23.14 -        vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
   23.15 -        device_id = pci_readw(devfn, PCI_DEVICE_ID);
   23.16 -        if ( (vendor_id == 0x5853) && (device_id == 0x0001) )
   23.17 -        {
   23.18 -            bar_data = pci_readl(devfn, PCI_BASE_ADDRESS_0);
   23.19 -            return bar_data & PCI_BASE_ADDRESS_IO_MASK;
   23.20 -        }
   23.21 -    }
   23.22 -
   23.23 -    return 0;
   23.24 -}
   23.25 -
   23.26  /*
   23.27   * Set up an empty TSS area for virtual 8086 mode to use. 
   23.28   * The only important thing is that it musn't have any bits set 
   23.29 @@ -744,7 +725,6 @@ int main(void)
   23.30      bios_info->pci_min = pci_mem_start;
   23.31      bios_info->pci_len = pci_mem_end - pci_mem_start;
   23.32      bios_info->bios32_entry = bios32_addr;
   23.33 -    bios_info->xen_pfiob = xen_platform_io_base();
   23.34  
   23.35      printf("Invoking ROMBIOS ...\n");
   23.36      return 0;
    24.1 --- a/tools/firmware/rombios/32bit/pmm.c	Fri Mar 27 10:54:08 2009 +0900
    24.2 +++ b/tools/firmware/rombios/32bit/pmm.c	Fri Mar 27 11:07:11 2009 +0900
    24.3 @@ -71,10 +71,13 @@
    24.4  
    24.5  #define DEBUG_PMM 0
    24.6  
    24.7 +#define __stringify(a) #a
    24.8 +#define stringify(a) __stringify(a)
    24.9 +
   24.10  #define ASSERT(_expr, _action)                                  \
   24.11      if (!(_expr)) {                                             \
   24.12          printf("ASSERTION FAIL: %s %s:%d %s()\n",               \
   24.13 -               __STRING(_expr), __FILE__, __LINE__, __func__);  \
   24.14 +               stringify(_expr), __FILE__, __LINE__, __func__); \
   24.15          _action;                                                \
   24.16      } else
   24.17  
    25.1 --- a/tools/firmware/rombios/rombios.c	Fri Mar 27 10:54:08 2009 +0900
    25.2 +++ b/tools/firmware/rombios/rombios.c	Fri Mar 27 11:07:11 2009 +0900
    25.3 @@ -1418,24 +1418,14 @@ fixup_base_mem_in_k()
    25.4    write_word(0x40, 0x13, base_mem >> 10);
    25.5  }
    25.6  
    25.7 -ASM_START
    25.8 -_rom_write_access_control:
    25.9 -    push ds
   25.10 -    mov ax,#(BIOS_INFO_PHYSICAL_ADDRESS >> 4)
   25.11 -    mov ds,ax
   25.12 -    mov ax,[BIOSINFO_OFF_xen_pfiob]
   25.13 -    pop ds
   25.14 -    ret
   25.15 -ASM_END
   25.16 -
   25.17  void enable_rom_write_access()
   25.18  {
   25.19 -    outb(rom_write_access_control(), 0);
   25.20 +    outb(XEN_PF_IOBASE, 0);
   25.21  }
   25.22  
   25.23  void disable_rom_write_access()
   25.24  {
   25.25 -    outb(rom_write_access_control(), PFFLAG_ROM_LOCK);
   25.26 +    outb(XEN_PF_IOBASE, PFFLAG_ROM_LOCK);
   25.27  }
   25.28      
   25.29  #endif /* HVMASSIST */
    26.1 --- a/tools/fs-back/Makefile	Fri Mar 27 10:54:08 2009 +0900
    26.2 +++ b/tools/fs-back/Makefile	Fri Mar 27 11:07:11 2009 +0900
    26.3 @@ -16,7 +16,7 @@ CFLAGS   += -D_GNU_SOURCE
    26.4  LIBS      := -L. -L.. -L../lib
    26.5  LIBS      += $(LDFLAGS_libxenctrl)
    26.6  LIBS      += $(LDFLAGS_libxenstore)
    26.7 -LIBS      += -lpthread -lrt 
    26.8 +LIBS      += -lrt 
    26.9  
   26.10  OBJS	  := fs-xenbus.o fs-ops.o
   26.11  
    27.1 --- a/tools/fs-back/fs-backend.c	Fri Mar 27 10:54:08 2009 +0900
    27.2 +++ b/tools/fs-back/fs-backend.c	Fri Mar 27 11:07:11 2009 +0900
    27.3 @@ -1,108 +1,76 @@
    27.4  #undef NDEBUG
    27.5 +#include <unistd.h>
    27.6  #include <stdio.h>
    27.7  #include <string.h>
    27.8  #include <assert.h>
    27.9  #include <malloc.h>
   27.10 -#include <pthread.h>
   27.11  #include <xenctrl.h>
   27.12  #include <aio.h>
   27.13  #include <sys/mman.h>
   27.14  #include <sys/select.h>
   27.15 +#include <sys/socket.h>
   27.16  #include <xen/io/ring.h>
   27.17 +#include <xc_private.h>
   27.18 +#include <err.h>
   27.19 +#include "sys-queue.h"
   27.20  #include "fs-backend.h"
   27.21 +#include "fs-debug.h"
   27.22  
   27.23  struct xs_handle *xsh = NULL;
   27.24  static struct fs_export *fs_exports = NULL;
   27.25  static int export_id = 0;
   27.26  static int mount_id = 0;
   27.27 +static int pipefds[2];
   27.28 +static LIST_HEAD(mount_requests_head, fs_mount) mount_requests_head;
   27.29  
   27.30 -static void dispatch_response(struct fs_mount *mount, int priv_req_id)
   27.31 +static void free_mount_request(struct fs_mount *mount);
   27.32 +
   27.33 +static void dispatch_response(struct fs_request *request)
   27.34  {
   27.35      int i;
   27.36      struct fs_op *op;
   27.37 -    struct fs_request *req = &mount->requests[priv_req_id];
   27.38  
   27.39      for(i=0;;i++)
   27.40      {
   27.41          op = fsops[i];
   27.42          /* We should dispatch a response before reaching the end of the array */
   27.43          assert(op != NULL);
   27.44 -        if(op->type == req->req_shadow.type)
   27.45 +        if(op->type == request->req_shadow.type)
   27.46          {
   27.47 -            printf("Found op for type=%d\n", op->type);
   27.48 +            FS_DEBUG("Found op for type=%d\n", op->type);
   27.49              /* There needs to be a response handler */
   27.50              assert(op->response_handler != NULL);
   27.51 -            op->response_handler(mount, req);
   27.52 +            op->response_handler(request->mount, request);
   27.53              break;
   27.54          }
   27.55      }
   27.56  
   27.57 -    req->active = 0;
   27.58 -    add_id_to_freelist(priv_req_id, mount->freelist);
   27.59 +    request->active = 0;
   27.60 +    add_id_to_freelist(request->id, request->mount->freelist);
   27.61  }
   27.62  
   27.63 -static void handle_aio_events(struct fs_mount *mount)
   27.64 +static void handle_aio_event(struct fs_request *request)
   27.65  {
   27.66 -    int fd, ret, count, i, notify;
   27.67 -    evtchn_port_t port;
   27.68 -    /* AIO control block for the evtchn file destriptor */
   27.69 -    struct aiocb evtchn_cb;
   27.70 -    const struct aiocb * cb_list[mount->nr_entries];
   27.71 -    int request_ids[mount->nr_entries];
   27.72 -
   27.73 -    /* Prepare the AIO control block for evtchn */ 
   27.74 -    fd = xc_evtchn_fd(mount->evth); 
   27.75 -    bzero(&evtchn_cb, sizeof(struct aiocb));
   27.76 -    evtchn_cb.aio_fildes = fd;
   27.77 -    evtchn_cb.aio_nbytes = sizeof(port);
   27.78 -    evtchn_cb.aio_buf = &port;
   27.79 -    assert(aio_read(&evtchn_cb) == 0);
   27.80 +    int ret, notify;
   27.81  
   27.82 -wait_again:   
   27.83 -    /* Create list of active AIO requests */
   27.84 -    count = 0;
   27.85 -    for(i=0; i<mount->nr_entries; i++)
   27.86 -        if(mount->requests[i].active)
   27.87 -        {
   27.88 -            cb_list[count] = &mount->requests[i].aiocb;
   27.89 -            request_ids[count] = i;
   27.90 -            count++;
   27.91 -        }
   27.92 -    /* Add the event channel at the end of the list. Event channel needs to be
   27.93 -     * handled last as it exits this function. */
   27.94 -    cb_list[count] = &evtchn_cb;
   27.95 -    request_ids[count] = -1;
   27.96 -    count++;
   27.97 +    FS_DEBUG("handle_aio_event: mount %s request %d\n", request->mount->frontend, request->id);
   27.98 +    if (request->active < 0) {
   27.99 +        request->mount->nr_entries++;
  27.100 +        if (!request->mount->nr_entries)
  27.101 +            free_mount_request(request->mount);
  27.102 +        return;
  27.103 +    }
  27.104  
  27.105 -    /* Block till an AIO requset finishes, or we get an event */ 
  27.106 -    while(1) {
  27.107 -	int ret = aio_suspend(cb_list, count, NULL);
  27.108 -	if (!ret)
  27.109 -	    break;
  27.110 -	assert(errno == EINTR);
  27.111 -    }
  27.112 -    for(i=0; i<count; i++)
  27.113 -        if(aio_error(cb_list[i]) != EINPROGRESS)
  27.114 -        {
  27.115 -            if(request_ids[i] >= 0)
  27.116 -                dispatch_response(mount, request_ids[i]);
  27.117 -            else
  27.118 -                goto read_event_channel;
  27.119 -        }
  27.120 - 
  27.121 -    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify);
  27.122 -    printf("Pushed responces and notify=%d\n", notify);
  27.123 +    ret = aio_error(&request->aiocb);
  27.124 +    if(ret != EINPROGRESS && ret != ECANCELED)
  27.125 +        dispatch_response(request);
  27.126 +
  27.127 +    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&request->mount->ring, notify);
  27.128 +    FS_DEBUG("Pushed responces and notify=%d\n", notify);
  27.129      if(notify)
  27.130 -        xc_evtchn_notify(mount->evth, mount->local_evtchn);
  27.131 -    
  27.132 -    goto wait_again;
  27.133 -
  27.134 -read_event_channel:    
  27.135 -    assert(aio_return(&evtchn_cb) == sizeof(evtchn_port_t)); 
  27.136 -    assert(xc_evtchn_unmask(mount->evth, mount->local_evtchn) >= 0);
  27.137 +        xc_evtchn_notify(request->mount->evth, request->mount->local_evtchn);
  27.138  }
  27.139  
  27.140 -
  27.141  static void allocate_request_array(struct fs_mount *mount)
  27.142  {
  27.143      int i, nr_entries = mount->nr_entries;
  27.144 @@ -116,6 +84,7 @@ static void allocate_request_array(struc
  27.145      for(i=0; i< nr_entries; i++)
  27.146      {
  27.147          requests[i].active = 0; 
  27.148 +        requests[i].mount = mount; 
  27.149          add_id_to_freelist(i, freelist);
  27.150      }
  27.151      mount->requests = requests;
  27.152 @@ -123,86 +92,102 @@ static void allocate_request_array(struc
  27.153  }
  27.154  
  27.155  
  27.156 -static void *handle_mount(void *data)
  27.157 +static void handle_mount(struct fs_mount *mount)
  27.158  {
  27.159      int more, notify;
  27.160 -    struct fs_mount *mount = (struct fs_mount *)data;
  27.161 -    
  27.162 -    printf("Starting a thread for mount: %d\n", mount->mount_id);
  27.163 -    allocate_request_array(mount);
  27.164 +    int nr_consumed=0;
  27.165 +    RING_IDX cons, rp;
  27.166 +    struct fsif_request *req;
  27.167  
  27.168 -    for(;;)
  27.169 -    {
  27.170 -        int nr_consumed=0;
  27.171 -        RING_IDX cons, rp;
  27.172 -        struct fsif_request *req;
  27.173 -
  27.174 -        handle_aio_events(mount);
  27.175  moretodo:
  27.176 -        rp = mount->ring.sring->req_prod;
  27.177 -        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
  27.178 +    rp = mount->ring.sring->req_prod;
  27.179 +    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
  27.180  
  27.181 -        while ((cons = mount->ring.req_cons) != rp)
  27.182 +    while ((cons = mount->ring.req_cons) != rp)
  27.183 +    {
  27.184 +        int i;
  27.185 +        struct fs_op *op;
  27.186 +
  27.187 +        FS_DEBUG("Got a request at %d (of %d)\n", 
  27.188 +                cons, RING_SIZE(&mount->ring));
  27.189 +        req = RING_GET_REQUEST(&mount->ring, cons);
  27.190 +        FS_DEBUG("Request type=%d\n", req->type); 
  27.191 +        for(i=0;;i++)
  27.192          {
  27.193 -            int i;
  27.194 -            struct fs_op *op;
  27.195 -
  27.196 -            printf("Got a request at %d (of %d)\n", 
  27.197 -                    cons, RING_SIZE(&mount->ring));
  27.198 -            req = RING_GET_REQUEST(&mount->ring, cons);
  27.199 -            printf("Request type=%d\n", req->type); 
  27.200 -            for(i=0;;i++)
  27.201 +            op = fsops[i];
  27.202 +            if(op == NULL)
  27.203              {
  27.204 -                op = fsops[i];
  27.205 -                if(op == NULL)
  27.206 -                {
  27.207 -                    /* We've reached the end of the array, no appropirate
  27.208 -                     * handler found. Warn, ignore and continue. */
  27.209 -                    printf("WARN: Unknown request type: %d\n", req->type);
  27.210 -                    mount->ring.req_cons++; 
  27.211 -                    break;
  27.212 -                }
  27.213 -                if(op->type == req->type)
  27.214 -                {
  27.215 -                    /* There needs to be a dispatch handler */
  27.216 -                    assert(op->dispatch_handler != NULL);
  27.217 -                    op->dispatch_handler(mount, req);
  27.218 -                    break;
  27.219 -                }
  27.220 -             }
  27.221 +                /* We've reached the end of the array, no appropirate
  27.222 +                 * handler found. Warn, ignore and continue. */
  27.223 +                FS_DEBUG("WARN: Unknown request type: %d\n", req->type);
  27.224 +                mount->ring.req_cons++; 
  27.225 +                break;
  27.226 +            }
  27.227 +            if(op->type == req->type)
  27.228 +            {
  27.229 +                /* There needs to be a dispatch handler */
  27.230 +                assert(op->dispatch_handler != NULL);
  27.231 +                op->dispatch_handler(mount, req);
  27.232 +                break;
  27.233 +            }
  27.234 +        }
  27.235  
  27.236 -            nr_consumed++;
  27.237 -        }
  27.238 -        printf("Backend consumed: %d requests\n", nr_consumed);
  27.239 -        RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more);
  27.240 -        if(more) goto moretodo;
  27.241 +        nr_consumed++;
  27.242 +    }
  27.243 +    FS_DEBUG("Backend consumed: %d requests\n", nr_consumed);
  27.244 +    RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more);
  27.245 +    if(more) goto moretodo;
  27.246  
  27.247 -        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify);
  27.248 -        printf("Pushed responces and notify=%d\n", notify);
  27.249 -        if(notify)
  27.250 -            xc_evtchn_notify(mount->evth, mount->local_evtchn);
  27.251 -    }
  27.252 - 
  27.253 -    printf("Destroying thread for mount: %d\n", mount->mount_id);
  27.254 -    xc_gnttab_munmap(mount->gnth, mount->ring.sring, 1);
  27.255 +    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify);
  27.256 +    FS_DEBUG("Pushed responces and notify=%d\n", notify);
  27.257 +    if(notify)
  27.258 +        xc_evtchn_notify(mount->evth, mount->local_evtchn);
  27.259 +}
  27.260 +
  27.261 +static void terminate_mount_request(struct fs_mount *mount) {
  27.262 +    int count = 0, i;
  27.263 +
  27.264 +    FS_DEBUG("terminate_mount_request %s\n", mount->frontend);
  27.265 +    xenbus_write_backend_state(mount, STATE_CLOSING);
  27.266 +
  27.267 +    for(i=0; i<mount->nr_entries; i++)
  27.268 +        if(mount->requests[i].active) {
  27.269 +            mount->requests[i].active = -1;
  27.270 +            aio_cancel(mount->requests[i].aiocb.aio_fildes, &mount->requests[i].aiocb);
  27.271 +            count--;
  27.272 +        }
  27.273 +    mount->nr_entries = count;
  27.274 +
  27.275 +    while (!xenbus_frontend_state_changed(mount, STATE_CLOSING));
  27.276 +    xenbus_write_backend_state(mount, STATE_CLOSED);
  27.277 +
  27.278 +    xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size);
  27.279      xc_gnttab_close(mount->gnth);
  27.280      xc_evtchn_unbind(mount->evth, mount->local_evtchn);
  27.281      xc_evtchn_close(mount->evth);
  27.282 +
  27.283 +    if (!count)
  27.284 +        free_mount_request(mount);
  27.285 +}
  27.286 +
  27.287 +static void free_mount_request(struct fs_mount *mount) {
  27.288 +    FS_DEBUG("free_mount_request %s\n", mount->frontend);
  27.289      free(mount->frontend);
  27.290 -    pthread_exit(NULL);
  27.291 +    free(mount->requests);
  27.292 +    free(mount->freelist);
  27.293 +    LIST_REMOVE (mount, entries);
  27.294 +    free(mount);
  27.295  }
  27.296  
  27.297  static void handle_connection(int frontend_dom_id, int export_id, char *frontend)
  27.298  {
  27.299      struct fs_mount *mount;
  27.300      struct fs_export *export;
  27.301 -    int evt_port;
  27.302 -    pthread_t handling_thread;
  27.303      struct fsif_sring *sring;
  27.304      uint32_t dom_ids[MAX_RING_SIZE];
  27.305      int i;
  27.306  
  27.307 -    printf("Handling connection from dom=%d, for export=%d\n", 
  27.308 +    FS_DEBUG("Handling connection from dom=%d, for export=%d\n", 
  27.309              frontend_dom_id, export_id);
  27.310      /* Try to find the export on the list */
  27.311      export = fs_exports;
  27.312 @@ -214,7 +199,7 @@ static void handle_connection(int fronte
  27.313      }
  27.314      if(!export)
  27.315      {
  27.316 -        printf("Could not find the export (the id is unknown).\n");
  27.317 +        FS_DEBUG("Could not find the export (the id is unknown).\n");
  27.318          return;
  27.319      }
  27.320  
  27.321 @@ -223,7 +208,7 @@ static void handle_connection(int fronte
  27.322      mount->export = export;
  27.323      mount->mount_id = mount_id++;
  27.324      xenbus_read_mount_request(mount, frontend);
  27.325 -    printf("Frontend found at: %s (gref=%d, evtchn=%d)\n", 
  27.326 +    FS_DEBUG("Frontend found at: %s (gref=%d, evtchn=%d)\n", 
  27.327              mount->frontend, mount->grefs[0], mount->remote_evtchn);
  27.328      xenbus_write_backend_node(mount);
  27.329      mount->evth = -1;
  27.330 @@ -249,18 +234,24 @@ static void handle_connection(int fronte
  27.331      mount->nr_entries = mount->ring.nr_ents; 
  27.332      for (i = 0; i < MAX_FDS; i++)
  27.333          mount->fds[i] = -1;
  27.334 -    xenbus_write_backend_ready(mount);
  27.335  
  27.336 -    pthread_create(&handling_thread, NULL, &handle_mount, mount);
  27.337 +    LIST_INSERT_HEAD(&mount_requests_head, mount, entries);
  27.338 +    xenbus_watch_frontend_state(mount);
  27.339 +    xenbus_write_backend_state(mount, STATE_READY);
  27.340 +    
  27.341 +    allocate_request_array(mount);
  27.342  }
  27.343  
  27.344  static void await_connections(void)
  27.345  {
  27.346 -    int fd, ret, dom_id, export_id; 
  27.347 +    int fd, max_fd, ret, dom_id, export_id; 
  27.348      fd_set fds;
  27.349      char **watch_paths;
  27.350      unsigned int len;
  27.351      char d;
  27.352 +    struct fs_mount *pointer;
  27.353 +
  27.354 +    LIST_INIT (&mount_requests_head);
  27.355  
  27.356      assert(xsh != NULL);
  27.357      fd = xenbus_get_watch_fd(); 
  27.358 @@ -268,28 +259,97 @@ static void await_connections(void)
  27.359      do {
  27.360  	FD_ZERO(&fds);
  27.361  	FD_SET(fd, &fds);
  27.362 -        ret = select(fd+1, &fds, NULL, NULL, NULL);
  27.363 -        assert(ret == 1);
  27.364 -        watch_paths = xs_read_watch(xsh, &len);
  27.365 -        assert(len == 2);
  27.366 -        assert(strcmp(watch_paths[1], "conn-watch") == 0);
  27.367 -        dom_id = -1;
  27.368 -        export_id = -1;
  27.369 -	d = 0;
  27.370 -        printf("Path changed %s\n", watch_paths[0]);
  27.371 -        sscanf(watch_paths[0], WATCH_NODE"/%d/%d/fronten%c", 
  27.372 -                &dom_id, &export_id, &d);
  27.373 -        if((dom_id >= 0) && (export_id >= 0) && d == 'd') {
  27.374 -	    char *frontend = xs_read(xsh, XBT_NULL, watch_paths[0], NULL);
  27.375 -	    if (frontend) {
  27.376 -		handle_connection(dom_id, export_id, frontend);
  27.377 -		xs_rm(xsh, XBT_NULL, watch_paths[0]);
  27.378 -	    }
  27.379 -	}
  27.380 -next_select:        
  27.381 -        printf("Awaiting next connection.\n");
  27.382 -        /* TODO - we need to figure out what to free */
  27.383 -	free(watch_paths);
  27.384 +	FD_SET(pipefds[0], &fds);
  27.385 +        max_fd = fd > pipefds[0] ? fd : pipefds[0];
  27.386 +        LIST_FOREACH(pointer, &mount_requests_head, entries) {
  27.387 +            int tfd = xc_evtchn_fd(pointer->evth);
  27.388 +            FD_SET(tfd, &fds);
  27.389 +            if (tfd > max_fd) max_fd = tfd;
  27.390 +        }
  27.391 +        ret = select(max_fd+1, &fds, NULL, NULL, NULL);
  27.392 +        if (ret < 0) {
  27.393 +            if (errno == EINTR) continue;
  27.394 +            /* try to recover */
  27.395 +            else if (errno == EBADF) {
  27.396 +                struct timeval timeout;
  27.397 +                memset(&timeout, 0x00, sizeof(timeout));
  27.398 +                FD_ZERO(&fds);
  27.399 +                FD_SET(fd, &fds);
  27.400 +                FD_SET(pipefds[0], &fds);
  27.401 +                max_fd = fd > pipefds[0] ? fd : pipefds[0];
  27.402 +                ret = select(max_fd + 1, &fds, NULL, NULL, &timeout);
  27.403 +                if (ret < 0)
  27.404 +                    err(1, "select: unrecoverable error occurred: %d\n", errno);
  27.405 +
  27.406 +                /* trying to find the bogus fd among the open event channels */
  27.407 +                LIST_FOREACH(pointer, &mount_requests_head, entries) {
  27.408 +                    int tfd = xc_evtchn_fd(pointer->evth);
  27.409 +                    memset(&timeout, 0x00, sizeof(timeout));
  27.410 +                    FD_ZERO(&fds);
  27.411 +                    FD_SET(tfd, &fds);
  27.412 +                    ret = select(tfd + 1, &fds, NULL, NULL, &timeout);
  27.413 +                    if (ret < 0) {
  27.414 +                        FS_DEBUG("fd %d is bogus, closing the related connection\n", tfd);
  27.415 +                        pointer->evth = fd;
  27.416 +                        terminate_mount_request(pointer);
  27.417 +                        continue;
  27.418 +                    }
  27.419 +                }
  27.420 +                continue;
  27.421 +            } else
  27.422 +                err(1, "select: unrecoverable error occurred: %d\n", errno);
  27.423 +        }
  27.424 +        if (FD_ISSET(fd, &fds)) {
  27.425 +            watch_paths = xs_read_watch(xsh, &len);
  27.426 +            if (!strcmp(watch_paths[XS_WATCH_TOKEN], "conn-watch")) {
  27.427 +                dom_id = -1;
  27.428 +                export_id = -1;
  27.429 +                d = 0;
  27.430 +                FS_DEBUG("Path changed %s\n", watch_paths[0]);
  27.431 +                sscanf(watch_paths[XS_WATCH_PATH], WATCH_NODE"/%d/%d/fronten%c", 
  27.432 +                        &dom_id, &export_id, &d);
  27.433 +                if((dom_id >= 0) && (export_id >= 0) && d == 'd') {
  27.434 +                    char *frontend = xs_read(xsh, XBT_NULL, watch_paths[XS_WATCH_PATH], NULL);
  27.435 +                    if (frontend) {
  27.436 +                        handle_connection(dom_id, export_id, frontend);
  27.437 +                        xs_rm(xsh, XBT_NULL, watch_paths[XS_WATCH_PATH]);
  27.438 +                    }
  27.439 +                }
  27.440 +            } else if (!strcmp(watch_paths[XS_WATCH_TOKEN], "frontend-state")) {
  27.441 +                LIST_FOREACH(pointer, &mount_requests_head, entries) {
  27.442 +                    if (!strncmp(pointer->frontend, watch_paths[XS_WATCH_PATH], strlen(pointer->frontend))) {
  27.443 +                        char *state = xenbus_read_frontend_state(pointer);
  27.444 +                        if (!state || strcmp(state, STATE_READY)) {
  27.445 +                            xenbus_unwatch_frontend_state(pointer);
  27.446 +                            terminate_mount_request(pointer);
  27.447 +                        }
  27.448 +                        free(state);
  27.449 +                        break;
  27.450 +                    }
  27.451 +                }
  27.452 +            } else {
  27.453 +                FS_DEBUG("xenstore watch event unrecognized\n");
  27.454 +            }
  27.455 +            FS_DEBUG("Awaiting next connection.\n");
  27.456 +            /* TODO - we need to figure out what to free */
  27.457 +            free(watch_paths);
  27.458 +        }
  27.459 +        if (FD_ISSET(pipefds[0], &fds)) {
  27.460 +            struct fs_request *request;
  27.461 +            if (read_exact(pipefds[0], &request, sizeof(struct fs_request *)) < 0)
  27.462 +                err(1, "read request failed\n");
  27.463 +            handle_aio_event(request); 
  27.464 +        }
  27.465 +        LIST_FOREACH(pointer, &mount_requests_head, entries) {
  27.466 +            if (FD_ISSET(xc_evtchn_fd(pointer->evth), &fds)) {
  27.467 +                evtchn_port_t port;
  27.468 +                port = xc_evtchn_pending(pointer->evth);
  27.469 +                if (port != -1) {
  27.470 +                    handle_mount(pointer);
  27.471 +                    xc_evtchn_unmask(pointer->evth, port);
  27.472 +                }
  27.473 +            }
  27.474 +        }
  27.475      } while (1);
  27.476  }
  27.477  
  27.478 @@ -312,10 +372,29 @@ static struct fs_export* create_export(c
  27.479      return curr_export;
  27.480  }
  27.481  
  27.482 +static void aio_signal_handler(int signo, siginfo_t *info, void *context)
  27.483 +{
  27.484 +    struct fs_request *request = (struct fs_request*) info->si_value.sival_ptr;
  27.485 +    int saved_errno = errno;
  27.486 +    if (write_exact(pipefds[1], &request, sizeof(struct fs_request *)) < 0)
  27.487 +        err(1, "write request filed\n");
  27.488 +    errno = saved_errno;
  27.489 +}
  27.490  
  27.491  int main(void)
  27.492  {
  27.493      struct fs_export *export;
  27.494 +    struct sigaction act;
  27.495 +    sigset_t enable;
  27.496 +
  27.497 +    sigemptyset(&enable);
  27.498 +    sigaddset(&enable, SIGUSR2);
  27.499 +    pthread_sigmask(SIG_UNBLOCK, &enable, NULL);
  27.500 +
  27.501 +    sigfillset(&act.sa_mask);
  27.502 +    act.sa_flags = SA_SIGINFO; /* do not restart syscalls to interrupt select(); use sa_sigaction */
  27.503 +    act.sa_sigaction = aio_signal_handler;
  27.504 +    sigaction(SIGUSR2, &act, NULL);
  27.505  
  27.506      /* Open the connection to XenStore first */
  27.507      xsh = xs_domain_open();
  27.508 @@ -328,6 +407,9 @@ int main(void)
  27.509      export = create_export("default", "/exports");
  27.510      xenbus_register_export(export);
  27.511  
  27.512 +    if (socketpair(PF_UNIX,SOCK_STREAM, 0, pipefds) == -1)
  27.513 +        err(1, "failed to create pipe\n");
  27.514 +
  27.515      await_connections();
  27.516      /* Close the connection to XenStore when we are finished with everything */
  27.517      xs_daemon_close(xsh);
    28.1 --- a/tools/fs-back/fs-backend.h	Fri Mar 27 10:54:08 2009 +0900
    28.2 +++ b/tools/fs-back/fs-backend.h	Fri Mar 27 11:07:11 2009 +0900
    28.3 @@ -7,6 +7,7 @@
    28.4  #include <xen/event_channel.h>
    28.5  #include <xen/io/ring.h>
    28.6  #include <xen/io/fsif.h>
    28.7 +#include "sys-queue.h"
    28.8  
    28.9  #define ROOT_NODE           "backend/vfs"
   28.10  #define EXPORTS_SUBNODE     "exports"
   28.11 @@ -25,6 +26,8 @@ struct fs_export
   28.12  
   28.13  struct fs_request
   28.14  {
   28.15 +    struct fs_mount *mount;
   28.16 +    int id;
   28.17      int active;
   28.18      void *page;                         /* Pointer to mapped grant */
   28.19      int count;
   28.20 @@ -50,6 +53,7 @@ struct fs_mount
   28.21      struct fs_request *requests;
   28.22      unsigned short *freelist;
   28.23      int fds[MAX_FDS];
   28.24 +    LIST_ENTRY(fs_mount) entries;
   28.25  };
   28.26  
   28.27  
   28.28 @@ -61,7 +65,11 @@ int xenbus_register_export(struct fs_exp
   28.29  int xenbus_get_watch_fd(void);
   28.30  void xenbus_read_mount_request(struct fs_mount *mount, char *frontend);
   28.31  void xenbus_write_backend_node(struct fs_mount *mount);
   28.32 -void xenbus_write_backend_ready(struct fs_mount *mount);
   28.33 +void xenbus_write_backend_state(struct fs_mount *mount, const char *state);
   28.34 +int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate);
   28.35 +void xenbus_watch_frontend_state(struct fs_mount *mount);
   28.36 +void xenbus_unwatch_frontend_state(struct fs_mount *mount);
   28.37 +char* xenbus_read_frontend_state(struct fs_mount *mount);
   28.38  
   28.39  /* File operations, implemented in fs-ops.c */
   28.40  struct fs_op
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/tools/fs-back/fs-debug.h	Fri Mar 27 11:07:11 2009 +0900
    29.3 @@ -0,0 +1,12 @@
    29.4 +#ifndef __FS_DEBUG__
    29.5 +#define __FS_DEBUG__
    29.6 +
    29.7 +// #define DEBUG 1
    29.8 +
    29.9 +#ifdef DEBUG
   29.10 +#define FS_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
   29.11 +#else
   29.12 +#define FS_DEBUG(fmt, ...) do { } while (0)
   29.13 +#endif
   29.14 +
   29.15 +#endif /*__FS_DEBUG__*/
    30.1 --- a/tools/fs-back/fs-ops.c	Fri Mar 27 10:54:08 2009 +0900
    30.2 +++ b/tools/fs-back/fs-ops.c	Fri Mar 27 11:07:11 2009 +0900
    30.3 @@ -14,6 +14,7 @@
    30.4  #include <sys/mount.h>
    30.5  #include <unistd.h>
    30.6  #include "fs-backend.h"
    30.7 +#include "fs-debug.h"
    30.8  
    30.9  /* For debugging only */
   30.10  #include <sys/time.h>
   30.11 @@ -22,12 +23,11 @@
   30.12  
   30.13  #define BUFFER_SIZE 1024
   30.14  
   30.15 -
   30.16  static unsigned short get_request(struct fs_mount *mount, struct fsif_request *req)
   30.17  {
   30.18      unsigned short id = get_id_from_freelist(mount->freelist); 
   30.19  
   30.20 -    printf("Private Request id: %d\n", id);
   30.21 +    FS_DEBUG("Private Request id: %d\n", id);
   30.22      memcpy(&mount->requests[id].req_shadow, req, sizeof(struct fsif_request));
   30.23      mount->requests[id].active = 1;
   30.24  
   30.25 @@ -49,12 +49,11 @@ static void dispatch_file_open(struct fs
   30.26  {
   30.27      char *file_name, full_path[BUFFER_SIZE];
   30.28      int fd;
   30.29 -    struct timeval tv1, tv2;
   30.30      RING_IDX rsp_idx;
   30.31      fsif_response_t *rsp;
   30.32      uint16_t req_id;
   30.33  
   30.34 -    printf("Dispatching file open operation (gref=%d).\n", req->u.fopen.gref);
   30.35 +    FS_DEBUG("Dispatching file open operation (gref=%d).\n", req->u.fopen.gref);
   30.36      /* Read the request, and open file */
   30.37      file_name = xc_gnttab_map_grant_ref(mount->gnth,
   30.38                                          mount->dom_id,
   30.39 @@ -62,13 +61,13 @@ static void dispatch_file_open(struct fs
   30.40                                          PROT_READ);
   30.41     
   30.42      req_id = req->id;
   30.43 -    printf("File open issued for %s\n", file_name); 
   30.44 +    FS_DEBUG("File open issued for %s\n", file_name); 
   30.45      assert(BUFFER_SIZE > 
   30.46             strlen(file_name) + strlen(mount->export->export_path) + 1); 
   30.47      snprintf(full_path, sizeof(full_path), "%s/%s",
   30.48             mount->export->export_path, file_name);
   30.49      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
   30.50 -    printf("Issuing open for %s\n", full_path);
   30.51 +    FS_DEBUG("Issuing open for %s\n", full_path);
   30.52      fd = get_fd(mount);
   30.53      if (fd >= 0) {
   30.54          int real_fd = open(full_path, O_RDWR);
   30.55 @@ -77,7 +76,7 @@ static void dispatch_file_open(struct fs
   30.56          else
   30.57          {
   30.58              mount->fds[fd] = real_fd;
   30.59 -            printf("Got FD: %d for real %d\n", fd, real_fd);
   30.60 +            FS_DEBUG("Got FD: %d for real %d\n", fd, real_fd);
   30.61          }
   30.62      }
   30.63      /* We can advance the request consumer index, from here on, the request
   30.64 @@ -87,7 +86,7 @@ static void dispatch_file_open(struct fs
   30.65  
   30.66      /* Get a response from the ring */
   30.67      rsp_idx = mount->ring.rsp_prod_pvt++;
   30.68 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
   30.69 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
   30.70      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
   30.71      rsp->id = req_id; 
   30.72      rsp->ret_val = (uint64_t)fd;
   30.73 @@ -100,7 +99,7 @@ static void dispatch_file_close(struct f
   30.74      fsif_response_t *rsp;
   30.75      uint16_t req_id;
   30.76  
   30.77 -    printf("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd);
   30.78 +    FS_DEBUG("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd);
   30.79     
   30.80      req_id = req->id;
   30.81      if (req->u.fclose.fd < MAX_FDS) {
   30.82 @@ -109,7 +108,7 @@ static void dispatch_file_close(struct f
   30.83          mount->fds[req->u.fclose.fd] = -1;
   30.84      } else
   30.85          ret = -1;
   30.86 -    printf("Got ret: %d\n", ret);
   30.87 +    FS_DEBUG("Got ret: %d\n", ret);
   30.88      /* We can advance the request consumer index, from here on, the request
   30.89       * should not be used (it may be overrinden by a response) */
   30.90      mount->ring.req_cons++;
   30.91 @@ -117,7 +116,7 @@ static void dispatch_file_close(struct f
   30.92  
   30.93      /* Get a response from the ring */
   30.94      rsp_idx = mount->ring.rsp_prod_pvt++;
   30.95 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
   30.96 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
   30.97      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
   30.98      rsp->id = req_id; 
   30.99      rsp->ret_val = (uint64_t)ret;
  30.100 @@ -127,7 +126,7 @@ static void dispatch_file_close(struct f
  30.101  static void dispatch_file_read(struct fs_mount *mount, struct fsif_request *req)
  30.102  {
  30.103      void *buf;
  30.104 -    int fd, i, count;
  30.105 +    int fd, count;
  30.106      uint16_t req_id;
  30.107      unsigned short priv_id;
  30.108      struct fs_request *priv_req;
  30.109 @@ -143,7 +142,7 @@ static void dispatch_file_read(struct fs
  30.110                                            PROT_WRITE);
  30.111     
  30.112      req_id = req->id;
  30.113 -    printf("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
  30.114 +    FS_DEBUG("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
  30.115              req->u.fread.fd, req->u.fread.len, req->u.fread.offset); 
  30.116  
  30.117      if (req->u.fread.fd < MAX_FDS)
  30.118 @@ -152,10 +151,11 @@ static void dispatch_file_read(struct fs
  30.119          fd = -1;
  30.120  
  30.121      priv_id = get_request(mount, req);
  30.122 -    printf("Private id is: %d\n", priv_id);
  30.123 +    FS_DEBUG("Private id is: %d\n", priv_id);
  30.124      priv_req = &mount->requests[priv_id];
  30.125      priv_req->page = buf;
  30.126      priv_req->count = count;
  30.127 +    priv_req->id = priv_id;
  30.128  
  30.129      /* Dispatch AIO read request */
  30.130      bzero(&priv_req->aiocb, sizeof(struct aiocb));
  30.131 @@ -163,9 +163,11 @@ static void dispatch_file_read(struct fs
  30.132      priv_req->aiocb.aio_nbytes = req->u.fread.len;
  30.133      priv_req->aiocb.aio_offset = req->u.fread.offset;
  30.134      priv_req->aiocb.aio_buf = buf;
  30.135 +    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
  30.136 +    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
  30.137 +    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
  30.138      assert(aio_read(&priv_req->aiocb) >= 0);
  30.139  
  30.140 -out: 
  30.141      /* We can advance the request consumer index, from here on, the request
  30.142       * should not be used (it may be overrinden by a response) */
  30.143      mount->ring.req_cons++;
  30.144 @@ -185,7 +187,7 @@ static void end_file_read(struct fs_moun
  30.145      /* Get a response from the ring */
  30.146      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.147      req_id = priv_req->req_shadow.id; 
  30.148 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.149 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.150      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.151      rsp->id = req_id; 
  30.152      rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb);
  30.153 @@ -194,7 +196,7 @@ static void end_file_read(struct fs_moun
  30.154  static void dispatch_file_write(struct fs_mount *mount, struct fsif_request *req)
  30.155  {
  30.156      void *buf;
  30.157 -    int fd, count, i;
  30.158 +    int fd, count;
  30.159      uint16_t req_id;
  30.160      unsigned short priv_id;
  30.161      struct fs_request *priv_req;
  30.162 @@ -210,7 +212,7 @@ static void dispatch_file_write(struct f
  30.163                                            PROT_READ);
  30.164     
  30.165      req_id = req->id;
  30.166 -    printf("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
  30.167 +    FS_DEBUG("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
  30.168              req->u.fwrite.fd, req->u.fwrite.len, req->u.fwrite.offset); 
  30.169     
  30.170      if (req->u.fwrite.fd < MAX_FDS)
  30.171 @@ -219,10 +221,11 @@ static void dispatch_file_write(struct f
  30.172          fd = -1;
  30.173  
  30.174      priv_id = get_request(mount, req);
  30.175 -    printf("Private id is: %d\n", priv_id);
  30.176 +    FS_DEBUG("Private id is: %d\n", priv_id);
  30.177      priv_req = &mount->requests[priv_id];
  30.178      priv_req->page = buf;
  30.179      priv_req->count = count;
  30.180 +    priv_req->id = priv_id;
  30.181  
  30.182      /* Dispatch AIO write request */
  30.183      bzero(&priv_req->aiocb, sizeof(struct aiocb));
  30.184 @@ -230,6 +233,9 @@ static void dispatch_file_write(struct f
  30.185      priv_req->aiocb.aio_nbytes = req->u.fwrite.len;
  30.186      priv_req->aiocb.aio_offset = req->u.fwrite.offset;
  30.187      priv_req->aiocb.aio_buf = buf;
  30.188 +    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
  30.189 +    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
  30.190 +    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
  30.191      assert(aio_write(&priv_req->aiocb) >= 0);
  30.192  
  30.193       
  30.194 @@ -252,7 +258,7 @@ static void end_file_write(struct fs_mou
  30.195      /* Get a response from the ring */
  30.196      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.197      req_id = priv_req->req_shadow.id; 
  30.198 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.199 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.200      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.201      rsp->id = req_id; 
  30.202      rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb);
  30.203 @@ -260,7 +266,6 @@ static void end_file_write(struct fs_mou
  30.204  
  30.205  static void dispatch_stat(struct fs_mount *mount, struct fsif_request *req)
  30.206  {
  30.207 -    struct fsif_stat_response *buf;
  30.208      struct stat stat;
  30.209      int fd, ret;
  30.210      uint16_t req_id;
  30.211 @@ -273,7 +278,7 @@ static void dispatch_stat(struct fs_moun
  30.212      else
  30.213          fd = -1;
  30.214  
  30.215 -    printf("File stat issued for FD=%d\n", req->u.fstat.fd); 
  30.216 +    FS_DEBUG("File stat issued for FD=%d\n", req->u.fstat.fd); 
  30.217     
  30.218      /* We can advance the request consumer index, from here on, the request
  30.219       * should not be used (it may be overrinden by a response) */
  30.220 @@ -281,12 +286,12 @@ static void dispatch_stat(struct fs_moun
  30.221     
  30.222      /* Stat, and create the response */ 
  30.223      ret = fstat(fd, &stat);
  30.224 -    printf("Mode=%o, uid=%d, a_time=%ld\n",
  30.225 +    FS_DEBUG("Mode=%o, uid=%d, a_time=%ld\n",
  30.226              stat.st_mode, stat.st_uid, (long)stat.st_atime);
  30.227      
  30.228      /* Get a response from the ring */
  30.229      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.230 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.231 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.232      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.233      rsp->id = req_id; 
  30.234      rsp->fstat.stat_ret = (uint32_t)ret;
  30.235 @@ -320,7 +325,7 @@ static void dispatch_truncate(struct fs_
  30.236  
  30.237      req_id = req->id;
  30.238      length = req->u.ftruncate.length;
  30.239 -    printf("File truncate issued for FD=%d, length=%"PRId64"\n", req->u.ftruncate.fd, length); 
  30.240 +    FS_DEBUG("File truncate issued for FD=%d, length=%"PRId64"\n", req->u.ftruncate.fd, length); 
  30.241     
  30.242      if (req->u.ftruncate.fd < MAX_FDS)
  30.243          fd = mount->fds[req->u.ftruncate.fd];
  30.244 @@ -336,7 +341,7 @@ static void dispatch_truncate(struct fs_
  30.245  
  30.246      /* Get a response from the ring */
  30.247      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.248 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.249 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.250      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.251      rsp->id = req_id; 
  30.252      rsp->ret_val = (uint64_t)ret;
  30.253 @@ -350,7 +355,7 @@ static void dispatch_remove(struct fs_mo
  30.254      fsif_response_t *rsp;
  30.255      uint16_t req_id;
  30.256  
  30.257 -    printf("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref);
  30.258 +    FS_DEBUG("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref);
  30.259      /* Read the request, and open file */
  30.260      file_name = xc_gnttab_map_grant_ref(mount->gnth,
  30.261                                          mount->dom_id,
  30.262 @@ -358,15 +363,15 @@ static void dispatch_remove(struct fs_mo
  30.263                                          PROT_READ);
  30.264     
  30.265      req_id = req->id;
  30.266 -    printf("File remove issued for %s\n", file_name); 
  30.267 +    FS_DEBUG("File remove issued for %s\n", file_name); 
  30.268      assert(BUFFER_SIZE > 
  30.269             strlen(file_name) + strlen(mount->export->export_path) + 1); 
  30.270      snprintf(full_path, sizeof(full_path), "%s/%s",
  30.271             mount->export->export_path, file_name);
  30.272      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
  30.273 -    printf("Issuing remove for %s\n", full_path);
  30.274 +    FS_DEBUG("Issuing remove for %s\n", full_path);
  30.275      ret = remove(full_path);
  30.276 -    printf("Got ret: %d\n", ret);
  30.277 +    FS_DEBUG("Got ret: %d\n", ret);
  30.278      /* We can advance the request consumer index, from here on, the request
  30.279       * should not be used (it may be overrinden by a response) */
  30.280      mount->ring.req_cons++;
  30.281 @@ -374,7 +379,7 @@ static void dispatch_remove(struct fs_mo
  30.282  
  30.283      /* Get a response from the ring */
  30.284      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.285 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.286 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.287      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.288      rsp->id = req_id; 
  30.289      rsp->ret_val = (uint64_t)ret;
  30.290 @@ -390,7 +395,7 @@ static void dispatch_rename(struct fs_mo
  30.291      fsif_response_t *rsp;
  30.292      uint16_t req_id;
  30.293  
  30.294 -    printf("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref);
  30.295 +    FS_DEBUG("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref);
  30.296      /* Read the request, and open file */
  30.297      buf = xc_gnttab_map_grant_ref(mount->gnth,
  30.298                                    mount->dom_id,
  30.299 @@ -400,7 +405,7 @@ static void dispatch_rename(struct fs_mo
  30.300      req_id = req->id;
  30.301      old_file_name = buf + req->u.frename.old_name_offset;
  30.302      new_file_name = buf + req->u.frename.new_name_offset;
  30.303 -    printf("File rename issued for %s -> %s (buf=%s)\n", 
  30.304 +    FS_DEBUG("File rename issued for %s -> %s (buf=%s)\n", 
  30.305              old_file_name, new_file_name, buf); 
  30.306      assert(BUFFER_SIZE > 
  30.307             strlen(old_file_name) + strlen(mount->export->export_path) + 1); 
  30.308 @@ -411,9 +416,9 @@ static void dispatch_rename(struct fs_mo
  30.309      snprintf(new_full_path, sizeof(new_full_path), "%s/%s",
  30.310             mount->export->export_path, new_file_name);
  30.311      assert(xc_gnttab_munmap(mount->gnth, buf, 1) == 0);
  30.312 -    printf("Issuing rename for %s -> %s\n", old_full_path, new_full_path);
  30.313 +    FS_DEBUG("Issuing rename for %s -> %s\n", old_full_path, new_full_path);
  30.314      ret = rename(old_full_path, new_full_path);
  30.315 -    printf("Got ret: %d\n", ret);
  30.316 +    FS_DEBUG("Got ret: %d\n", ret);
  30.317      /* We can advance the request consumer index, from here on, the request
  30.318       * should not be used (it may be overrinden by a response) */
  30.319      mount->ring.req_cons++;
  30.320 @@ -421,7 +426,7 @@ static void dispatch_rename(struct fs_mo
  30.321  
  30.322      /* Get a response from the ring */
  30.323      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.324 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.325 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.326      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.327      rsp->id = req_id; 
  30.328      rsp->ret_val = (uint64_t)ret;
  30.329 @@ -438,7 +443,7 @@ static void dispatch_create(struct fs_mo
  30.330      fsif_response_t *rsp;
  30.331      uint16_t req_id;
  30.332  
  30.333 -    printf("Dispatching file create operation (gref=%d).\n", req->u.fcreate.gref);
  30.334 +    FS_DEBUG("Dispatching file create operation (gref=%d).\n", req->u.fcreate.gref);
  30.335      /* Read the request, and create file/directory */
  30.336      mode = req->u.fcreate.mode;
  30.337      directory = req->u.fcreate.directory;
  30.338 @@ -448,7 +453,7 @@ static void dispatch_create(struct fs_mo
  30.339                                          PROT_READ);
  30.340     
  30.341      req_id = req->id;
  30.342 -    printf("File create issued for %s\n", file_name); 
  30.343 +    FS_DEBUG("File create issued for %s\n", file_name); 
  30.344      assert(BUFFER_SIZE > 
  30.345             strlen(file_name) + strlen(mount->export->export_path) + 1); 
  30.346      snprintf(full_path, sizeof(full_path), "%s/%s",
  30.347 @@ -460,12 +465,12 @@ static void dispatch_create(struct fs_mo
  30.348  
  30.349      if(directory)
  30.350      {
  30.351 -        printf("Issuing create for directory: %s\n", full_path);
  30.352 +        FS_DEBUG("Issuing create for directory: %s\n", full_path);
  30.353          ret = mkdir(full_path, mode);
  30.354      }
  30.355      else
  30.356      {
  30.357 -        printf("Issuing create for file: %s\n", full_path);
  30.358 +        FS_DEBUG("Issuing create for file: %s\n", full_path);
  30.359          ret = get_fd(mount);
  30.360          if (ret >= 0) {
  30.361              int real_fd = creat(full_path, mode); 
  30.362 @@ -474,15 +479,15 @@ static void dispatch_create(struct fs_mo
  30.363              else
  30.364              {
  30.365                  mount->fds[ret] = real_fd;
  30.366 -                printf("Got FD: %d for real %d\n", ret, real_fd);
  30.367 +                FS_DEBUG("Got FD: %d for real %d\n", ret, real_fd);
  30.368              }
  30.369          }
  30.370      }
  30.371 -    printf("Got ret %d (errno=%d)\n", ret, errno);
  30.372 +    FS_DEBUG("Got ret %d (errno=%d)\n", ret, errno);
  30.373  
  30.374      /* Get a response from the ring */
  30.375      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.376 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.377 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.378      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.379      rsp->id = req_id; 
  30.380      rsp->ret_val = (uint64_t)ret;
  30.381 @@ -499,7 +504,7 @@ static void dispatch_list(struct fs_moun
  30.382      DIR *dir;
  30.383      struct dirent *dirent = NULL;
  30.384  
  30.385 -    printf("Dispatching list operation (gref=%d).\n", req->u.flist.gref);
  30.386 +    FS_DEBUG("Dispatching list operation (gref=%d).\n", req->u.flist.gref);
  30.387      /* Read the request, and list directory */
  30.388      offset = req->u.flist.offset;
  30.389      buf = file_name = xc_gnttab_map_grant_ref(mount->gnth,
  30.390 @@ -508,7 +513,7 @@ static void dispatch_list(struct fs_moun
  30.391                                          PROT_READ | PROT_WRITE);
  30.392     
  30.393      req_id = req->id;
  30.394 -    printf("Dir list issued for %s\n", file_name); 
  30.395 +    FS_DEBUG("Dir list issued for %s\n", file_name); 
  30.396      assert(BUFFER_SIZE > 
  30.397             strlen(file_name) + strlen(mount->export->export_path) + 1); 
  30.398      snprintf(full_path, sizeof(full_path), "%s/%s",
  30.399 @@ -552,7 +557,7 @@ error_out:
  30.400      
  30.401      /* Get a response from the ring */
  30.402      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.403 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.404 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.405      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.406      rsp->id = req_id; 
  30.407      rsp->ret_val = ret_val;
  30.408 @@ -566,7 +571,7 @@ static void dispatch_chmod(struct fs_mou
  30.409      uint16_t req_id;
  30.410      int32_t mode;
  30.411  
  30.412 -    printf("Dispatching file chmod operation (fd=%d, mode=%o).\n", 
  30.413 +    FS_DEBUG("Dispatching file chmod operation (fd=%d, mode=%o).\n", 
  30.414              req->u.fchmod.fd, req->u.fchmod.mode);
  30.415      req_id = req->id;
  30.416      if (req->u.fchmod.fd < MAX_FDS)
  30.417 @@ -583,7 +588,7 @@ static void dispatch_chmod(struct fs_mou
  30.418  
  30.419      /* Get a response from the ring */
  30.420      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.421 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.422 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.423      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.424      rsp->id = req_id; 
  30.425      rsp->ret_val = (uint64_t)ret;
  30.426 @@ -598,7 +603,7 @@ static void dispatch_fs_space(struct fs_
  30.427      struct statvfs stat;
  30.428      int64_t ret;
  30.429  
  30.430 -    printf("Dispatching fs space operation (gref=%d).\n", req->u.fspace.gref);
  30.431 +    FS_DEBUG("Dispatching fs space operation (gref=%d).\n", req->u.fspace.gref);
  30.432      /* Read the request, and open file */
  30.433      file_name = xc_gnttab_map_grant_ref(mount->gnth,
  30.434                                          mount->dom_id,
  30.435 @@ -606,13 +611,13 @@ static void dispatch_fs_space(struct fs_
  30.436                                          PROT_READ);
  30.437     
  30.438      req_id = req->id;
  30.439 -    printf("Fs space issued for %s\n", file_name); 
  30.440 +    FS_DEBUG("Fs space issued for %s\n", file_name); 
  30.441      assert(BUFFER_SIZE > 
  30.442             strlen(file_name) + strlen(mount->export->export_path) + 1); 
  30.443      snprintf(full_path, sizeof(full_path), "%s/%s",
  30.444             mount->export->export_path, file_name);
  30.445      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
  30.446 -    printf("Issuing fs space for %s\n", full_path);
  30.447 +    FS_DEBUG("Issuing fs space for %s\n", full_path);
  30.448      ret = statvfs(full_path, &stat);
  30.449      if(ret >= 0)
  30.450          ret = stat.f_bsize * stat.f_bfree;
  30.451 @@ -624,7 +629,7 @@ static void dispatch_fs_space(struct fs_
  30.452  
  30.453      /* Get a response from the ring */
  30.454      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.455 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.456 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.457      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.458      rsp->id = req_id; 
  30.459      rsp->ret_val = (uint64_t)ret;
  30.460 @@ -643,15 +648,19 @@ static void dispatch_file_sync(struct fs
  30.461      else
  30.462          fd = -1;
  30.463  
  30.464 -    printf("File sync issued for FD=%d\n", req->u.fsync.fd); 
  30.465 +    FS_DEBUG("File sync issued for FD=%d\n", req->u.fsync.fd); 
  30.466     
  30.467      priv_id = get_request(mount, req);
  30.468 -    printf("Private id is: %d\n", priv_id);
  30.469 +    FS_DEBUG("Private id is: %d\n", priv_id);
  30.470      priv_req = &mount->requests[priv_id];
  30.471 +    priv_req->id = priv_id;
  30.472  
  30.473      /* Dispatch AIO read request */
  30.474      bzero(&priv_req->aiocb, sizeof(struct aiocb));
  30.475      priv_req->aiocb.aio_fildes = fd;
  30.476 +    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
  30.477 +    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
  30.478 +    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
  30.479      assert(aio_fsync(O_SYNC, &priv_req->aiocb) >= 0);
  30.480  
  30.481       
  30.482 @@ -669,7 +678,7 @@ static void end_file_sync(struct fs_moun
  30.483      /* Get a response from the ring */
  30.484      rsp_idx = mount->ring.rsp_prod_pvt++;
  30.485      req_id = priv_req->req_shadow.id; 
  30.486 -    printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.487 +    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
  30.488      rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
  30.489      rsp->id = req_id; 
  30.490      rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb);
    31.1 --- a/tools/fs-back/fs-xenbus.c	Fri Mar 27 10:54:08 2009 +0900
    31.2 +++ b/tools/fs-back/fs-xenbus.c	Fri Mar 27 11:07:11 2009 +0900
    31.3 @@ -4,10 +4,12 @@
    31.4  #include <stdarg.h>
    31.5  #include <string.h>
    31.6  #include <assert.h>
    31.7 +#include <sys/select.h>
    31.8  #include <xenctrl.h>
    31.9  #include <xs.h>
   31.10  #include <xen/io/fsif.h>
   31.11  #include "fs-backend.h"
   31.12 +#include "fs-debug.h"
   31.13  
   31.14  
   31.15  static bool xenbus_printf(struct xs_handle *xsh,
   31.16 @@ -25,7 +27,7 @@ static bool xenbus_printf(struct xs_hand
   31.17      snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path);
   31.18      vsnprintf(val, sizeof(val), fmt, args);
   31.19      va_end(args);
   31.20 -    printf("xenbus_printf (%s) <= %s.\n", fullpath, val);    
   31.21 +    FS_DEBUG("xenbus_printf (%s) <= %s.\n", fullpath, val);    
   31.22  
   31.23      return xs_write(xsh, xbt, fullpath, val, strlen(val));
   31.24  }
   31.25 @@ -57,19 +59,19 @@ int xenbus_register_export(struct fs_exp
   31.26      assert(xsh != NULL);
   31.27      if(xsh == NULL)
   31.28      {
   31.29 -        printf("Could not open connection to xenbus deamon.\n");
   31.30 +        FS_DEBUG("Could not open connection to xenbus deamon.\n");
   31.31          goto error_exit;
   31.32      }
   31.33 -    printf("Connection to the xenbus deamon opened successfully.\n");
   31.34 +    FS_DEBUG("Connection to the xenbus deamon opened successfully.\n");
   31.35  
   31.36      /* Start transaction */
   31.37      xst = xs_transaction_start(xsh);
   31.38      if(xst == 0)
   31.39      {
   31.40 -        printf("Could not start a transaction.\n");
   31.41 +        FS_DEBUG("Could not start a transaction.\n");
   31.42          goto error_exit;
   31.43      }
   31.44 -    printf("XS transaction is %d\n", xst); 
   31.45 +    FS_DEBUG("XS transaction is %d\n", xst); 
   31.46   
   31.47      /* Create node string */
   31.48      snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 
   31.49 @@ -78,7 +80,7 @@ int xenbus_register_export(struct fs_exp
   31.50  
   31.51      if(!xenbus_printf(xsh, xst, node, "name", "%s", export->name))
   31.52      {
   31.53 -        printf("Could not write the export node.\n");
   31.54 +        FS_DEBUG("Could not write the export node.\n");
   31.55          goto error_exit;
   31.56      }
   31.57  
   31.58 @@ -87,7 +89,7 @@ int xenbus_register_export(struct fs_exp
   31.59      perms.perms = XS_PERM_READ;
   31.60      if(!xs_set_permissions(xsh, xst, EXPORTS_NODE, &perms, 1))
   31.61      {
   31.62 -        printf("Could not set permissions on the export node.\n");
   31.63 +        FS_DEBUG("Could not set permissions on the export node.\n");
   31.64          goto error_exit;
   31.65      }
   31.66  
   31.67 @@ -166,7 +168,7 @@ void xenbus_write_backend_node(struct fs
   31.68  
   31.69      assert(xsh != NULL);
   31.70      self_id = get_self_id();
   31.71 -    printf("Our own dom_id=%d\n", self_id);
   31.72 +    FS_DEBUG("Our own dom_id=%d\n", self_id);
   31.73      snprintf(node, sizeof(node), "%s/backend", mount->frontend);
   31.74      snprintf(backend_node, sizeof(backend_node), "/local/domain/%d/"ROOT_NODE"/%d",
   31.75                                  self_id, mount->mount_id);
   31.76 @@ -176,7 +178,7 @@ void xenbus_write_backend_node(struct fs
   31.77      xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, strlen(STATE_INITIALISED));
   31.78  }
   31.79  
   31.80 -void xenbus_write_backend_ready(struct fs_mount *mount)
   31.81 +void xenbus_write_backend_state(struct fs_mount *mount, const char *state)
   31.82  {
   31.83      char node[1024];
   31.84      int self_id;
   31.85 @@ -184,6 +186,59 @@ void xenbus_write_backend_ready(struct f
   31.86      assert(xsh != NULL);
   31.87      self_id = get_self_id();
   31.88      snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
   31.89 -    xs_write(xsh, XBT_NULL, node, STATE_READY, strlen(STATE_READY));
   31.90 +    xs_write(xsh, XBT_NULL, node, state, strlen(state));
   31.91  }
   31.92  
   31.93 +void xenbus_watch_frontend_state(struct fs_mount *mount)
   31.94 +{
   31.95 +    int res;
   31.96 +    char statepath[1024];
   31.97 +
   31.98 +    assert(xsh != NULL);
   31.99 +    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
  31.100 +    res = xs_watch(xsh, statepath, "frontend-state");
  31.101 +    assert(res);
  31.102 +}
  31.103 +
  31.104 +void xenbus_unwatch_frontend_state(struct fs_mount *mount)
  31.105 +{
  31.106 +    int res;
  31.107 +    char statepath[1024];
  31.108 +
  31.109 +    assert(xsh != NULL);
  31.110 +    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
  31.111 +    res = xs_unwatch(xsh, statepath, "frontend-state");
  31.112 +    assert(res);
  31.113 +}
  31.114 +
  31.115 +int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate)
  31.116 +{
  31.117 +    unsigned int len;
  31.118 +    char statepath[1024];
  31.119 +    char *state = NULL;
  31.120 +
  31.121 +    assert(xsh != NULL);
  31.122 +    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
  31.123 +    state = xs_read(xsh, XBT_NULL, statepath, &len);
  31.124 +    if (state && len > 0) {
  31.125 +        if (strcmp(state, oldstate)) {
  31.126 +            free(state);
  31.127 +            return 1;
  31.128 +        } else {
  31.129 +            free(state);
  31.130 +            return 0;
  31.131 +        }
  31.132 +    } else
  31.133 +        return 1;
  31.134 +}
  31.135 +
  31.136 +char* xenbus_read_frontend_state(struct fs_mount *mount)
  31.137 +{
  31.138 +    unsigned int len;
  31.139 +    char statepath[1024];
  31.140 +
  31.141 +    assert(xsh != NULL);
  31.142 +    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
  31.143 +    return xs_read(xsh, XBT_NULL, statepath, &len);
  31.144 +}
  31.145 +
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/tools/fs-back/sys-queue.h	Fri Mar 27 11:07:11 2009 +0900
    32.3 @@ -0,0 +1,338 @@
    32.4 +/*      $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */
    32.5 +
    32.6 +/*
    32.7 + * Qemu version: Copy from netbsd, removed debug code, removed some of
    32.8 + * the implementations.  Left in lists, tail queues and circular queues.
    32.9 + */
   32.10 +
   32.11 +/*
   32.12 + * Copyright (c) 1991, 1993
   32.13 + *      The Regents of the University of California.  All rights reserved.
   32.14 + *
   32.15 + * Redistribution and use in source and binary forms, with or without
   32.16 + * modification, are permitted provided that the following conditions
   32.17 + * are met:
   32.18 + * 1. Redistributions of source code must retain the above copyright
   32.19 + *    notice, this list of conditions and the following disclaimer.
   32.20 + * 2. Redistributions in binary form must reproduce the above copyright
   32.21 + *    notice, this list of conditions and the following disclaimer in the
   32.22 + *    documentation and/or other materials provided with the distribution.
   32.23 + * 3. Neither the name of the University nor the names of its contributors
   32.24 + *    may be used to endorse or promote products derived from this software
   32.25 + *    without specific prior written permission.
   32.26 + *
   32.27 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   32.28 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   32.29 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32.30 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   32.31 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   32.32 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32.33 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32.34 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32.35 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32.36 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32.37 + * SUCH DAMAGE.
   32.38 + *
   32.39 + *      @(#)queue.h     8.5 (Berkeley) 8/20/94
   32.40 + */
   32.41 +
   32.42 +#ifndef _SYS_QUEUE_H_
   32.43 +#define _SYS_QUEUE_H_
   32.44 +
   32.45 +/*
   32.46 + * This file defines three types of data structures:
   32.47 + * lists, tail queues, and circular queues.
   32.48 + *
   32.49 + * A list is headed by a single forward pointer (or an array of forward
   32.50 + * pointers for a hash table header). The elements are doubly linked
   32.51 + * so that an arbitrary element can be removed without a need to
   32.52 + * traverse the list. New elements can be added to the list before
   32.53 + * or after an existing element or at the head of the list. A list
   32.54 + * may only be traversed in the forward direction.
   32.55 + *
   32.56 + * A tail queue is headed by a pair of pointers, one to the head of the
   32.57 + * list and the other to the tail of the list. The elements are doubly
   32.58 + * linked so that an arbitrary element can be removed without a need to
   32.59 + * traverse the list. New elements can be added to the list before or
   32.60 + * after an existing element, at the head of the list, or at the end of
   32.61 + * the list. A tail queue may be traversed in either direction.
   32.62 + *
   32.63 + * A circle queue is headed by a pair of pointers, one to the head of the
   32.64 + * list and the other to the tail of the list. The elements are doubly
   32.65 + * linked so that an arbitrary element can be removed without a need to
   32.66 + * traverse the list. New elements can be added to the list before or after
   32.67 + * an existing element, at the head of the list, or at the end of the list.
   32.68 + * A circle queue may be traversed in either direction, but has a more
   32.69 + * complex end of list detection.
   32.70 + *
   32.71 + * For details on the use of these macros, see the queue(3) manual page.
   32.72 + */
   32.73 +
   32.74 +/*
   32.75 + * List definitions.
   32.76 + */
   32.77 +#define LIST_HEAD(name, type)                                           \
   32.78 +struct name {                                                           \
   32.79 +        struct type *lh_first;  /* first element */                     \
   32.80 +}
   32.81 +
   32.82 +#define LIST_HEAD_INITIALIZER(head)                                     \
   32.83 +        { NULL }
   32.84 +
   32.85 +#define LIST_ENTRY(type)                                                \
   32.86 +struct {                                                                \
   32.87 +        struct type *le_next;   /* next element */                      \
   32.88 +        struct type **le_prev;  /* address of previous next element */  \
   32.89 +}
   32.90 +
   32.91 +/*
   32.92 + * List functions.
   32.93 + */
   32.94 +#define LIST_INIT(head) do {                                            \
   32.95 +        (head)->lh_first = NULL;                                        \
   32.96 +} while (/*CONSTCOND*/0)
   32.97 +
   32.98 +#define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
   32.99 +        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
  32.100 +                (listelm)->field.le_next->field.le_prev =               \
  32.101 +                    &(elm)->field.le_next;                              \
  32.102 +        (listelm)->field.le_next = (elm);                               \
  32.103 +        (elm)->field.le_prev = &(listelm)->field.le_next;               \
  32.104 +} while (/*CONSTCOND*/0)
  32.105 +
  32.106 +#define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
  32.107 +        (elm)->field.le_prev = (listelm)->field.le_prev;                \
  32.108 +        (elm)->field.le_next = (listelm);                               \
  32.109 +        *(listelm)->field.le_prev = (elm);                              \
  32.110 +        (listelm)->field.le_prev = &(elm)->field.le_next;               \
  32.111 +} while (/*CONSTCOND*/0)
  32.112 +
  32.113 +#define LIST_INSERT_HEAD(head, elm, field) do {                         \
  32.114 +        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
  32.115 +                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
  32.116 +        (head)->lh_first = (elm);                                       \
  32.117 +        (elm)->field.le_prev = &(head)->lh_first;                       \
  32.118 +} while (/*CONSTCOND*/0)
  32.119 +
  32.120 +#define LIST_REMOVE(elm, field) do {                                    \
  32.121 +        if ((elm)->field.le_next != NULL)                               \
  32.122 +                (elm)->field.le_next->field.le_prev =                   \
  32.123 +                    (elm)->field.le_prev;                               \
  32.124 +        *(elm)->field.le_prev = (elm)->field.le_next;                   \
  32.125 +} while (/*CONSTCOND*/0)
  32.126 +
  32.127 +#define LIST_FOREACH(var, head, field)                                  \
  32.128 +        for ((var) = ((head)->lh_first);                                \
  32.129 +                (var);                                                  \
  32.130 +                (var) = ((var)->field.le_next))
  32.131 +
  32.132 +/*
  32.133 + * List access methods.
  32.134 + */
  32.135 +#define LIST_EMPTY(head)                ((head)->lh_first == NULL)
  32.136 +#define LIST_FIRST(head)                ((head)->lh_first)
  32.137 +#define LIST_NEXT(elm, field)           ((elm)->field.le_next)
  32.138 +
  32.139 +
  32.140 +/*
  32.141 + * Tail queue definitions.
  32.142 + */
  32.143 +#define _TAILQ_HEAD(name, type, qual)                                   \
  32.144 +struct name {                                                           \
  32.145 +        qual type *tqh_first;           /* first element */             \
  32.146 +        qual type *qual *tqh_last;      /* addr of last next element */ \
  32.147 +}
  32.148 +#define TAILQ_HEAD(name, type)  _TAILQ_HEAD(name, struct type,)
  32.149 +
  32.150 +#define TAILQ_HEAD_INITIALIZER(head)                                    \
  32.151 +        { NULL, &(head).tqh_first }
  32.152 +
  32.153 +#define _TAILQ_ENTRY(type, qual)                                        \
  32.154 +struct {                                                                \
  32.155 +        qual type *tqe_next;            /* next element */              \
  32.156 +        qual type *qual *tqe_prev;      /* address of previous next element */\
  32.157 +}
  32.158 +#define TAILQ_ENTRY(type)       _TAILQ_ENTRY(struct type,)
  32.159 +
  32.160 +/*
  32.161 + * Tail queue functions.
  32.162 + */
  32.163 +#define TAILQ_INIT(head) do {                                           \
  32.164 +        (head)->tqh_first = NULL;                                       \
  32.165 +        (head)->tqh_last = &(head)->tqh_first;                          \
  32.166 +} while (/*CONSTCOND*/0)
  32.167 +
  32.168 +#define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
  32.169 +        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
  32.170 +                (head)->tqh_first->field.tqe_prev =                     \
  32.171 +                    &(elm)->field.tqe_next;                             \
  32.172 +        else                                                            \
  32.173 +                (head)->tqh_last = &(elm)->field.tqe_next;              \
  32.174 +        (head)->tqh_first = (elm);                                      \
  32.175 +        (elm)->field.tqe_prev = &(head)->tqh_first;                     \
  32.176 +} while (/*CONSTCOND*/0)
  32.177 +
  32.178 +#define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
  32.179 +        (elm)->field.tqe_next = NULL;                                   \
  32.180 +        (elm)->field.tqe_prev = (head)->tqh_last;                       \
  32.181 +        *(head)->tqh_last = (elm);                                      \
  32.182 +        (head)->tqh_last = &(elm)->field.tqe_next;                      \
  32.183 +} while (/*CONSTCOND*/0)
  32.184 +
  32.185 +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
  32.186 +        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
  32.187 +                (elm)->field.tqe_next->field.tqe_prev =                 \
  32.188 +                    &(elm)->field.tqe_next;                             \
  32.189 +        else                                                            \
  32.190 +                (head)->tqh_last = &(elm)->field.tqe_next;              \
  32.191 +        (listelm)->field.tqe_next = (elm);                              \
  32.192 +        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
  32.193 +} while (/*CONSTCOND*/0)
  32.194 +
  32.195 +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
  32.196 +        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
  32.197 +        (elm)->field.tqe_next = (listelm);                              \
  32.198 +        *(listelm)->field.tqe_prev = (elm);                             \
  32.199 +        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
  32.200 +} while (/*CONSTCOND*/0)
  32.201 +
  32.202 +#define TAILQ_REMOVE(head, elm, field) do {                             \
  32.203 +        if (((elm)->field.tqe_next) != NULL)                            \
  32.204 +                (elm)->field.tqe_next->field.tqe_prev =                 \
  32.205 +                    (elm)->field.tqe_prev;                              \
  32.206 +        else                                                            \
  32.207 +                (head)->tqh_last = (elm)->field.tqe_prev;               \
  32.208 +        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
  32.209 +} while (/*CONSTCOND*/0)
  32.210 +
  32.211 +#define TAILQ_FOREACH(var, head, field)                                 \
  32.212 +        for ((var) = ((head)->tqh_first);                               \
  32.213 +                (var);                                                  \
  32.214 +                (var) = ((var)->field.tqe_next))
  32.215 +
  32.216 +#define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
  32.217 +        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));    \
  32.218 +                (var);                                                  \
  32.219 +                (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
  32.220 +
  32.221 +/*
  32.222 + * Tail queue access methods.
  32.223 + */
  32.224 +#define TAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
  32.225 +#define TAILQ_FIRST(head)               ((head)->tqh_first)
  32.226 +#define TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
  32.227 +
  32.228 +#define TAILQ_LAST(head, headname) \
  32.229 +        (*(((struct headname *)((head)->tqh_last))->tqh_last))
  32.230 +#define TAILQ_PREV(elm, headname, field) \
  32.231 +        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
  32.232 +
  32.233 +
  32.234 +/*
  32.235 + * Circular queue definitions.
  32.236 + */
  32.237 +#define CIRCLEQ_HEAD(name, type)                                        \
  32.238 +struct name {                                                           \
  32.239 +        struct type *cqh_first;         /* first element */             \
  32.240 +        struct type *cqh_last;          /* last element */              \
  32.241 +}
  32.242 +
  32.243 +#define CIRCLEQ_HEAD_INITIALIZER(head)                                  \
  32.244 +        { (void *)&head, (void *)&head }
  32.245 +
  32.246 +#define CIRCLEQ_ENTRY(type)                                             \
  32.247 +struct {                                                                \
  32.248 +        struct type *cqe_next;          /* next element */              \
  32.249 +        struct type *cqe_prev;          /* previous element */          \
  32.250 +}
  32.251 +
  32.252 +/*
  32.253 + * Circular queue functions.
  32.254 + */
  32.255 +#define CIRCLEQ_INIT(head) do {                                         \
  32.256 +        (head)->cqh_first = (void *)(head);                             \
  32.257 +        (head)->cqh_last = (void *)(head);                              \
  32.258 +} while (/*CONSTCOND*/0)
  32.259 +
  32.260 +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {            \
  32.261 +        (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
  32.262 +        (elm)->field.cqe_prev = (listelm);                              \
  32.263 +        if ((listelm)->field.cqe_next == (void *)(head))                \
  32.264 +                (head)->cqh_last = (elm);                               \
  32.265 +        else                                                            \
  32.266 +                (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
  32.267 +        (listelm)->field.cqe_next = (elm);                              \
  32.268 +} while (/*CONSTCOND*/0)
  32.269 +
  32.270 +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {           \
  32.271 +        (elm)->field.cqe_next = (listelm);                              \
  32.272 +        (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
  32.273 +        if ((listelm)->field.cqe_prev == (void *)(head))                \
  32.274 +                (head)->cqh_first = (elm);                              \
  32.275 +        else                                                            \
  32.276 +                (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
  32.277 +        (listelm)->field.cqe_prev = (elm);                              \
  32.278 +} while (/*CONSTCOND*/0)
  32.279 +
  32.280 +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {                      \
  32.281 +        (elm)->field.cqe_next = (head)->cqh_first;                      \
  32.282 +        (elm)->field.cqe_prev = (void *)(head);                         \
  32.283 +        if ((head)->cqh_last == (void *)(head))                         \
  32.284 +                (head)->cqh_last = (elm);                               \
  32.285 +        else                                                            \
  32.286 +                (head)->cqh_first->field.cqe_prev = (elm);              \
  32.287 +        (head)->cqh_first = (elm);                                      \
  32.288 +} while (/*CONSTCOND*/0)
  32.289 +
  32.290 +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {                      \
  32.291 +        (elm)->field.cqe_next = (void *)(head);                         \
  32.292 +        (elm)->field.cqe_prev = (head)->cqh_last;                       \
  32.293 +        if ((head)->cqh_first == (void *)(head))                        \
  32.294 +                (head)->cqh_first = (elm);                              \
  32.295 +        else                                                            \
  32.296 +                (head)->cqh_last->field.cqe_next = (elm);               \
  32.297 +        (head)->cqh_last = (elm);                                       \
  32.298 +} while (/*CONSTCOND*/0)
  32.299 +
  32.300 +#define CIRCLEQ_REMOVE(head, elm, field) do {                           \
  32.301 +        if ((elm)->field.cqe_next == (void *)(head))                    \
  32.302 +                (head)->cqh_last = (elm)->field.cqe_prev;               \
  32.303 +        else                                                            \
  32.304 +                (elm)->field.cqe_next->field.cqe_prev =                 \
  32.305 +                    (elm)->field.cqe_prev;                              \
  32.306 +        if ((elm)->field.cqe_prev == (void *)(head))                    \
  32.307 +                (head)->cqh_first = (elm)->field.cqe_next;              \
  32.308 +        else                                                            \
  32.309 +                (elm)->field.cqe_prev->field.cqe_next =                 \
  32.310 +                    (elm)->field.cqe_next;                              \
  32.311 +} while (/*CONSTCOND*/0)
  32.312 +
  32.313 +#define CIRCLEQ_FOREACH(var, head, field)                               \
  32.314 +        for ((var) = ((head)->cqh_first);                               \
  32.315 +                (var) != (const void *)(head);                          \
  32.316 +                (var) = ((var)->field.cqe_next))
  32.317 +
  32.318 +#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                       \
  32.319 +        for ((var) = ((head)->cqh_last);                                \
  32.320 +                (var) != (const void *)(head);                          \
  32.321 +                (var) = ((var)->field.cqe_prev))
  32.322 +
  32.323 +/*
  32.324 + * Circular queue access methods.
  32.325 + */
  32.326 +#define CIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
  32.327 +#define CIRCLEQ_FIRST(head)             ((head)->cqh_first)
  32.328 +#define CIRCLEQ_LAST(head)              ((head)->cqh_last)
  32.329 +#define CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
  32.330 +#define CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
  32.331 +
  32.332 +#define CIRCLEQ_LOOP_NEXT(head, elm, field)                             \
  32.333 +        (((elm)->field.cqe_next == (void *)(head))                      \
  32.334 +            ? ((head)->cqh_first)                                       \
  32.335 +            : (elm->field.cqe_next))
  32.336 +#define CIRCLEQ_LOOP_PREV(head, elm, field)                             \
  32.337 +        (((elm)->field.cqe_prev == (void *)(head))                      \
  32.338 +            ? ((head)->cqh_last)                                        \
  32.339 +            : (elm->field.cqe_prev))
  32.340 +
  32.341 +#endif  /* !_SYS_QUEUE_H_ */
    33.1 --- a/tools/hotplug/Linux/Makefile	Fri Mar 27 10:54:08 2009 +0900
    33.2 +++ b/tools/hotplug/Linux/Makefile	Fri Mar 27 11:07:11 2009 +0900
    33.3 @@ -16,7 +16,6 @@ XEN_SCRIPTS += network-route vif-route
    33.4  XEN_SCRIPTS += network-nat vif-nat
    33.5  XEN_SCRIPTS += block
    33.6  XEN_SCRIPTS += block-enbd block-nbd
    33.7 -XEN_SCRIPTS += blktap
    33.8  XEN_SCRIPTS += vtpm vtpm-delete
    33.9  XEN_SCRIPTS += xen-hotplug-cleanup
   33.10  XEN_SCRIPTS += external-device-migrate
   33.11 @@ -30,7 +29,7 @@ XEN_HOTPLUG_DIR = /etc/hotplug
   33.12  XEN_HOTPLUG_SCRIPTS = xen-backend.agent
   33.13  
   33.14  UDEV_RULES_DIR = /etc/udev
   33.15 -UDEV_RULES = xen-backend.rules
   33.16 +UDEV_RULES = xen-backend.rules xend.rules
   33.17  
   33.18  DI = $(if $(DISTDIR),$(shell readlink -f $(DISTDIR)),)
   33.19  DE = $(if $(DESTDIR),$(shell readlink -f $(DESTDIR)),)
    34.1 --- a/tools/hotplug/Linux/blktap	Fri Mar 27 10:54:08 2009 +0900
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,93 +0,0 @@
    34.4 -#!/bin/bash
    34.5 -
    34.6 -# Copyright (c) 2005, XenSource Ltd.
    34.7 -
    34.8 -dir=$(dirname "$0")
    34.9 -. "$dir/xen-hotplug-common.sh"
   34.10 -. "$dir/block-common.sh"
   34.11 -
   34.12 -findCommand "$@"
   34.13 -
   34.14 -##
   34.15 -# check_blktap_sharing file mode
   34.16 -#
   34.17 -# Perform the sharing check for the given blktap and mode.
   34.18 -#
   34.19 -check_blktap_sharing()
   34.20 -{
   34.21 -    local file="$1"
   34.22 -    local mode="$2"
   34.23 -
   34.24 -    local base_path="$XENBUS_BASE_PATH/$XENBUS_TYPE"
   34.25 -    for dom in $(xenstore-list "$base_path")
   34.26 -    do
   34.27 -        for dev in $(xenstore-list "$base_path/$dom")
   34.28 -        do
   34.29 -            params=$(xenstore_read "$base_path/$dom/$dev/params" | cut -d: -f2)
   34.30 -            if [ "$file" = "$params" ]
   34.31 -            then
   34.32 -
   34.33 -                if [ "$mode" = 'w' ]
   34.34 -                then
   34.35 -                    if ! same_vm "$dom" 
   34.36 -                    then
   34.37 -                        echo 'guest'
   34.38 -                        return
   34.39 -                    fi
   34.40 -                else 
   34.41 -                    local m=$(xenstore_read "$base_path/$dom/$dev/mode")
   34.42 -                    m=$(canonicalise_mode "$m")
   34.43 -
   34.44 -                    if [ "$m" = 'w' ] 
   34.45 -                    then
   34.46 -                        if ! same_vm "$dom"
   34.47 -                        then
   34.48 -                            echo 'guest'
   34.49 -                            return
   34.50 -                        fi
   34.51 -                    fi
   34.52 -                fi
   34.53 -            fi
   34.54 -        done
   34.55 -    done
   34.56 -
   34.57 -    echo 'ok'
   34.58 -}
   34.59 -
   34.60 -
   34.61 -t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
   34.62 -if [ -n "$t" ]
   34.63 -then
   34.64 -    p=$(xenstore_read "$XENBUS_PATH/params")
   34.65 -    # if we have a ':', chew from head including :
   34.66 -    if echo $p | grep -q \:
   34.67 -    then
   34.68 -        p=${p#*:}
   34.69 -    fi
   34.70 -fi
   34.71 -# some versions of readlink cannot be passed a regular file
   34.72 -if [ -L "$p" ]; then
   34.73 -    file=$(readlink -f "$p") || fatal "$p link does not exist."
   34.74 -else
   34.75 -    file="$p"
   34.76 -fi
   34.77 -
   34.78 -if [ "$command" = 'add' ]
   34.79 -then
   34.80 -    [ -e "$file" ] || { fatal $file does not exist; }
   34.81 -
   34.82 -    FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
   34.83 -    FRONTEND_UUID=$(xenstore_read "/local/domain/$FRONTEND_ID/vm")
   34.84 -    mode=$(xenstore_read "$XENBUS_PATH/mode")
   34.85 -    mode=$(canonicalise_mode "$mode")
   34.86 -
   34.87 -    if [ "$mode" != '!' ] 
   34.88 -    then
   34.89 -        result=$(check_blktap_sharing "$file" "$mode")
   34.90 -        [ "$result" = 'ok' ] || ebusy "$file already in use by other domain"
   34.91 -    fi
   34.92 -
   34.93 -    success
   34.94 -fi
   34.95 -
   34.96 -exit 0
    35.1 --- a/tools/hotplug/Linux/xen-backend.rules	Fri Mar 27 10:54:08 2009 +0900
    35.2 +++ b/tools/hotplug/Linux/xen-backend.rules	Fri Mar 27 11:07:11 2009 +0900
    35.3 @@ -1,4 +1,3 @@
    35.4 -SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}"
    35.5  SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}"
    35.6  SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}"
    35.7  SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"
    36.1 --- a/tools/hotplug/Linux/xen-hotplug-cleanup	Fri Mar 27 10:54:08 2009 +0900
    36.2 +++ b/tools/hotplug/Linux/xen-hotplug-cleanup	Fri Mar 27 11:07:11 2009 +0900
    36.3 @@ -14,9 +14,13 @@ claim_lock "block"
    36.4  # split backend/DEVCLASS/VMID/DEVID on slashes
    36.5  path_array=( ${XENBUS_PATH//\// } )
    36.6  # get /vm/UUID path
    36.7 -vm=$(xenstore-read "/local/domain/${path_array[2]}/vm")
    36.8 +vm=$(xenstore_read_default "/local/domain/${path_array[2]}/vm" "")
    36.9  # construct /vm/UUID/device/DEVCLASS/DEVID
   36.10 -vm_dev="$vm/device/${path_array[1]}/${path_array[3]}"
   36.11 +if [ "$vm" != "" ]; then
   36.12 +  vm_dev="$vm/device/${path_array[1]}/${path_array[3]}"
   36.13 +else
   36.14 +  vm_dev=
   36.15 +fi
   36.16  
   36.17  # remove device frontend store entries
   36.18  xenstore-rm -t \
   36.19 @@ -27,6 +31,6 @@ xenstore-rm -t "$XENBUS_PATH"        2>/
   36.20  xenstore-rm -t "error/$XENBUS_PATH"  2>/dev/null || true
   36.21  
   36.22  # remove device path from /vm/UUID
   36.23 -xenstore-rm -t "$vm_dev" 2>/dev/null || true
   36.24 +[ "$vm_dev" != "" ] && xenstore-rm -t "$vm_dev" 2>/dev/null || true
   36.25  
   36.26  release_lock "block"
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/tools/hotplug/Linux/xend.rules	Fri Mar 27 11:07:11 2009 +0900
    37.3 @@ -0,0 +1,3 @@
    37.4 +SUBSYSTEM=="pci", RUN+="socket:/org/xen/xend/udev_event"
    37.5 +#SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event"
    37.6 +#SUBSYSTEM=="net", KERNEL!="vif[0-9]*.[0-9]*|tap[0-9]*.[0-9]*", RUN+="socket:/org/xen/xend/udev_event"
    38.1 --- a/tools/hotplug/NetBSD/Makefile	Fri Mar 27 10:54:08 2009 +0900
    38.2 +++ b/tools/hotplug/NetBSD/Makefile	Fri Mar 27 11:07:11 2009 +0900
    38.3 @@ -2,14 +2,12 @@ XEN_ROOT = ../../../
    38.4  include $(XEN_ROOT)/tools/Rules.mk
    38.5  
    38.6  # Xen configuration dir and configs to go there.
    38.7 -XEN_CONFIG_DIR = $(PREFIX)/etc/xen
    38.8 +XEN_CONFIG_DIR = /etc/xen
    38.9  
   38.10  # Xen script dir and scripts to go there.
   38.11 -XEN_SCRIPT_DIR = $(PREFIX)/etc/xen/scripts
   38.12 +XEN_SCRIPT_DIR = $(XEN_CONFIG_DIR)/scripts
   38.13  XEN_SCRIPTS =
   38.14  XEN_SCRIPTS += block-nbsd
   38.15 -XEN_SCRIPTS += hvm-nbsd
   38.16 -XEN_SCRIPTS += netbsd1-nbsd
   38.17  XEN_SCRIPTS += qemu-ifup-nbsd
   38.18  XEN_SCRIPTS += vif-bridge-nbsd
   38.19  XEN_SCRIPTS += vif-ip-nbsd
   38.20 @@ -27,7 +25,7 @@ install: all install-scripts
   38.21  
   38.22  .PHONY: install-scripts
   38.23  install-scripts:
   38.24 -	$(INSTALL_DATA_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
   38.25 +	$(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
   38.26  	set -e; for i in $(XEN_SCRIPTS); \
   38.27  	   do \
   38.28  	   $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
    39.1 --- a/tools/libfsimage/zfs/fsys_zfs.c	Fri Mar 27 10:54:08 2009 +0900
    39.2 +++ b/tools/libfsimage/zfs/fsys_zfs.c	Fri Mar 27 11:07:11 2009 +0900
    39.3 @@ -298,8 +298,7 @@ uberblock_verify(uberblock_phys_t *ub, i
    39.4  		return (-1);
    39.5  
    39.6  	if (uber->ub_magic == UBERBLOCK_MAGIC &&
    39.7 -	    uber->ub_version >= SPA_VERSION_1 &&
    39.8 -	    uber->ub_version <= SPA_VERSION)
    39.9 +	    uber->ub_version > 0 && uber->ub_version <= SPA_VERSION)
   39.10  		return (0);
   39.11  
   39.12  	return (-1);
    40.1 --- a/tools/libfsimage/zfs/zfs-include/zfs.h	Fri Mar 27 10:54:08 2009 +0900
    40.2 +++ b/tools/libfsimage/zfs/zfs-include/zfs.h	Fri Mar 27 11:07:11 2009 +0900
    40.3 @@ -28,17 +28,7 @@
    40.4  /*
    40.5   * On-disk version number.
    40.6   */
    40.7 -#define	SPA_VERSION_1			1ULL
    40.8 -#define	SPA_VERSION_2			2ULL
    40.9 -#define	SPA_VERSION_3			3ULL
   40.10 -#define	SPA_VERSION_4			4ULL
   40.11 -#define	SPA_VERSION_5			5ULL
   40.12 -#define	SPA_VERSION_6			6ULL
   40.13 -#define	SPA_VERSION_7			7ULL
   40.14 -#define	SPA_VERSION_8			8ULL
   40.15 -#define	SPA_VERSION_9			9ULL
   40.16 -#define	SPA_VERSION_10			10ULL
   40.17 -#define	SPA_VERSION			SPA_VERSION_10
   40.18 +#define	SPA_VERSION			14ULL
   40.19  
   40.20  /*
   40.21   * The following are configuration names used in the nvlist describing a pool's
    41.1 --- a/tools/libxc/Makefile	Fri Mar 27 10:54:08 2009 +0900
    41.2 +++ b/tools/libxc/Makefile	Fri Mar 27 11:07:11 2009 +0900
    41.3 @@ -29,7 +29,7 @@ CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.
    41.4  CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c
    41.5  
    41.6  GUEST_SRCS-y :=
    41.7 -GUEST_SRCS-y += xg_private.c
    41.8 +GUEST_SRCS-y += xg_private.c xc_suspend.c
    41.9  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c
   41.10  GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
   41.11  
    42.1 --- a/tools/libxc/xc_core.c	Fri Mar 27 10:54:08 2009 +0900
    42.2 +++ b/tools/libxc/xc_core.c	Fri Mar 27 11:07:11 2009 +0900
    42.3 @@ -518,7 +518,17 @@ xc_domain_dumpcore_via_callback(int xc_h
    42.4      if ( sts != 0 )
    42.5          goto out;
    42.6  
    42.7 +    /*
    42.8 +     * Note: this is the *current* number of pages and may change under
    42.9 +     * a live dump-core.  We'll just take this value, and if more pages
   42.10 +     * exist, we'll skip them.  If there's less, then we'll just not use
   42.11 +     * all the array...
   42.12 +     *
   42.13 +     * We don't want to use the total potential size of the memory map
   42.14 +     * since that is usually much higher than info.nr_pages.
   42.15 +     */
   42.16      nr_pages = info.nr_pages;
   42.17 +
   42.18      if ( !auto_translated_physmap )
   42.19      {
   42.20          /* obtain p2m table */
    43.1 --- a/tools/libxc/xc_dom_x86.c	Fri Mar 27 10:54:08 2009 +0900
    43.2 +++ b/tools/libxc/xc_dom_x86.c	Fri Mar 27 11:07:11 2009 +0900
    43.3 @@ -694,7 +694,7 @@ static int x86_shadow(int xc, domid_t do
    43.4  int arch_setup_meminit(struct xc_dom_image *dom)
    43.5  {
    43.6      int rc;
    43.7 -    xen_pfn_t pfn;
    43.8 +    xen_pfn_t pfn, allocsz, i;
    43.9  
   43.10      rc = x86_compat(dom->guest_xc, dom->guest_domid, dom->guest_type);
   43.11      if ( rc )
   43.12 @@ -713,9 +713,15 @@ int arch_setup_meminit(struct xc_dom_ima
   43.13          dom->p2m_host[pfn] = pfn;
   43.14  
   43.15      /* allocate guest memory */
   43.16 -    rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
   43.17 -                                           dom->total_pages, 0, 0,
   43.18 -                                           dom->p2m_host);
   43.19 +    for ( i = rc = allocsz = 0; (i < dom->total_pages) && !rc; i += allocsz )
   43.20 +    {
   43.21 +        allocsz = dom->total_pages - i;
   43.22 +        if ( allocsz > 1024*1024 )
   43.23 +            allocsz = 1024*1024;
   43.24 +        rc = xc_domain_memory_populate_physmap(
   43.25 +            dom->guest_xc, dom->guest_domid, allocsz, 0, 0, &dom->p2m_host[i]);
   43.26 +    }
   43.27 +
   43.28      return rc;
   43.29  }
   43.30  
    44.1 --- a/tools/libxc/xc_domain_save.c	Fri Mar 27 10:54:08 2009 +0900
    44.2 +++ b/tools/libxc/xc_domain_save.c	Fri Mar 27 11:07:11 2009 +0900
    44.3 @@ -744,8 +744,6 @@ static xen_pfn_t *map_and_save_p2m_table
    44.4      return success ? p2m : NULL;
    44.5  }
    44.6  
    44.7 -
    44.8 -
    44.9  int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
   44.10                     uint32_t max_factor, uint32_t flags, int (*suspend)(void),
   44.11                     int hvm, void *(*init_qemu_maps)(int, unsigned), 
    45.1 --- a/tools/libxc/xc_pm.c	Fri Mar 27 10:54:08 2009 +0900
    45.2 +++ b/tools/libxc/xc_pm.c	Fri Mar 27 11:07:11 2009 +0900
    45.3 @@ -306,3 +306,59 @@ int xc_set_cpufreq_para(int xc_handle, i
    45.4  
    45.5      return xc_sysctl(xc_handle, &sysctl);
    45.6  }
    45.7 +
    45.8 +int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int *avg_freq)
    45.9 +{
   45.10 +    int ret = 0;
   45.11 +    DECLARE_SYSCTL;
   45.12 +
   45.13 +    if ( (xc_handle < 0) || (!avg_freq) )
   45.14 +        return -EINVAL;
   45.15 +
   45.16 +    sysctl.cmd = XEN_SYSCTL_pm_op;
   45.17 +    sysctl.u.pm_op.cmd = GET_CPUFREQ_AVGFREQ;
   45.18 +    sysctl.u.pm_op.cpuid = cpuid;
   45.19 +    ret = xc_sysctl(xc_handle, &sysctl);
   45.20 +
   45.21 +    *avg_freq = sysctl.u.pm_op.get_avgfreq;
   45.22 +
   45.23 +    return ret;
   45.24 +}
   45.25 +
   45.26 +int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info)
   45.27 +{
   45.28 +    int rc;
   45.29 +    DECLARE_SYSCTL;
   45.30 +
   45.31 +    sysctl.cmd = XEN_SYSCTL_pm_op;
   45.32 +    sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_cputopo;
   45.33 +    sysctl.u.pm_op.cpuid = 0;
   45.34 +    set_xen_guest_handle( sysctl.u.pm_op.get_topo.cpu_to_core,
   45.35 +                         info->cpu_to_core );
   45.36 +    set_xen_guest_handle( sysctl.u.pm_op.get_topo.cpu_to_socket,
   45.37 +                         info->cpu_to_socket );
   45.38 +    sysctl.u.pm_op.get_topo.max_cpus = info->max_cpus;
   45.39 +
   45.40 +    rc = do_sysctl(xc_handle, &sysctl);
   45.41 +    info->nr_cpus = sysctl.u.pm_op.get_topo.nr_cpus;
   45.42 +
   45.43 +    return rc;
   45.44 +}
   45.45 +
   45.46 +/* value:   0 - disable sched_smt_power_savings 
   45.47 +            1 - enable sched_smt_power_savings
   45.48 + */
   45.49 +int xc_set_sched_opt_smt(int xc_handle, uint32_t value)
   45.50 +{
   45.51 +   int rc;
   45.52 +   DECLARE_SYSCTL;
   45.53 +
   45.54 +   sysctl.cmd = XEN_SYSCTL_pm_op;
   45.55 +   sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_set_sched_opt_smt;
   45.56 +   sysctl.u.pm_op.cpuid = 0;
   45.57 +   sysctl.u.pm_op.set_sched_opt_smt = value;
   45.58 +   rc = do_sysctl(xc_handle, &sysctl);
   45.59 +
   45.60 +   return rc;
   45.61 +}
   45.62 +
    46.1 --- a/tools/libxc/xc_ptrace_core.c	Fri Mar 27 10:54:08 2009 +0900
    46.2 +++ b/tools/libxc/xc_ptrace_core.c	Fri Mar 27 11:07:11 2009 +0900
    46.3 @@ -154,7 +154,7 @@ xc_waitdomain_core_compat(
    46.4              IPRINTF("Could not allocate m2p array\n");
    46.5              return -1;
    46.6          }
    46.7 -        bzero(m2p_array_compat, sizeof(unsigned long)* 1 << 20);
    46.8 +        memset(m2p_array_compat, 0, sizeof(unsigned long)* 1 << 20);
    46.9  
   46.10          for (i = 0; i < nr_pages_compat; i++)
   46.11              m2p_array_compat[p2m_array_compat[i]] = i;
    47.1 --- a/tools/libxc/xc_solaris.c	Fri Mar 27 10:54:08 2009 +0900
    47.2 +++ b/tools/libxc/xc_solaris.c	Fri Mar 27 11:07:11 2009 +0900
    47.3 @@ -134,6 +134,8 @@ void *xc_map_foreign_ranges(int xc_handl
    47.4      if (rc)
    47.5          goto ioctl_failed;
    47.6  
    47.7 +    return addr;
    47.8 +
    47.9  ioctl_failed:
   47.10      rc = munmap(addr, size);
   47.11      if (rc == -1)
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/tools/libxc/xc_suspend.c	Fri Mar 27 11:07:11 2009 +0900
    48.3 @@ -0,0 +1,117 @@
    48.4 +/*
    48.5 + * This file is subject to the terms and conditions of the GNU General
    48.6 + * Public License.  See the file "COPYING" in the main directory of
    48.7 + * this archive for more details.
    48.8 + */
    48.9 +
   48.10 +#include "xc_private.h"
   48.11 +#include "xenguest.h"
   48.12 +
   48.13 +#define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn_lock.d"
   48.14 +static int lock_suspend_event(void)
   48.15 +{
   48.16 +    int fd, rc;
   48.17 +    mode_t mask;
   48.18 +    char buf[128];
   48.19 +
   48.20 +    mask = umask(022);
   48.21 +    fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0666);
   48.22 +    if (fd < 0)
   48.23 +    {
   48.24 +        ERROR("Can't create lock file for suspend event channel\n");
   48.25 +        return -EINVAL;
   48.26 +    }
   48.27 +    umask(mask);
   48.28 +    snprintf(buf, sizeof(buf), "%10ld", (long)getpid());
   48.29 +
   48.30 +    rc = write_exact(fd, buf, strlen(buf));
   48.31 +    close(fd);
   48.32 +
   48.33 +    return rc;
   48.34 +}
   48.35 +
   48.36 +static int unlock_suspend_event(void)
   48.37 +{
   48.38 +    int fd, pid, n;
   48.39 +    char buf[128];
   48.40 +
   48.41 +    fd = open(SUSPEND_LOCK_FILE, O_RDWR);
   48.42 +
   48.43 +    if (fd < 0)
   48.44 +        return -EINVAL;
   48.45 +
   48.46 +    n = read(fd, buf, 127);
   48.47 +
   48.48 +    close(fd);
   48.49 +
   48.50 +    if (n > 0)
   48.51 +    {
   48.52 +        sscanf(buf, "%d", &pid);
   48.53 +        /* We are the owner, so we can simply delete the file */
   48.54 +        if (pid == getpid())
   48.55 +        {
   48.56 +            unlink(SUSPEND_LOCK_FILE);
   48.57 +            return 0;
   48.58 +        }
   48.59 +    }
   48.60 +
   48.61 +    return -EPERM;
   48.62 +}
   48.63 +
   48.64 +int xc_await_suspend(int xce, int suspend_evtchn)
   48.65 +{
   48.66 +    int rc;
   48.67 +
   48.68 +    do {
   48.69 +        rc = xc_evtchn_pending(xce);
   48.70 +        if (rc < 0) {
   48.71 +            ERROR("error polling suspend notification channel: %d", rc);
   48.72 +            return -1;
   48.73 +        }
   48.74 +    } while (rc != suspend_evtchn);
   48.75 +
   48.76 +    /* harmless for one-off suspend */
   48.77 +    if (xc_evtchn_unmask(xce, suspend_evtchn) < 0)
   48.78 +        ERROR("failed to unmask suspend notification channel: %d", rc);
   48.79 +
   48.80 +    return 0;
   48.81 +}
   48.82 +
   48.83 +int xc_suspend_evtchn_release(int xce, int suspend_evtchn)
   48.84 +{
   48.85 +    if (suspend_evtchn >= 0)
   48.86 +        xc_evtchn_unbind(xce, suspend_evtchn);
   48.87 +
   48.88 +    return unlock_suspend_event();
   48.89 +}
   48.90 +
   48.91 +int xc_suspend_evtchn_init(int xc, int xce, int domid, int port)
   48.92 +{
   48.93 +    int rc, suspend_evtchn = -1;
   48.94 +
   48.95 +    if (lock_suspend_event())
   48.96 +        return -EINVAL;
   48.97 +
   48.98 +    suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port);
   48.99 +    if (suspend_evtchn < 0) {
  48.100 +        ERROR("failed to bind suspend event channel: %d", suspend_evtchn);
  48.101 +        goto cleanup;
  48.102 +    }
  48.103 +
  48.104 +    rc = xc_domain_subscribe_for_suspend(xc, domid, port);
  48.105 +    if (rc < 0) {
  48.106 +        ERROR("failed to subscribe to domain: %d", rc);
  48.107 +        goto cleanup;
  48.108 +    }
  48.109 +
  48.110 +    /* event channel is pending immediately after binding */
  48.111 +    xc_await_suspend(xce, suspend_evtchn);
  48.112 +
  48.113 +    return suspend_evtchn;
  48.114 +
  48.115 +cleanup:
  48.116 +    if (suspend_evtchn > 0)
  48.117 +        xc_suspend_evtchn_release(xce, suspend_evtchn);
  48.118 +
  48.119 +    return -1;
  48.120 +}
    49.1 --- a/tools/libxc/xenctrl.h	Fri Mar 27 10:54:08 2009 +0900
    49.2 +++ b/tools/libxc/xenctrl.h	Fri Mar 27 11:07:11 2009 +0900
    49.3 @@ -158,7 +158,7 @@ typedef struct xc_dominfo {
    49.4                    paused:1, blocked:1, running:1,
    49.5                    hvm:1, debugged:1;
    49.6      unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
    49.7 -    unsigned long nr_pages;
    49.8 +    unsigned long nr_pages; /* current number, not maximum */
    49.9      unsigned long shared_info_frame;
   49.10      uint64_t      cpu_time;
   49.11      unsigned long max_memkb;
   49.12 @@ -1242,4 +1242,24 @@ int xc_get_cpufreq_para(int xc_handle, i
   49.13  int xc_set_cpufreq_gov(int xc_handle, int cpuid, char *govname);
   49.14  int xc_set_cpufreq_para(int xc_handle, int cpuid,
   49.15                          int ctrl_type, int ctrl_value);
   49.16 +int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int *avg_freq);
   49.17 +
   49.18 +struct xc_get_cputopo {
   49.19 +     /* IN: maximum addressable entry in
   49.20 +      * the caller-provided cpu_to_core/socket.
   49.21 +      */
   49.22 +    uint32_t max_cpus;
   49.23 +    uint32_t *cpu_to_core;
   49.24 +    uint32_t *cpu_to_socket;
   49.25 +
   49.26 +    /* OUT: number of cpus returned
   49.27 +     * If OUT is greater than IN then the cpu_to_core/socket is truncated!
   49.28 +     */
   49.29 +    uint32_t nr_cpus;
   49.30 +};
   49.31 +
   49.32 +int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info);
   49.33 +
   49.34 +int xc_set_sched_opt_smt(int xc_handle, uint32_t value);
   49.35 +
   49.36  #endif /* XENCTRL_H */
    50.1 --- a/tools/libxc/xenguest.h	Fri Mar 27 10:54:08 2009 +0900
    50.2 +++ b/tools/libxc/xenguest.h	Fri Mar 27 11:07:11 2009 +0900
    50.3 @@ -142,4 +142,10 @@ int xc_hvm_build_mem(int xc_handle,
    50.4                       const char *image_buffer,
    50.5                       unsigned long image_size);
    50.6  
    50.7 +int xc_suspend_evtchn_release(int xce, int suspend_evtchn);
    50.8 +
    50.9 +int xc_suspend_evtchn_init(int xc, int xce, int domid, int port);
   50.10 +
   50.11 +int xc_await_suspend(int xce, int suspend_evtchn);
   50.12 +
   50.13  #endif /* XENGUEST_H */
    51.1 --- a/tools/libxc/xg_private.c	Fri Mar 27 10:54:08 2009 +0900
    51.2 +++ b/tools/libxc/xg_private.c	Fri Mar 27 11:07:11 2009 +0900
    51.3 @@ -108,7 +108,7 @@ char *xc_inflate_buffer(const char *in_b
    51.4                  (256 * ((unsigned char)in_buf[in_size-2] +
    51.5                          (256 * (unsigned char)in_buf[in_size-1])))));
    51.6  
    51.7 -    bzero(&zStream, sizeof(zStream));
    51.8 +    memset(&zStream, 0, sizeof(zStream));
    51.9      out_buf = malloc(out_len + 16);        /* Leave a little extra space */
   51.10      if ( out_buf == NULL )
   51.11      {
    52.1 --- a/tools/misc/xenpm.c	Fri Mar 27 10:54:08 2009 +0900
    52.2 +++ b/tools/misc/xenpm.c	Fri Mar 27 11:07:11 2009 +0900
    52.3 @@ -16,9 +16,6 @@
    52.4   * Place - Suite 330, Boston, MA 02111-1307 USA.
    52.5   */
    52.6  
    52.7 -/* to eliminate warning on `strndup' */
    52.8 -#define _GNU_SOURCE
    52.9 -
   52.10  #include <stdio.h>
   52.11  #include <stdlib.h>
   52.12  #include <unistd.h>
   52.13 @@ -58,8 +55,10 @@ void show_help(void)
   52.14              "                                     it is used in ondemand governor.\n"
   52.15              " set-up-threshold      [cpuid] <num> set up threshold on CPU <cpuid> or all\n"
   52.16              "                                     it is used in ondemand governor.\n"
   52.17 -            " start                               start collect Cx/Px statistics,\n"
   52.18 -            "                                     output after CTRL-C or SIGINT.\n"
   52.19 +            " get-cpu-topology                    get thread/core/socket topology info\n"
   52.20 +            " set-sched-smt           enable|disable enable/disable scheduler smt power saving\n"
   52.21 +            " start [seconds]                     start collect Cx/Px statistics,\n"
   52.22 +            "                                     output after CTRL-C or SIGINT or several seconds.\n"
   52.23              );
   52.24  }
   52.25  /* wrapper function */
   52.26 @@ -224,6 +223,20 @@ static int get_pxstat_by_cpuid(int xc_fd
   52.27      return 0;
   52.28  }
   52.29  
   52.30 +/* show cpu actual average freq information on CPU cpuid */
   52.31 +static int get_avgfreq_by_cpuid(int xc_fd, int cpuid, int *avgfreq)
   52.32 +{
   52.33 +    int ret = 0;
   52.34 +
   52.35 +    ret = xc_get_cpufreq_avgfreq(xc_fd, cpuid, avgfreq);
   52.36 +    if ( ret )
   52.37 +    {
   52.38 +        return errno;
   52.39 +    }
   52.40 +
   52.41 +    return 0;
   52.42 +}
   52.43 +
   52.44  static int show_pxstat_by_cpuid(int xc_fd, int cpuid)
   52.45  {
   52.46      int ret = 0;
   52.47 @@ -265,6 +278,7 @@ void pxstat_func(int argc, char *argv[])
   52.48  static uint64_t usec_start, usec_end;
   52.49  static struct xc_cx_stat *cxstat, *cxstat_start, *cxstat_end;
   52.50  static struct xc_px_stat *pxstat, *pxstat_start, *pxstat_end;
   52.51 +static int *avgfreq;
   52.52  static uint64_t *sum, *sum_cx, *sum_px;
   52.53  
   52.54  static void signal_int_handler(int signo)
   52.55 @@ -300,6 +314,9 @@ static void signal_int_handler(int signo
   52.56                                   pxstat_start[i].pt[j].residency;
   52.57      }
   52.58  
   52.59 +    for ( i = 0; i < max_cpu_nr; i++ )
   52.60 +        get_avgfreq_by_cpuid(xc_fd, i, &avgfreq[i]);
   52.61 +
   52.62      printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL);
   52.63      for ( i = 0; i < max_cpu_nr; i++ )
   52.64      {
   52.65 @@ -331,6 +348,7 @@ static void signal_int_handler(int signo
   52.66                          res / 1000000UL, 100UL * res / (double)sum_px[i]);
   52.67              }
   52.68          }
   52.69 +        printf("  Avg freq\t%d\tKHz\n", avgfreq[i]);
   52.70      }
   52.71  
   52.72      /* some clean up and then exits */
   52.73 @@ -344,6 +362,7 @@ static void signal_int_handler(int signo
   52.74      free(cxstat);
   52.75      free(pxstat);
   52.76      free(sum);
   52.77 +    free(avgfreq);
   52.78      xc_interface_close(xc_fd);
   52.79      exit(0);
   52.80  }
   52.81 @@ -352,6 +371,16 @@ void start_gather_func(int argc, char *a
   52.82  {
   52.83      int i;
   52.84      struct timeval tv;
   52.85 +    int timeout = 0;
   52.86 +
   52.87 +    if ( argc == 1 )
   52.88 +    {
   52.89 +        sscanf(argv[0], "%d", &timeout);
   52.90 +        if ( timeout <= 0 )
   52.91 +            fprintf(stderr, "failed to set timeout seconds, falling back...\n");
   52.92 +        else
   52.93 +            printf("Timeout set to %d seconds\n", timeout);
   52.94 +    }
   52.95  
   52.96      if ( gettimeofday(&tv, NULL) == -1 )
   52.97      {
   52.98 @@ -376,9 +405,18 @@ void start_gather_func(int argc, char *a
   52.99          free(cxstat);
  52.100          return ;
  52.101      }
  52.102 +    avgfreq = malloc(sizeof(int) * max_cpu_nr);
  52.103 +    if ( avgfreq == NULL )
  52.104 +    {
  52.105 +        free(sum);
  52.106 +        free(cxstat);
  52.107 +        free(pxstat);
  52.108 +        return ;
  52.109 +    }
  52.110      memset(sum, 0, sizeof(uint64_t) * 2 * max_cpu_nr);
  52.111      memset(cxstat, 0, sizeof(struct xc_cx_stat) * 2 * max_cpu_nr);
  52.112      memset(pxstat, 0, sizeof(struct xc_px_stat) * 2 * max_cpu_nr);
  52.113 +    memset(avgfreq, 0, sizeof(int) * max_cpu_nr);
  52.114      sum_cx = sum;
  52.115      sum_px = sum + max_cpu_nr;
  52.116      cxstat_start = cxstat;
  52.117 @@ -397,6 +435,7 @@ void start_gather_func(int argc, char *a
  52.118      {
  52.119          get_cxstat_by_cpuid(xc_fd, i, &cxstat_start[i]);
  52.120          get_pxstat_by_cpuid(xc_fd, i, &pxstat_start[i]);
  52.121 +        get_avgfreq_by_cpuid(xc_fd, i, &avgfreq[i]);
  52.122      }
  52.123  
  52.124      if (signal(SIGINT, signal_int_handler) == SIG_ERR)
  52.125 @@ -405,9 +444,25 @@ void start_gather_func(int argc, char *a
  52.126          free(sum);
  52.127          free(pxstat);
  52.128          free(cxstat);
  52.129 +        free(avgfreq);
  52.130          return ;
  52.131      }
  52.132 -    printf("Start sampling, waiting for CTRL-C or SIGINT signal ...\n");
  52.133 +
  52.134 +    if ( timeout > 0 )
  52.135 +    {
  52.136 +        if ( signal(SIGALRM, signal_int_handler) == SIG_ERR )
  52.137 +        {
  52.138 +            fprintf(stderr, "failed to set signal alarm handler\n");
  52.139 +            free(sum);
  52.140 +            free(pxstat);
  52.141 +            free(cxstat);
  52.142 +            free(avgfreq);
  52.143 +            return ;
  52.144 +        }
  52.145 +        alarm(timeout);
  52.146 +    }
  52.147 +
  52.148 +    printf("Start sampling, waiting for CTRL-C or SIGINT or SIGALARM signal ...\n");
  52.149  
  52.150      pause();
  52.151  }
  52.152 @@ -750,6 +805,70 @@ out:
  52.153      fprintf(stderr, "failed to set governor name\n");
  52.154  }
  52.155  
  52.156 +#define MAX_NR_CPU 512
  52.157 +
  52.158 +void cpu_topology_func(int argc, char *argv[])
  52.159 +{
  52.160 +    uint32_t cpu_to_core[MAX_NR_CPU];
  52.161 +    uint32_t cpu_to_socket[MAX_NR_CPU];
  52.162 +    struct xc_get_cputopo info;
  52.163 +    int i, ret;
  52.164 +
  52.165 +    info.cpu_to_core = cpu_to_core;
  52.166 +    info.cpu_to_socket = cpu_to_socket;
  52.167 +    info.max_cpus = MAX_NR_CPU;
  52.168 +    ret = xc_get_cputopo(xc_fd, &info);
  52.169 +    if (!ret)
  52.170 +    {
  52.171 +        printf("CPU\tcore\tsocket\n");
  52.172 +        for (i=0; i<info.nr_cpus; i++)
  52.173 +        {
  52.174 +            if ( info.cpu_to_core[i] != INVALID_TOPOLOGY_ID &&
  52.175 +                    info.cpu_to_socket[i] != INVALID_TOPOLOGY_ID )
  52.176 +            {
  52.177 +            printf("CPU%d\t %d\t %d\n", i, info.cpu_to_core[i],
  52.178 +                    info.cpu_to_socket[i]);
  52.179 +            }
  52.180 +        }
  52.181 +    }
  52.182 +    else
  52.183 +    {
  52.184 +        printf("Can not get Xen CPU topology!\n");
  52.185 +    }
  52.186 +
  52.187 +    return ;
  52.188 +}
  52.189 +
  52.190 +void set_sched_smt_func(int argc, char *argv[])
  52.191 +{
  52.192 +    int value, rc;
  52.193 +
  52.194 +    if (argc != 1){
  52.195 +        show_help();
  52.196 +        exit(-1);
  52.197 +    }
  52.198 +
  52.199 +    if ( !strncmp(argv[0], "disable", sizeof("disable")) )
  52.200 +    {
  52.201 +        value = 0;
  52.202 +    }
  52.203 +    else if ( !strncmp(argv[0], "enable", sizeof("enable")) )
  52.204 +    {
  52.205 +        value = 1;
  52.206 +    }
  52.207 +    else
  52.208 +    {
  52.209 +        show_help();
  52.210 +        exit(-1);
  52.211 +    }
  52.212 +
  52.213 +    rc = xc_set_sched_opt_smt(xc_fd, value);
  52.214 +    printf("%s sched_smt_power_savings %s\n", argv[0],
  52.215 +                    rc? "failed":"successeed" );
  52.216 +
  52.217 +    return;
  52.218 +}
  52.219 +
  52.220  struct {
  52.221      const char *name;
  52.222      void (*function)(int argc, char *argv[]);
  52.223 @@ -765,6 +884,8 @@ struct {
  52.224      { "set-scaling-speed", scaling_speed_func },
  52.225      { "set-sampling-rate", scaling_sampling_rate_func },
  52.226      { "set-up-threshold", scaling_up_threshold_func },
  52.227 +    { "get-cpu-topology", cpu_topology_func},
  52.228 +    { "set-sched-smt", set_sched_smt_func},
  52.229  };
  52.230  
  52.231  int main(int argc, char *argv[])
    53.1 --- a/tools/pygrub/src/pygrub	Fri Mar 27 10:54:08 2009 +0900
    53.2 +++ b/tools/pygrub/src/pygrub	Fri Mar 27 11:07:11 2009 +0900
    53.3 @@ -441,7 +441,11 @@ class Grub:
    53.4                  # Timed out waiting for a keypress
    53.5                  if mytime != -1:
    53.6                      mytime += 1
    53.7 -                    if mytime >= int(timeout):
    53.8 +                    # curses.timeout() does not work properly on Solaris
    53.9 +                    # So we may come here even after a key has been pressed.
   53.10 +                    # Check both timeout and mytime to avoid exiting
   53.11 +                    # when we shouldn't.
   53.12 +                    if timeout != -1 and mytime >= int(timeout):
   53.13                          self.isdone = True
   53.14                          break
   53.15              else:
   53.16 @@ -526,7 +530,11 @@ def run_grub(file, entry, fs, arg):
   53.17          print "No kernel image selected!"
   53.18          sys.exit(1)
   53.19  
   53.20 -    img = g.cf.images[sel]
   53.21 +    try:
   53.22 +        img = g.cf.images[sel]
   53.23 +    except:
   53.24 +        log.debug("PyGrub: Default selection is not valid, using first boot configuration...")
   53.25 +        img = g.cf.images[0]
   53.26  
   53.27      grubcfg = { "kernel": None, "ramdisk": None, "args": None }
   53.28  
   53.29 @@ -579,6 +587,15 @@ def sniff_solaris(fs, cfg):
   53.30  
   53.31      return cfg
   53.32   
   53.33 +def sniff_netware(fs, cfg):
   53.34 +    if not fs.file_exists("/nwserver/xnloader.sys"):
   53.35 +        return cfg
   53.36 +
   53.37 +    if not cfg["kernel"]:
   53.38 +        cfg["kernel"] = "/nwserver/xnloader.sys"
   53.39 +
   53.40 +    return cfg
   53.41 +
   53.42  if __name__ == "__main__":
   53.43      sel = None
   53.44      
   53.45 @@ -659,6 +676,9 @@ if __name__ == "__main__":
   53.46      chosencfg = sniff_solaris(fs, incfg)
   53.47  
   53.48      if not chosencfg["kernel"]:
   53.49 +        chosencfg = sniff_netware(fs, incfg)
   53.50 +
   53.51 +    if not chosencfg["kernel"]:
   53.52          chosencfg = run_grub(file, entry, fs, incfg["args"])
   53.53  
   53.54      data = fs.open_file(chosencfg["kernel"]).read()
    54.1 --- a/tools/python/setup.py	Fri Mar 27 10:54:08 2009 +0900
    54.2 +++ b/tools/python/setup.py	Fri Mar 27 11:07:11 2009 +0900
    54.3 @@ -38,6 +38,13 @@ scf = Extension("scf",
    54.4                 libraries          = libraries,
    54.5                 sources            = [ "xen/lowlevel/scf/scf.c" ])
    54.6               
    54.7 +process = Extension("process",
    54.8 +               extra_compile_args = extra_compile_args,
    54.9 +               include_dirs       = include_dirs + [ "xen/lowlevel/process" ],
   54.10 +               library_dirs       = library_dirs,
   54.11 +               libraries          = libraries + [ "contract" ],
   54.12 +               sources            = [ "xen/lowlevel/process/process.c" ])
   54.13 +
   54.14  acm = Extension("acm",
   54.15                 extra_compile_args = extra_compile_args,
   54.16                 include_dirs       = include_dirs + [ "xen/lowlevel/acm" ],
   54.17 @@ -63,6 +70,7 @@ ptsname = Extension("ptsname",
   54.18  modules = [ xc, xs, ptsname, acm, flask ]
   54.19  if os.uname()[0] == 'SunOS':
   54.20      modules.append(scf)
   54.21 +    modules.append(process)
   54.22  
   54.23  setup(name            = 'xen',
   54.24        version         = '3.0',
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/tools/python/xen/lowlevel/process/process.c	Fri Mar 27 11:07:11 2009 +0900
    55.3 @@ -0,0 +1,164 @@
    55.4 +/*
    55.5 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    55.6 + * of this software and associated documentation files (the "Software"), to
    55.7 + * deal in the Software without restriction, including without limitation the
    55.8 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    55.9 + * sell copies of the Software, and to permit persons to whom the Software is
   55.10 + * furnished to do so, subject to the following conditions:
   55.11 + *
   55.12 + * The above copyright notice and this permission notice shall be included in
   55.13 + * all copies or substantial portions of the Software.
   55.14 + *
   55.15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   55.16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   55.17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   55.18 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   55.19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   55.20 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   55.21 + * DEALINGS IN THE SOFTWARE.
   55.22 + *
   55.23 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   55.24 + * Use is subject to license terms.
   55.25 + */
   55.26 +
   55.27 +#include <Python.h>
   55.28 +
   55.29 +#include <libcontract.h>
   55.30 +#include <sys/contract/process.h>
   55.31 +#include <fcntl.h>
   55.32 +#include <stdio.h>
   55.33 +
   55.34 +/*
   55.35 + * On Solaris, xend runs under a contract as an smf(5) service.  As a
   55.36 + * result, when spawning long-running children such as a domain's
   55.37 + * qemu-dm instantiation, we have to make sure it's in a separate
   55.38 + * contract. Before we fork, we must activate a separate process
   55.39 + * contract template to place the child processes in a new contract.
   55.40 + */
   55.41 +
   55.42 +static PyObject *
   55.43 +pyprocess_activate(PyObject *o, PyObject *args, PyObject *kwargs)
   55.44 +{
   55.45 +	static char *kwlist[] = { "name", NULL };
   55.46 +	char *name = NULL;
   55.47 +	int flags;
   55.48 +	int cfd;
   55.49 +
   55.50 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &name))
   55.51 +		return (NULL);
   55.52 +
   55.53 +	cfd = open64("/system/contract/process/template", O_RDWR);
   55.54 +
   55.55 +	if (cfd == -1)
   55.56 +		goto err;
   55.57 +
   55.58 +	if ((flags = fcntl(cfd, F_GETFD, 0)) == -1)
   55.59 +		goto err;
   55.60 +	
   55.61 +	if (fcntl(cfd, F_SETFD, flags | FD_CLOEXEC) == -1)
   55.62 +		goto err;
   55.63 +
   55.64 +	if (name != NULL)
   55.65 +		ct_pr_tmpl_set_svc_aux(cfd, name);
   55.66 +
   55.67 +	if (ct_tmpl_activate(cfd))
   55.68 +		goto err;
   55.69 +
   55.70 +	return (PyInt_FromLong((long)cfd));
   55.71 +
   55.72 +err:
   55.73 +	if (cfd != -1)
   55.74 +		close(cfd);
   55.75 +	PyErr_SetFromErrno(PyExc_OSError);
   55.76 +	return (NULL);
   55.77 +}
   55.78 +
   55.79 +static PyObject *
   55.80 +pyprocess_clear(PyObject *o, PyObject *args, PyObject *kwargs)
   55.81 +{
   55.82 +	static char *kwlist[] = { "contract", NULL };
   55.83 +	int cfd;
   55.84 +
   55.85 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &cfd))
   55.86 +		return (NULL);
   55.87 +
   55.88 +	if (ct_tmpl_clear(cfd) != 0) {
   55.89 +		PyErr_SetFromErrno(PyExc_OSError);
   55.90 +		return (NULL);
   55.91 +	}
   55.92 +
   55.93 +	close(cfd);
   55.94 +
   55.95 +	Py_INCREF(Py_None);
   55.96 +	return (Py_None);
   55.97 +}
   55.98 +
   55.99 +static PyObject *
  55.100 +pyprocess_abandon_latest(PyObject *o, PyObject *args, PyObject *kwargs)
  55.101 +{
  55.102 +	static char *kwlist[] = { NULL };
  55.103 +	static char path[PATH_MAX];
  55.104 +	ct_stathdl_t st;
  55.105 +	ctid_t latest;
  55.106 +	int cfd;
  55.107 +
  55.108 +	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist))
  55.109 +		return (NULL);
  55.110 +
  55.111 +	cfd = open64("/system/contract/process/latest", O_RDONLY);
  55.112 +	if (cfd == -1)
  55.113 +		goto err;
  55.114 +
  55.115 +	ct_status_read(cfd, CTD_COMMON, &st);
  55.116 +	latest = ct_status_get_id(st);
  55.117 +	ct_status_free(st);
  55.118 +	close(cfd);
  55.119 +
  55.120 +	snprintf(path, PATH_MAX, "/system/contract/process/%ld/ctl",
  55.121 +	    (long)latest);
  55.122 +
  55.123 +	if ((cfd = open64(path, O_WRONLY)) < 0) 
  55.124 +		goto err;
  55.125 +	if (ct_ctl_abandon(cfd))
  55.126 +		goto err;
  55.127 +	close(cfd);
  55.128 +
  55.129 +	Py_INCREF(Py_None);
  55.130 +	return (Py_None);
  55.131 +err:
  55.132 +	PyErr_SetFromErrno(PyExc_OSError);
  55.133 +	return (NULL);
  55.134 +}
  55.135 +
  55.136 +PyDoc_STRVAR(pyprocess_activate__doc__,
  55.137 +    "activate(name)\n"
  55.138 +    "\n"
  55.139 +    "Activate a new process contract template. If name is given,\n"
  55.140 +    "it is used as the template's auxiliary value.\n"
  55.141 +    "Returns the new contract template.\n");
  55.142 + 
  55.143 +PyDoc_STRVAR(pyprocess_clear__doc__,
  55.144 +    "clear(contract)\n"
  55.145 +    "\n"
  55.146 +    "Clear and close the given contract template.\n");
  55.147 +
  55.148 +PyDoc_STRVAR(pyprocess_abandon_latest__doc__,
  55.149 +    "abandon_latest()\n"
  55.150 +    "\n"
  55.151 +    "Abandon the latest contract created by this thread.\n");
  55.152 +
  55.153 +static struct PyMethodDef pyprocess_module_methods[] = {
  55.154 +    { "activate", (PyCFunction) pyprocess_activate,
  55.155 +      METH_VARARGS|METH_KEYWORDS, pyprocess_activate__doc__ },
  55.156 +    { "clear", (PyCFunction) pyprocess_clear,
  55.157 +      METH_VARARGS|METH_KEYWORDS, pyprocess_clear__doc__ },
  55.158 +    { "abandon_latest", (PyCFunction) pyprocess_abandon_latest,
  55.159 +      METH_VARARGS|METH_KEYWORDS, pyprocess_abandon_latest__doc__ },
  55.160 +    { NULL, NULL, 0, NULL }	
  55.161 +};
  55.162 +
  55.163 +PyMODINIT_FUNC
  55.164 +initprocess(void)
  55.165 +{
  55.166 +	Py_InitModule("process", pyprocess_module_methods);
  55.167 +}
    56.1 --- a/tools/python/xen/util/pci.py	Fri Mar 27 10:54:08 2009 +0900
    56.2 +++ b/tools/python/xen/util/pci.py	Fri Mar 27 11:07:11 2009 +0900
    56.3 @@ -12,6 +12,7 @@ import re
    56.4  import types
    56.5  import struct
    56.6  import time
    56.7 +import threading
    56.8  from xen.util import utils
    56.9  
   56.10  PROC_PCI_PATH = '/proc/bus/pci/devices'
   56.11 @@ -97,6 +98,7 @@ MSIX_SIZE_MASK = 0x7ff
   56.12  
   56.13  # Global variable to store information from lspci
   56.14  lspci_info = None
   56.15 +lspci_info_lock = threading.RLock()
   56.16  
   56.17  #Calculate PAGE_SHIFT: number of bits to shift an address to get the page number
   56.18  PAGE_SIZE = resource.getpagesize()
   56.19 @@ -174,12 +176,16 @@ def get_all_pci_devices():
   56.20  
   56.21      return pci_devs
   56.22  
   56.23 -def create_lspci_info():
   56.24 +def _create_lspci_info():
   56.25 +    """Execute 'lspci' command and parse the result.
   56.26 +    If the command does not exist, lspci_info will be kept blank ({}).
   56.27 +
   56.28 +    Expects to be protected by lspci_info_lock.
   56.29 +    """
   56.30      global lspci_info
   56.31 +    
   56.32      lspci_info = {}
   56.33  
   56.34 -    # Execute 'lspci' command and parse the result.
   56.35 -    # If the command does not exist, lspci_info will be kept blank ({}).
   56.36      for paragraph in os.popen(LSPCI_CMD + ' -vmm').read().split('\n\n'):
   56.37          device_name = None
   56.38          device_info = {}
   56.39 @@ -195,6 +201,14 @@ def create_lspci_info():
   56.40          if device_name is not None:
   56.41              lspci_info[device_name] = device_info
   56.42  
   56.43 +def create_lspci_info():
   56.44 +    global lspci_info_lock
   56.45 +    lspci_info_lock.acquire()
   56.46 +    try:
   56.47 +        _create_lspci_info()
   56.48 +    finally:
   56.49 +        lspci_info_lock.release()
   56.50 +
   56.51  def save_pci_conf_space(devs_string):
   56.52      pci_list = []
   56.53      cfg_list = []
   56.54 @@ -911,22 +925,27 @@ class PciDevice:
   56.55          Since we cannot obtain these data from sysfs, use 'lspci' command.
   56.56          """
   56.57          global lspci_info
   56.58 +        global lspci_info_lock
   56.59  
   56.60 -        if lspci_info is None:
   56.61 -            create_lspci_info()
   56.62 -
   56.63 +        lspci_info_lock.acquire()
   56.64          try:
   56.65 -            device_info = lspci_info[self.name]
   56.66 -            self.revision = int(device_info['Rev'], 16)
   56.67 -            self.vendorname = device_info['Vendor']
   56.68 -            self.devicename = device_info['Device']
   56.69 -            self.classname = device_info['Class']
   56.70 -            self.subvendorname = device_info['SVendor']
   56.71 -            self.subdevicename = device_info['SDevice']
   56.72 -        except KeyError:
   56.73 -            pass
   56.74 +            if lspci_info is None:
   56.75 +                _create_lspci_info()
   56.76  
   56.77 -        return True
   56.78 +            try:
   56.79 +                device_info = lspci_info[self.name]
   56.80 +                self.revision = int(device_info['Rev'], 16)
   56.81 +                self.vendorname = device_info['Vendor']
   56.82 +                self.devicename = device_info['Device']
   56.83 +                self.classname = device_info['Class']
   56.84 +                self.subvendorname = device_info['SVendor']
   56.85 +                self.subdevicename = device_info['SDevice']
   56.86 +            except KeyError:
   56.87 +                pass
   56.88 +
   56.89 +            return True
   56.90 +        finally:
   56.91 +            lspci_info_lock.release()
   56.92  
   56.93      def __str__(self):
   56.94          str = "PCI Device %s\n" % (self.name)
    57.1 --- a/tools/python/xen/util/vscsi_util.py	Fri Mar 27 10:54:08 2009 +0900
    57.2 +++ b/tools/python/xen/util/vscsi_util.py	Fri Mar 27 11:07:11 2009 +0900
    57.3 @@ -90,7 +90,7 @@ def _vscsi_get_scsidevices_by_lsscsi(opt
    57.4  
    57.5      devices = []
    57.6  
    57.7 -    for scsiinfo in os.popen('lsscsi -g %s' % option).readlines():
    57.8 +    for scsiinfo in os.popen('{ lsscsi -g %s; } 2>/dev/null' % option).readlines():
    57.9          s = scsiinfo.split()
   57.10          hctl = s[0][1:-1]
   57.11          try:
   57.12 @@ -112,7 +112,10 @@ def _vscsi_get_scsidevices_by_sysfs():
   57.13      """ get all scsi devices information by sysfs """
   57.14  
   57.15      devices = []
   57.16 -    sysfs_mnt = utils.find_sysfs_mount() 
   57.17 +    try:
   57.18 +        sysfs_mnt = utils.find_sysfs_mount() 
   57.19 +    except:
   57.20 +        return devices
   57.21  
   57.22      for dirpath, dirnames, files in os.walk(sysfs_mnt + SYSFS_SCSI_PATH):
   57.23          for hctl in dirnames:
   57.24 @@ -152,7 +155,9 @@ def vscsi_get_hctl_and_devname_by(target
   57.25          elif target.startswith('/dev/'): 
   57.26              scsi_devices = _vscsi_get_scsidevices_by_lsscsi("| grep %s" % target)
   57.27          else:
   57.28 -            scsi_devices = vscsi_get_scsidevices()
   57.29 +            scsi_devices = _vscsi_get_scsidevices_by_lsscsi("")
   57.30 +        if not scsi_devices:
   57.31 +            scsi_devices = _vscsi_get_scsidevices_by_sysfs()
   57.32  
   57.33      if len(target.split(':')) == 4:
   57.34          return _vscsi_get_devname_by(target, scsi_devices)
   57.35 @@ -248,7 +253,7 @@ def get_all_scsi_devices():
   57.36              get_scsi_scsilevel(scsi_dev['physical_HCTL'])
   57.37  
   57.38          try:
   57.39 -            lsscsi_info = os.popen('lsscsi ' + scsi_dev['physical_HCTL']).read().split()
   57.40 +            lsscsi_info = os.popen('lsscsi %s 2>/dev/null' % scsi_dev['physical_HCTL']).read().split()
   57.41              scsi_dev['type'] = lsscsi_info[1]
   57.42          except:
   57.43              scsi_dev['type'] = None
    58.1 --- a/tools/python/xen/web/SrvDir.py	Fri Mar 27 10:54:08 2009 +0900
    58.2 +++ b/tools/python/xen/web/SrvDir.py	Fri Mar 27 11:07:11 2009 +0900
    58.3 @@ -20,7 +20,7 @@ import types
    58.4  from xen.xend import sxp
    58.5  from xen.xend import PrettyPrint
    58.6  from xen.xend.Args import ArgError
    58.7 -from xen.xend.XendError import XendError
    58.8 +from xen.xend.XendError import XendError, XendInvalidDomain
    58.9  #from xen.xend.XendLogging import log
   58.10  
   58.11  import resource
   58.12 @@ -71,6 +71,8 @@ class SrvDir(SrvBase):
   58.13              val = self.get(x)
   58.14          except XendError, ex:
   58.15              return self.noChild(str(ex))
   58.16 +        except XendInvalidDomain, ex:
   58.17 +            return self.noChild(str(ex))
   58.18          if val is None:
   58.19              return self.noChild('Not found: ' + str(x))
   58.20          else:
    59.1 --- a/tools/python/xen/web/connection.py	Fri Mar 27 10:54:08 2009 +0900
    59.2 +++ b/tools/python/xen/web/connection.py	Fri Mar 27 11:07:11 2009 +0900
    59.3 @@ -292,3 +292,40 @@ def hostAllowed(addrport, hosts_allowed)
    59.4                  return True
    59.5          log.warn("Rejected connection from %s (%s).", addrport[0], fqdn)
    59.6          return False
    59.7 +
    59.8 +
    59.9 +class SocketDgramListener:
   59.10 +    """A connectionless server socket, running listen in a thread.
   59.11 +    """
   59.12 +
   59.13 +    def __init__(self, protocol_class):
   59.14 +        self.protocol = protocol_class()
   59.15 +        self.sock = self.createSocket()
   59.16 +        threading.Thread(target=self.main).start()
   59.17 +
   59.18 +
   59.19 +    def close(self):
   59.20 +        try:
   59.21 +            self.sock.close()
   59.22 +        except:
   59.23 +            pass
   59.24 +
   59.25 +
   59.26 +    def createSocket(self):
   59.27 +        raise NotImplementedError()
   59.28 +
   59.29 +
   59.30 +    def main(self):
   59.31 +        try:
   59.32 +            while True:
   59.33 +                try:
   59.34 +                    data = self.sock.recv(BUFFER_SIZE)
   59.35 +                    self.protocol.dataReceived(data)
   59.36 +                except socket.error, ex:
   59.37 +                    if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR):
   59.38 +                        break
   59.39 +        finally:
   59.40 +            try:
   59.41 +                self.close()
   59.42 +            except:
   59.43 +                pass
    60.1 --- a/tools/python/xen/web/unix.py	Fri Mar 27 10:54:08 2009 +0900
    60.2 +++ b/tools/python/xen/web/unix.py	Fri Mar 27 11:07:11 2009 +0900
    60.3 @@ -27,16 +27,19 @@ from xen.util import mkdir
    60.4  import connection
    60.5  
    60.6  
    60.7 -def bind(path):
    60.8 -    """Create a Unix socket, and bind it to the given path.  The socket is
    60.9 -created such that only the current user may access it."""
   60.10 +def bind(path, type = socket.SOCK_STREAM):
   60.11 +    """Create a Unix socket, and bind it to the given path.
   60.12 +    The socket is created such that only the current user may access it."""
   60.13  
   60.14 -    parent = os.path.dirname(path)
   60.15 -    mkdir.parents(parent, stat.S_IRWXU, True)
   60.16 -    if os.path.exists(path):
   60.17 -        os.unlink(path)
   60.18 +    if path[0] == '\0': # Abstract namespace is used for the path
   60.19 +        pass
   60.20 +    else:
   60.21 +        parent = os.path.dirname(path)
   60.22 +        mkdir.parents(parent, stat.S_IRWXU, True)
   60.23 +        if os.path.exists(path):
   60.24 +            os.unlink(path)
   60.25  
   60.26 -    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   60.27 +    sock = socket.socket(socket.AF_UNIX, type)
   60.28      sock.bind(path)
   60.29      return sock
   60.30  
   60.31 @@ -48,8 +51,19 @@ class UnixListener(connection.SocketList
   60.32  
   60.33  
   60.34      def createSocket(self):
   60.35 -        return bind(self.path)
   60.36 +        return bind(self.path, socket.SOCK_STREAM)
   60.37  
   60.38  
   60.39      def acceptConnection(self, sock, _):
   60.40          connection.SocketServerConnection(sock, self.protocol_class)
   60.41 +
   60.42 +
   60.43 +class UnixDgramListener(connection.SocketDgramListener):
   60.44 +    def __init__(self, path, protocol_class):
   60.45 +        self.path = path
   60.46 +        connection.SocketDgramListener.__init__(self, protocol_class)
   60.47 +
   60.48 +
   60.49 +    def createSocket(self):
   60.50 +        return bind(self.path, socket.SOCK_DGRAM)
   60.51 +
    61.1 --- a/tools/python/xen/xend/XendAPIStore.py	Fri Mar 27 10:54:08 2009 +0900
    61.2 +++ b/tools/python/xen/xend/XendAPIStore.py	Fri Mar 27 11:07:11 2009 +0900
    61.3 @@ -25,36 +25,59 @@ You must register both the uuid and type
    61.4  by type, to ensure safety
    61.5  """
    61.6  
    61.7 +import threading
    61.8 +
    61.9  __classes = {}
   61.10 +__classes_lock = threading.RLock()
   61.11  
   61.12  def register(uuid, type, inst):
   61.13 -    __classes[(uuid, type)] = inst
   61.14 -    return inst
   61.15 +    __classes_lock.acquire()
   61.16 +    try:
   61.17 +        __classes[(uuid, type)] = inst
   61.18 +        return inst
   61.19 +    finally:
   61.20 +        __classes_lock.release()
   61.21  
   61.22  def deregister(uuid, type):
   61.23 -    old = get(uuid, type)
   61.24 -    if old is not None:
   61.25 -        del __classes[(uuid, type)]
   61.26 -    return old
   61.27 +    __classes_lock.acquire()
   61.28 +    try:
   61.29 +        old = get(uuid, type)
   61.30 +        if old is not None:
   61.31 +            del __classes[(uuid, type)]
   61.32 +        return old
   61.33 +    finally:
   61.34 +        __classes_lock.release()
   61.35  
   61.36  def get(uuid, type):
   61.37      """
   61.38      Get the instances by uuid and type
   61.39      """
   61.40 -    return __classes.get((uuid, type), None)
   61.41 +    __classes_lock.acquire()
   61.42 +    try:
   61.43 +        return __classes.get((uuid, type), None)
   61.44 +    finally:
   61.45 +        __classes_lock.release()
   61.46  
   61.47  def get_all(all_type):
   61.48      """
   61.49      Get all instances by type
   61.50      """
   61.51 -    return [inst
   61.52 -            for ((uuid, t), inst) in __classes.items()
   61.53 -            if t == all_type]        
   61.54 +    __classes_lock.acquire()
   61.55 +    try:
   61.56 +        return [inst
   61.57 +                for ((uuid, t), inst) in __classes.items()
   61.58 +                if t == all_type]        
   61.59 +    finally:
   61.60 +        __classes_lock.release()
   61.61  
   61.62  def get_all_uuid(all_type):
   61.63      """
   61.64      Get all uuids by type
   61.65      """
   61.66 -    return [uuid
   61.67 -            for (uuid, t) in __classes.keys()
   61.68 -            if t == all_type]
   61.69 +    __classes_lock.acquire()
   61.70 +    try:
   61.71 +        return [uuid
   61.72 +                for (uuid, t) in __classes.keys()
   61.73 +                if t == all_type]
   61.74 +    finally:
   61.75 +        __classes_lock.release()
    62.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Fri Mar 27 10:54:08 2009 +0900
    62.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Fri Mar 27 11:07:11 2009 +0900
    62.3 @@ -114,7 +114,7 @@ def save(fd, dominfo, network, live, dst
    62.4              if line == "suspend":
    62.5                  log.debug("Suspending %d ...", dominfo.getDomid())
    62.6                  dominfo.shutdown('suspend')
    62.7 -                dominfo.waitForShutdown()
    62.8 +                dominfo.waitForSuspend()
    62.9              if line in ('suspend', 'suspended'):
   62.10                  dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2,
   62.11                                         domain_name)
    63.1 --- a/tools/python/xen/xend/XendConfig.py	Fri Mar 27 10:54:08 2009 +0900
    63.2 +++ b/tools/python/xen/xend/XendConfig.py	Fri Mar 27 11:07:11 2009 +0900
    63.3 @@ -170,6 +170,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
    63.4      'xen_extended_power_mgmt': int,
    63.5      'pci_msitranslate': int,
    63.6      'pci_power_mgmt': int,
    63.7 +    'xen_platform_pci': int,
    63.8  }
    63.9  
   63.10  # Xen API console 'other_config' keys.
   63.11 @@ -464,6 +465,8 @@ class XendConfig(dict):
   63.12                  self['platform']['rtc_timeoffset'] = 0
   63.13              if 'hpet' not in self['platform']:
   63.14                  self['platform']['hpet'] = 0
   63.15 +            if 'xen_platform_pci' not in self['platform']:
   63.16 +                self['platform']['xen_platform_pci'] = 1
   63.17              if 'vpt_align' not in self['platform']:
   63.18                  self['platform']['vpt_align'] = 1
   63.19              if 'loader' not in self['platform']:
   63.20 @@ -1155,7 +1158,7 @@ class XendConfig(dict):
   63.21                      return None
   63.22          return devid
   63.23      
   63.24 -    def device_duplicate_check(self, dev_type, dev_info, defined_config):
   63.25 +    def device_duplicate_check(self, dev_type, dev_info, defined_config, config):
   63.26          defined_devices_sxpr = self.all_devices_sxpr(target = defined_config)
   63.27          
   63.28          if dev_type == 'vbd' or dev_type == 'tap':
   63.29 @@ -1174,9 +1177,34 @@ class XendConfig(dict):
   63.30                          if blkdev_file == o_blkdev_file:
   63.31                              raise XendConfigError('The file "%s" is already used' %
   63.32                                                    blkdev_file)
   63.33 +                    if dev_uname == o_dev_uname:
   63.34 +                        raise XendConfigError('The uname "%s" is already defined' %
   63.35 +                                             dev_uname)
   63.36                      o_blkdev_name = sxp.child_value(o_dev_info, 'dev')
   63.37                      o_devid = self._blkdev_name_to_number(o_blkdev_name)
   63.38                      if o_devid != None and devid == o_devid:
   63.39 +                        name_array = blkdev_name.split(':', 2)
   63.40 +                        if len(name_array) == 2 and name_array[1] == 'cdrom':
   63.41 +                            #
   63.42 +                            # Since the device is a cdrom, we are most likely
   63.43 +                            # inserting, changing, or removing a cd.  We can
   63.44 +                            # update the old device instead of creating a new
   63.45 +                            # one.
   63.46 +                            #
   63.47 +                            if o_dev_uname != None and dev_uname == None:
   63.48 +                                #
   63.49 +                                # We are removing a cd.  We can simply update
   63.50 +                                # the uname on the existing device.
   63.51 +                                #
   63.52 +                                merge_sxp = sxp.from_string("('vbd' ('uname' ''))")
   63.53 +                            else:
   63.54 +                                merge_sxp = config
   63.55 +
   63.56 +                            dev_uuid = sxp.child_value(o_dev_info, 'uuid')
   63.57 +                            if dev_uuid != None and \
   63.58 +                               self.device_update(dev_uuid, cfg_sxp = merge_sxp):
   63.59 +                                return dev_uuid
   63.60 +
   63.61                          raise XendConfigError('The device "%s" is already defined' %
   63.62                                                blkdev_name)
   63.63                      
   63.64 @@ -1188,6 +1216,7 @@ class XendConfig(dict):
   63.65                      if dev_mac.lower() == sxp.child_value(o_dev_info, 'mac').lower():
   63.66                          raise XendConfigError('The mac "%s" is already defined' %
   63.67                                                dev_mac)
   63.68 +        return None
   63.69      
   63.70      def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None,
   63.71                     target = None):
   63.72 @@ -1326,7 +1355,9 @@ class XendConfig(dict):
   63.73                  if not dev_info.get('mac'):
   63.74                      dev_info['mac'] = randomMAC()
   63.75  
   63.76 -            self.device_duplicate_check(dev_type, dev_info, target)
   63.77 +            ret_uuid = self.device_duplicate_check(dev_type, dev_info, target, config)
   63.78 +            if ret_uuid != None:
   63.79 +                return ret_uuid
   63.80  
   63.81              if dev_type == 'vif':
   63.82                  if dev_info.get('policy') and dev_info.get('label'):
   63.83 @@ -1820,8 +1851,11 @@ class XendConfig(dict):
   63.84                  vscsi_be = vscsi_dict.get('backend', None)
   63.85  
   63.86                  # destroy existing XenAPI DSCSI objects
   63.87 +                vscsi_devid = int(dev_info['devs'][0]['devid'])
   63.88                  for dscsi_uuid in XendDSCSI.get_by_VM(self['uuid']):
   63.89 -                    XendAPIStore.deregister(dscsi_uuid, "DSCSI")
   63.90 +                    dscsi_inst = XendAPIStore.get(dscsi_uuid, 'DSCSI')
   63.91 +                    if vscsi_devid == dscsi_inst.get_virtual_host():
   63.92 +                        XendAPIStore.deregister(dscsi_uuid, "DSCSI")
   63.93  
   63.94                  # create XenAPI DSCSI objects.
   63.95                  for vscsi_dev in vscsi_devs:
    64.1 --- a/tools/python/xen/xend/XendConstants.py	Fri Mar 27 10:54:08 2009 +0900
    64.2 +++ b/tools/python/xen/xend/XendConstants.py	Fri Mar 27 11:07:11 2009 +0900
    64.3 @@ -96,7 +96,7 @@ SHUTDOWN_TIMEOUT = (60.0 * 5)
    64.4  ZOMBIE_PREFIX = 'Zombie-'
    64.5  
    64.6  """Minimum time between domain restarts in seconds."""
    64.7 -MINIMUM_RESTART_TIME = 20
    64.8 +MINIMUM_RESTART_TIME = 60
    64.9  
   64.10  RESTART_IN_PROGRESS = 'xend/restart_in_progress'
   64.11  DUMPCORE_IN_PROGRESS = 'xend/dumpcore_in_progress'
   64.12 @@ -135,3 +135,6 @@ VTPM_DELETE_SCRIPT = '/etc/xen/scripts/v
   64.13  
   64.14  XS_VMROOT = "/vm/"
   64.15  
   64.16 +NR_PCI_DEV = 32
   64.17 +AUTO_PHP_SLOT = NR_PCI_DEV
   64.18 +AUTO_PHP_SLOT_STR = "%02x" % NR_PCI_DEV
    65.1 --- a/tools/python/xen/xend/XendDomain.py	Fri Mar 27 10:54:08 2009 +0900
    65.2 +++ b/tools/python/xen/xend/XendDomain.py	Fri Mar 27 11:07:11 2009 +0900
    65.3 @@ -1223,7 +1223,7 @@ class XendDomain:
    65.4              log.exception("domain_pause")
    65.5              raise XendError(str(ex))
    65.6  
    65.7 -    def domain_dump(self, domid, filename, live, crash):
    65.8 +    def domain_dump(self, domid, filename=None, live=False, crash=False, reset=False):
    65.9          """Dump domain core."""
   65.10  
   65.11          dominfo = self.domain_lookup_nr(domid)
   65.12 @@ -1237,13 +1237,25 @@ class XendDomain:
   65.13                               POWER_STATE_NAMES[DOM_STATE_PAUSED],
   65.14                               POWER_STATE_NAMES[dominfo._stateGet()])
   65.15  
   65.16 +        dopause = (not live and dominfo._stateGet() == DOM_STATE_RUNNING)
   65.17 +        if dopause:
   65.18 +            dominfo.pause()
   65.19 +
   65.20          try:
   65.21 -            log.info("Domain core dump requested for domain %s (%d) "
   65.22 -                     "live=%d crash=%d.",
   65.23 -                     dominfo.getName(), dominfo.getDomid(), live, crash)
   65.24 -            return dominfo.dumpCore(filename)
   65.25 -        except Exception, ex:
   65.26 -            raise XendError(str(ex))
   65.27 +            try:
   65.28 +                log.info("Domain core dump requested for domain %s (%d) "
   65.29 +                         "live=%d crash=%d reset=%d.",
   65.30 +                         dominfo.getName(), dominfo.getDomid(), live, crash, reset)
   65.31 +                dominfo.dumpCore(filename)
   65.32 +                if crash:
   65.33 +                    self.domain_destroy(domid)
   65.34 +                elif reset:
   65.35 +                    self.domain_reset(domid)
   65.36 +            except Exception, ex:
   65.37 +                raise XendError(str(ex))
   65.38 +        finally:
   65.39 +            if dopause and not crash and not reset:
   65.40 +                dominfo.unpause()
   65.41  
   65.42      def domain_destroy(self, domid):
   65.43          """Terminate domain immediately.
    66.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Mar 27 10:54:08 2009 +0900
    66.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Mar 27 11:07:11 2009 +0900
    66.3 @@ -793,7 +793,7 @@ class XendDomainInfo:
    66.4                  existing_dev_uuid = sxp.child_value(existing_dev_info, 'uuid')
    66.5                  existing_pci_conf = self.info['devices'][existing_dev_uuid][1]
    66.6                  existing_pci_devs = existing_pci_conf['devs']
    66.7 -                vslt = '0x0'
    66.8 +                vslt = AUTO_PHP_SLOT_STR
    66.9                  for x in existing_pci_devs:
   66.10                      if ( int(x['domain'], 16) == int(dev['domain'], 16) and
   66.11                           int(x['bus'], 16) == int(dev['bus'], 16) and
   66.12 @@ -801,7 +801,7 @@ class XendDomainInfo:
   66.13                           int(x['func'], 16) == int(dev['func'], 16) ):
   66.14                          vslt = x['vslt']
   66.15                          break
   66.16 -                if vslt == '0x0':
   66.17 +                if vslt == AUTO_PHP_SLOT_STR:
   66.18                      raise VmError("Device %04x:%02x:%02x.%01x is not connected"
   66.19                                    % (int(dev['domain'],16), int(dev['bus'],16),
   66.20                                       int(dev['slot'],16), int(dev['func'],16)))
   66.21 @@ -1410,7 +1410,8 @@ class XendDomainInfo:
   66.22              for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
   66.23                  if dev_type == 'vfb':
   66.24                      old_location = dev_info.get('location')
   66.25 -                    listen_host = dev_info.get('vnclisten', 'localhost')
   66.26 +                    listen_host = dev_info.get('vnclisten', \
   66.27 +                                XendOptions.instance().get_vnclisten_address())
   66.28                      new_location = '%s:%s' % (listen_host, str(vnc_port))
   66.29                      if old_location == new_location:
   66.30                          break
   66.31 @@ -1495,7 +1496,8 @@ class XendDomainInfo:
   66.32          t.mkdir()
   66.33          t.set_permissions({'dom' : self.domid, 'read' : True})
   66.34          t.write('vm', self.vmpath)
   66.35 -        for i in [ 'device', 'control', 'error', 'memory' ]:
   66.36 +        # NB. Solaris guests use guest/ and hvmpv/ xenstore directories
   66.37 +        for i in [ 'device', 'control', 'error', 'memory', 'guest', 'hvmpv' ]:
   66.38              t.mkdir(i)
   66.39              t.set_permissions(i, {'dom' : self.domid})
   66.40  
   66.41 @@ -2027,26 +2029,31 @@ class XendDomainInfo:
   66.42          @raise: XendError if core dumping failed.
   66.43          """
   66.44          
   66.45 -        try:
   66.46 -            if not corefile:
   66.47 -                this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
   66.48 -                corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
   66.49 -                                  self.info['name_label'], self.domid)
   66.50 +        if not corefile:
   66.51 +            this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
   66.52 +            corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
   66.53 +                              self.info['name_label'], self.domid)
   66.54                  
   66.55 -            if os.path.isdir(corefile):
   66.56 -                raise XendError("Cannot dump core in a directory: %s" %
   66.57 -                                corefile)
   66.58 -            
   66.59 -            self._writeVm(DUMPCORE_IN_PROGRESS, 'True')
   66.60 -            xc.domain_dumpcore(self.domid, corefile)
   66.61 +        if os.path.isdir(corefile):
   66.62 +            raise XendError("Cannot dump core in a directory: %s" %
   66.63 +                            corefile)
   66.64 +
   66.65 +        try:
   66.66 +            try:
   66.67 +                self._writeVm(DUMPCORE_IN_PROGRESS, 'True')
   66.68 +                xc.domain_dumpcore(self.domid, corefile)
   66.69 +            except RuntimeError, ex:
   66.70 +                corefile_incomp = corefile+'-incomplete'
   66.71 +                try:
   66.72 +                    os.rename(corefile, corefile_incomp)
   66.73 +                except:
   66.74 +                    pass
   66.75 +
   66.76 +                log.error("core dump failed: id = %s name = %s: %s",
   66.77 +                          self.domid, self.info['name_label'], str(ex))
   66.78 +                raise XendError("Failed to dump core: %s" %  str(ex))
   66.79 +        finally:
   66.80              self._removeVm(DUMPCORE_IN_PROGRESS)
   66.81 -        except RuntimeError, ex:
   66.82 -            corefile_incomp = corefile+'-incomplete'
   66.83 -            os.rename(corefile, corefile_incomp)
   66.84 -            self._removeVm(DUMPCORE_IN_PROGRESS)
   66.85 -            log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
   66.86 -                          self.domid, self.info['name_label'])
   66.87 -            raise XendError("Failed to dump core: %s" %  str(ex))
   66.88  
   66.89      #
   66.90      # Device creation/deletion functions
   66.91 @@ -2544,6 +2551,31 @@ class XendDomainInfo:
   66.92          finally:
   66.93              self.state_updated.release()
   66.94  
   66.95 +    def waitForSuspend(self):
   66.96 +        """Wait for the guest to respond to a suspend request by
   66.97 +        shutting down.  If the guest hasn't re-written control/shutdown
   66.98 +        after a certain amount of time, it's obviously not listening and
   66.99 +        won't suspend, so we give up.  HVM guests with no PV drivers
  66.100 +        should already be shutdown.
  66.101 +        """
  66.102 +        state = "suspend"
  66.103 +        nr_tries = 60
  66.104 +
  66.105 +        self.state_updated.acquire()
  66.106 +        try:
  66.107 +            while self._stateGet() in (DOM_STATE_RUNNING,DOM_STATE_PAUSED):
  66.108 +                self.state_updated.wait(1.0)
  66.109 +                if state == "suspend":
  66.110 +                    if nr_tries == 0:
  66.111 +                        msg = ('Timeout waiting for domain %s to suspend'
  66.112 +                            % self.domid)
  66.113 +                        self._writeDom('control/shutdown', '')
  66.114 +                        raise XendError(msg)
  66.115 +                    state = self.readDom('control/shutdown')
  66.116 +                    nr_tries -= 1
  66.117 +        finally:
  66.118 +            self.state_updated.release()
  66.119 +
  66.120      #
  66.121      # TODO: recategorise - called from XendCheckpoint
  66.122      # 
  66.123 @@ -2888,7 +2920,9 @@ class XendDomainInfo:
  66.124          while True:
  66.125              test = 0
  66.126              diff = time.time() - start
  66.127 -            for i in self.getDeviceController('vbd').deviceIDs():
  66.128 +            vbds = self.getDeviceController('vbd').deviceIDs()
  66.129 +            taps = self.getDeviceController('tap').deviceIDs()
  66.130 +            for i in vbds + taps:
  66.131                  test = 1
  66.132                  log.info("Dev %s still active, looping...", i)
  66.133                  time.sleep(0.1)
  66.134 @@ -3669,7 +3703,8 @@ class XendDomainInfo:
  66.135                      ['v-dev', xenapi_dscsi.get('virtual_HCTL')],
  66.136                      ['state', xenbusState['Initialising']],
  66.137                      ['uuid', dscsi_uuid]
  66.138 -                ]
  66.139 +                ],
  66.140 +                ['feature-host', 0]
  66.141              ]
  66.142  
  66.143          if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING:
  66.144 @@ -3682,7 +3717,7 @@ class XendDomainInfo:
  66.145                      raise XendError('Failed to create device')
  66.146  
  66.147              else:
  66.148 -                new_vscsi_sxp = ['vscsi']
  66.149 +                new_vscsi_sxp = ['vscsi', ['feature-host', 0]]
  66.150                  for existing_dev in sxp.children(cur_vscsi_sxp, 'dev'):
  66.151                      new_vscsi_sxp.append(existing_dev)
  66.152                  new_vscsi_sxp.append(sxp.child0(target_vscsi_sxp, 'dev'))
  66.153 @@ -3776,7 +3811,7 @@ class XendDomainInfo:
  66.154          dev_uuid = sxp.child_value(cur_vscsi_sxp, 'uuid')
  66.155  
  66.156          target_dev = None
  66.157 -        new_vscsi_sxp = ['vscsi']
  66.158 +        new_vscsi_sxp = ['vscsi', ['feature-host', 0]]
  66.159          for dev in sxp.children(cur_vscsi_sxp, 'dev'):
  66.160              if vHCTL == sxp.child_value(dev, 'v-dev'):
  66.161                  target_dev = dev
  66.162 @@ -3787,7 +3822,7 @@ class XendDomainInfo:
  66.163              raise XendError('Failed to destroy device')
  66.164  
  66.165          target_dev.append(['state', xenbusState['Closing']])
  66.166 -        target_vscsi_sxp = ['vscsi', target_dev]
  66.167 +        target_vscsi_sxp = ['vscsi', target_dev, ['feature-host', 0]]
  66.168  
  66.169          if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING:
  66.170  
    67.1 --- a/tools/python/xen/xend/XendNode.py	Fri Mar 27 10:54:08 2009 +0900
    67.2 +++ b/tools/python/xen/xend/XendNode.py	Fri Mar 27 11:07:11 2009 +0900
    67.3 @@ -18,6 +18,7 @@
    67.4  
    67.5  import os
    67.6  import socket
    67.7 +import time
    67.8  import xen.lowlevel.xc
    67.9  
   67.10  from xen.util import Brctl
   67.11 @@ -145,6 +146,18 @@ class XendNode:
   67.12  
   67.13          self.srs = {}
   67.14  
   67.15 +        self._init_networks()
   67.16 +        self._init_PIFs()
   67.17 +
   67.18 +        self._init_SRs()
   67.19 +        self._init_PBDs()
   67.20 +
   67.21 +        self._init_PPCIs()
   67.22 +
   67.23 +        self._init_PSCSIs()
   67.24 +
   67.25 +
   67.26 +    def _init_networks(self):
   67.27          # Initialise networks
   67.28          # First configure ones off disk
   67.29          saved_networks = self.state_store.load_state('network')
   67.30 @@ -157,7 +170,16 @@ class XendNode:
   67.31                  
   67.32          # Next discover any existing bridges and check
   67.33          # they are not already configured
   67.34 -        bridges = Brctl.get_state().keys()
   67.35 +
   67.36 +        # 'tmpbridge' is a temporary bridge created by network-bridge script.
   67.37 +        # Wait a couple of seconds for it to be renamed.
   67.38 +        for i in xrange(20):
   67.39 +            bridges = Brctl.get_state().keys()
   67.40 +            if 'tmpbridge' in bridges:
   67.41 +                time.sleep(0.1)
   67.42 +            else:
   67.43 +                break
   67.44 +            
   67.45          configured_bridges = [XendAPIStore.get(
   67.46                                    network_uuid, "network")
   67.47                                        .get_name_label()
   67.48 @@ -166,8 +188,10 @@ class XendNode:
   67.49                                  for bridge in bridges
   67.50                                  if bridge not in configured_bridges]
   67.51          for unconfigured_bridge in unconfigured_bridges:
   67.52 -            XendNetwork.create_phy(unconfigured_bridge)
   67.53 +            if unconfigured_bridge != 'tmpbridge':
   67.54 +                XendNetwork.create_phy(unconfigured_bridge)
   67.55  
   67.56 +    def _init_PIFs(self):
   67.57          # Initialise PIFs
   67.58          # First configure ones off disk
   67.59          saved_pifs = self.state_store.load_state('pif')
   67.60 @@ -210,7 +234,8 @@ class XendNode:
   67.61                      log.debug("Cannot find network for bridge %s "
   67.62                                "when configuring PIF %s",
   67.63                                (bridge_name, name))     
   67.64 -        
   67.65 +
   67.66 +    def _init_SRs(self):
   67.67          # initialise storage
   67.68          saved_srs = self.state_store.load_state('sr')
   67.69          if saved_srs:
   67.70 @@ -229,6 +254,7 @@ class XendNode:
   67.71              qcow_sr_uuid = uuid.createString()
   67.72              self.srs[qcow_sr_uuid] = XendQCoWStorageRepo(qcow_sr_uuid)
   67.73  
   67.74 +    def _init_PBDs(self):
   67.75          saved_pbds = self.state_store.load_state('pbd')
   67.76          if saved_pbds:
   67.77              for pbd_uuid, pbd_cfg in saved_pbds.items():
   67.78 @@ -237,8 +263,7 @@ class XendNode:
   67.79                  except CreateUnspecifiedAttributeError:
   67.80                      log.warn("Error recreating PBD %s", pbd_uuid) 
   67.81  
   67.82 -
   67.83 -        # Initialise PPCIs
   67.84 +    def _init_PPCIs(self):
   67.85          saved_ppcis = self.state_store.load_state('ppci')
   67.86          saved_ppci_table = {}
   67.87          if saved_ppcis:
   67.88 @@ -271,7 +296,7 @@ class XendNode:
   67.89              ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString())
   67.90              XendPPCI(ppci_uuid, ppci_record)
   67.91  
   67.92 -
   67.93 +    def _init_PSCSIs(self):
   67.94          # Initialise PSCSIs
   67.95          saved_pscsis = self.state_store.load_state('pscsi')
   67.96          saved_pscsi_table = {}
   67.97 @@ -290,6 +315,75 @@ class XendNode:
   67.98                  XendPSCSI(pscsi_uuid, pscsi_record)
   67.99  
  67.100  
  67.101 +    def add_network(self, interface):
  67.102 +        # TODO
  67.103 +        log.debug("add_network(): Not implemented.")
  67.104 +
  67.105 +
  67.106 +    def remove_network(self, interface):
  67.107 +        # TODO
  67.108 +        log.debug("remove_network(): Not implemented.")
  67.109 +
  67.110 +
  67.111 +    def add_PPCI(self, pci_name):
  67.112 +        # Update lspci info
  67.113 +        PciUtil.create_lspci_info()
  67.114 +
  67.115 +        # Initialise the PPCI
  67.116 +        saved_ppcis = self.state_store.load_state('ppci')
  67.117 +        saved_ppci_table = {}
  67.118 +        if saved_ppcis:
  67.119 +            for ppci_uuid, ppci_record in saved_ppcis.items():
  67.120 +                try:
  67.121 +                    saved_ppci_table[ppci_record['name']] = ppci_uuid
  67.122 +                except KeyError:
  67.123 +                    pass
  67.124 +
  67.125 +        (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name)
  67.126 +        pci_dev = PciUtil.PciDevice(domain, bus, slot, func)
  67.127 +        ppci_record = {
  67.128 +            'domain':                   pci_dev.domain,
  67.129 +            'bus':                      pci_dev.bus,
  67.130 +            'slot':                     pci_dev.slot,
  67.131 +            'func':                     pci_dev.func,
  67.132 +            'vendor_id':                pci_dev.vendor,
  67.133 +            'vendor_name':              pci_dev.vendorname,
  67.134 +            'device_id':                pci_dev.device,
  67.135 +            'device_name':              pci_dev.devicename,
  67.136 +            'revision_id':              pci_dev.revision,
  67.137 +            'class_code':               pci_dev.classcode,
  67.138 +            'class_name':               pci_dev.classname,
  67.139 +            'subsystem_vendor_id':      pci_dev.subvendor,
  67.140 +            'subsystem_vendor_name':    pci_dev.subvendorname,
  67.141 +            'subsystem_id':             pci_dev.subdevice,
  67.142 +            'subsystem_name':           pci_dev.subdevicename,
  67.143 +            'driver':                   pci_dev.driver
  67.144 +            }
  67.145 +        # If saved uuid exists, use it. Otherwise create one.
  67.146 +        ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString())
  67.147 +        XendPPCI(ppci_uuid, ppci_record)
  67.148 +
  67.149 +
  67.150 +    def remove_PPCI(self, pci_name):
  67.151 +        # Update lspci info
  67.152 +        PciUtil.create_lspci_info()
  67.153 +
  67.154 +        # Remove the PPCI
  67.155 +        (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name)
  67.156 +        ppci_ref = XendPPCI.get_by_sbdf(domain, bus, slot, func)
  67.157 +        XendAPIStore.get(ppci_ref, "PPCI").destroy()
  67.158 +
  67.159 +
  67.160 +    def add_PSCSI(self):
  67.161 +        # TODO
  67.162 +        log.debug("add_network(): Not implemented.")
  67.163 +
  67.164 +
  67.165 +    def remove_PSCSI(self):
  67.166 +        # TODO
  67.167 +        log.debug("add_network(): Not implemented.")
  67.168 +
  67.169 +
  67.170  ##    def network_destroy(self, net_uuid):
  67.171   ##       del self.networks[net_uuid]
  67.172    ##      self.save_networks()
    68.1 --- a/tools/python/xen/xend/XendOptions.py	Fri Mar 27 10:54:08 2009 +0900
    68.2 +++ b/tools/python/xen/xend/XendOptions.py	Fri Mar 27 11:07:11 2009 +0900
    68.3 @@ -75,6 +75,9 @@ class XendOptions:
    68.4      """Default for the flag indicating whether xend should run a ssl relocation server."""
    68.5      xend_relocation_ssl_server_default = 'no'
    68.6  
    68.7 +    """Default for the flag indicating whether xend should run a udev event server."""
    68.8 +    xend_udev_event_server_default = 'no'
    68.9 +
   68.10      """Default interface address the xend relocation server listens at. """
   68.11      xend_relocation_address_default = ''
   68.12  
   68.13 @@ -216,6 +219,10 @@ class XendOptions:
   68.14      def get_xend_relocation_server_ssl_cert_file(self):
   68.15          return self.get_config_string("xend-relocation-server-ssl-cert-file")
   68.16  
   68.17 +    def get_xend_udev_event_server(self):
   68.18 +        return self.get_config_bool("xend-udev-event-server",
   68.19 +                                    self.xend_udev_event_server_default)
   68.20 +
   68.21      def get_xend_port(self):
   68.22          """Get the port xend listens at for its HTTP interface.
   68.23          """
    69.1 --- a/tools/python/xen/xend/XendPPCI.py	Fri Mar 27 10:54:08 2009 +0900
    69.2 +++ b/tools/python/xen/xend/XendPPCI.py	Fri Mar 27 11:07:11 2009 +0900
    69.3 @@ -20,6 +20,8 @@ from xen.xend.XendBase import XendBase
    69.4  from xen.xend.XendBase import XendAPIStore
    69.5  from xen.xend import uuid as genuuid
    69.6  
    69.7 +from xen.util.pci import parse_hex
    69.8 +
    69.9  class XendPPCI(XendBase):
   69.10      """Representation of a physical PCI device."""
   69.11  
   69.12 @@ -72,10 +74,10 @@ class XendPPCI(XendBase):
   69.13   
   69.14      def get_by_sbdf(self, domain, bus, slot, func):
   69.15          for ppci in XendAPIStore.get_all("PPCI"):
   69.16 -            if ppci.get_domain() == int(domain, 16) and \
   69.17 -               ppci.get_bus() == int(bus, 16) and \
   69.18 -               ppci.get_slot() == int(slot, 16) and \
   69.19 -               ppci.get_func() == int(func, 16):
   69.20 +            if ppci.get_domain() == parse_hex(domain) and \
   69.21 +               ppci.get_bus() == parse_hex(bus) and \
   69.22 +               ppci.get_slot() == parse_hex(slot) and \
   69.23 +               ppci.get_func() == parse_hex(func):
   69.24                  return ppci.get_uuid()
   69.25          return None
   69.26  
    70.1 --- a/tools/python/xen/xend/image.py	Fri Mar 27 10:54:08 2009 +0900
    70.2 +++ b/tools/python/xen/xend/image.py	Fri Mar 27 11:07:11 2009 +0900
    70.3 @@ -28,6 +28,7 @@ import sys
    70.4  import errno
    70.5  import glob
    70.6  import traceback
    70.7 +import platform
    70.8  
    70.9  import xen.lowlevel.xc
   70.10  from xen.xend.XendConstants import *
   70.11 @@ -40,6 +41,7 @@ from xen.xend import arch
   70.12  from xen.xend import XendOptions
   70.13  from xen.util import oshelp
   70.14  from xen.util import utils
   70.15 +from xen.xend import osdep
   70.16  
   70.17  xc = xen.lowlevel.xc.xc()
   70.18  
   70.19 @@ -226,23 +228,23 @@ class ImageHandler:
   70.20          if self.device_model is None:
   70.21              return
   70.22  
   70.23 -        # If we use a device model, the pipes for communication between
   70.24 -        # blktapctrl and ioemu must be present before the devices are 
   70.25 -        # created (blktapctrl must access them for new block devices)
   70.26 +        if platform.system() != 'SunOS':
   70.27 +            # If we use a device model, the pipes for communication between
   70.28 +            # blktapctrl and ioemu must be present before the devices are 
   70.29 +            # created (blktapctrl must access them for new block devices)
   70.30  
   70.31 -        # mkdir throws an exception if the path already exists
   70.32 -        try:
   70.33 -            os.mkdir('/var/run/tap', 0755)
   70.34 -        except:
   70.35 -            pass
   70.36 +            try:
   70.37 +                os.makedirs('/var/run/tap', 0755)
   70.38 +            except:
   70.39 +                pass
   70.40  
   70.41 -        try:
   70.42 -            os.mkfifo('/var/run/tap/qemu-read-%d' % domid, 0600)
   70.43 -            os.mkfifo('/var/run/tap/qemu-write-%d' % domid, 0600)
   70.44 -        except OSError, e:
   70.45 -            log.warn('Could not create blktap pipes for domain %d' % domid)
   70.46 -            log.exception(e)
   70.47 -            pass
   70.48 +            try:
   70.49 +                os.mkfifo('/var/run/tap/qemu-read-%d' % domid, 0600)
   70.50 +                os.mkfifo('/var/run/tap/qemu-write-%d' % domid, 0600)
   70.51 +            except OSError, e:
   70.52 +                log.warn('Could not create blktap pipes for domain %d' % domid)
   70.53 +                log.exception(e)
   70.54 +                pass
   70.55  
   70.56  
   70.57      # Return a list of cmd line args to the device models based on the
   70.58 @@ -407,9 +409,12 @@ class ImageHandler:
   70.59          logfd = os.open(self.logfile, logfile_mode)
   70.60          
   70.61          sys.stderr.flush()
   70.62 +        contract = osdep.prefork("%s:%d" %
   70.63 +                                 (self.vm.getName(), self.vm.getDomid()))
   70.64          pid = os.fork()
   70.65          if pid == 0: #child
   70.66              try:
   70.67 +                osdep.postfork(contract)
   70.68                  os.dup2(null, 0)
   70.69                  os.dup2(logfd, 1)
   70.70                  os.dup2(logfd, 2)
   70.71 @@ -426,6 +431,7 @@ class ImageHandler:
   70.72              except:
   70.73                  os._exit(127)
   70.74          else:
   70.75 +            osdep.postfork(contract, abandon=True)
   70.76              self.pid = pid
   70.77              os.close(null)
   70.78              os.close(logfd)
   70.79 @@ -482,11 +488,7 @@ class ImageHandler:
   70.80  
   70.81      def _dmfailed(self, message):
   70.82          log.warning("domain %s: %s", self.vm.getName(), message)
   70.83 -        # ideally we would like to forcibly crash the domain with
   70.84 -        # something like
   70.85 -        #    xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH)
   70.86 -        # but this can easily lead to very rapid restart loops against
   70.87 -        # which we currently have no protection
   70.88 +        xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH)
   70.89  
   70.90      def recreate(self):
   70.91          if self.device_model is None:
   70.92 @@ -714,6 +716,7 @@ class HVMImageHandler(ImageHandler):
   70.93          if 'hvm' not in info['xen_caps']:
   70.94              raise HVMRequired()
   70.95  
   70.96 +        xen_platform_pci = int(vmConfig['platform'].get('xen_platform_pci',1))
   70.97          rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
   70.98  
   70.99          if not self.display :
  70.100 @@ -722,13 +725,23 @@ class HVMImageHandler(ImageHandler):
  70.101                          ("image/device-model", self.device_model),
  70.102                          ("image/display", self.display))
  70.103          self.vm.permissionsVm("image/dmargs", { 'dom': self.vm.getDomid(), 'read': True } )
  70.104 +
  70.105 +        if xen_platform_pci == 0:
  70.106 +            disable_pf = 1
  70.107 +            log.info("No need to create platform device.[domid:%d]", self.vm.getDomid())
  70.108 +        else:
  70.109 +            disable_pf = 0
  70.110 +            log.info("Need to create platform device.[domid:%d]", self.vm.getDomid())
  70.111 +
  70.112 +        xstransact.Store("/local/domain/0/device-model/%i"%self.vm.getDomid(),
  70.113 +                                      ('disable_pf', disable_pf))
  70.114          self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset))
  70.115          self.vm.permissionsVm("rtc/timeoffset", { 'dom': self.vm.getDomid(), 'read': True } )
  70.116  
  70.117          self.apic = int(vmConfig['platform'].get('apic', 0))
  70.118          self.acpi = int(vmConfig['platform'].get('acpi', 0))
  70.119          self.guest_os_type = vmConfig['platform'].get('guest_os_type')
  70.120 -           
  70.121 +
  70.122  
  70.123      # Return a list of cmd line args to the device models based on the
  70.124      # xm config file
    71.1 --- a/tools/python/xen/xend/osdep.py	Fri Mar 27 10:54:08 2009 +0900
    71.2 +++ b/tools/python/xen/xend/osdep.py	Fri Mar 27 11:07:11 2009 +0900
    71.3 @@ -18,6 +18,7 @@
    71.4  # Use is subject to license terms.
    71.5  
    71.6  import os
    71.7 +import commands
    71.8  
    71.9  _scripts_dir = {
   71.10      "Linux": "/etc/xen/scripts",
   71.11 @@ -142,7 +143,79 @@ def _linux_get_cpuinfo():
   71.12      finally:
   71.13          f.close()
   71.14  
   71.15 +def _solaris_get_cpuinfo():
   71.16 +    cpuinfo = {}
   71.17 +
   71.18 +    # call kstat to extrace specific cpu_info output
   71.19 +    cmd = "/usr/bin/kstat -p -c misc -m cpu_info"
   71.20 +    kstatoutput = commands.getoutput (cmd)
   71.21 +
   71.22 +    # walk each line
   71.23 +    for kstatline in kstatoutput.split('\n'):
   71.24 +
   71.25 +        # split the line on 
   71.26 +        # module:cpu #:module#:name value
   71.27 +        (module, cpunum, combo, namevalue) = kstatline.split (":")
   71.28 +
   71.29 +        # check to see if this cpunum is already a key.  If not,
   71.30 +        # initialize an empty hash table
   71.31 +        if not cpuinfo.has_key (int(cpunum)):
   71.32 +            cpuinfo[int(cpunum)] = {}
   71.33 +
   71.34 +        # split the namevalue output on whitespace
   71.35 +        data = namevalue.split()
   71.36 +
   71.37 +        # the key will be data[0]
   71.38 +        key = data[0]
   71.39 +
   71.40 +        # check the length of the data list.  If it's larger than
   71.41 +        # 2, join the rest of the list together with a space.
   71.42 +        # Otherwise, value is just data[1]
   71.43 +        if len (data) > 2:
   71.44 +            value = ' '.join (data[1:])
   71.45 +        else:
   71.46 +            value = data[1]
   71.47 +
   71.48 +        # add this key/value pair to the cpuhash
   71.49 +        cpuinfo[int(cpunum)][key] = value
   71.50 +    
   71.51 +    # Translate Solaris tokens into what Xend expects
   71.52 +    for key in cpuinfo.keys():
   71.53 +        cpuinfo[key]["flags"] = ""
   71.54 +        cpuinfo[key]["model name"] = cpuinfo[key]["brand"]
   71.55 +        cpuinfo[key]["cpu MHz"] = cpuinfo[key]["clock_MHz"]
   71.56 +
   71.57 +    # return the hash table
   71.58 +    return cpuinfo
   71.59 +
   71.60  _get_cpuinfo = {
   71.61 +    "SunOS": _solaris_get_cpuinfo
   71.62 +}
   71.63 +
   71.64 +def _default_prefork(name):
   71.65 +    pass
   71.66 +
   71.67 +def _default_postfork(ct, abandon=False):
   71.68 +    pass
   71.69 +
   71.70 +# call this for long-running processes that should survive a xend
   71.71 +# restart
   71.72 +def _solaris_prefork(name):
   71.73 +    from xen.lowlevel import process
   71.74 +    return process.activate(name)
   71.75 +
   71.76 +def _solaris_postfork(ct, abandon=False):
   71.77 +    from xen.lowlevel import process
   71.78 +    process.clear(ct)
   71.79 +    if abandon:
   71.80 +        process.abandon_latest()
   71.81 +
   71.82 +_get_prefork = {
   71.83 +    "SunOS": _solaris_prefork
   71.84 +}
   71.85 +
   71.86 +_get_postfork = {
   71.87 +    "SunOS": _solaris_postfork
   71.88  }
   71.89  
   71.90  def _get(var, default=None):
   71.91 @@ -154,3 +227,5 @@ pygrub_path = _get(_pygrub_path, "/usr/b
   71.92  vif_script = _get(_vif_script, "vif-bridge")
   71.93  lookup_balloon_stat = _get(_balloon_stat, _linux_balloon_stat)
   71.94  get_cpuinfo = _get(_get_cpuinfo, _linux_get_cpuinfo)
   71.95 +prefork = _get(_get_prefork, _default_prefork)
   71.96 +postfork = _get(_get_postfork, _default_postfork)
    72.1 --- a/tools/python/xen/xend/server/BlktapController.py	Fri Mar 27 10:54:08 2009 +0900
    72.2 +++ b/tools/python/xen/xend/server/BlktapController.py	Fri Mar 27 11:07:11 2009 +0900
    72.3 @@ -15,7 +15,8 @@ blktap_disk_types = [
    72.4      'qcow',
    72.5      'qcow2',
    72.6  
    72.7 -    'ioemu'
    72.8 +    'ioemu',
    72.9 +    'tapdisk',
   72.10      ]
   72.11  
   72.12  class BlktapController(BlkifController):
    73.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Fri Mar 27 10:54:08 2009 +0900
    73.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Fri Mar 27 11:07:11 2009 +0900
    73.3 @@ -24,6 +24,7 @@ from xen.xend import osdep
    73.4  from xen.util import mkdir
    73.5  
    73.6  import relocate
    73.7 +import udevevent
    73.8  import SrvServer
    73.9  from params import *
   73.10  
   73.11 @@ -336,6 +337,7 @@ class Daemon:
   73.12              del xc
   73.13  
   73.14              relocate.listenRelocation()
   73.15 +            udevevent.listenUdevEvent()
   73.16              servers = SrvServer.create()
   73.17              servers.start(status)
   73.18              del servers
    74.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Fri Mar 27 10:54:08 2009 +0900
    74.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Fri Mar 27 11:07:11 2009 +0900
    74.3 @@ -104,7 +104,8 @@ class SrvDomain(SrvDir):
    74.4                      [['dom',         'int'],
    74.5                       ['file',        'str'],
    74.6                       ['live',        'int'],
    74.7 -                     ['crash',       'int']])
    74.8 +                     ['crash',       'int'],
    74.9 +                     ['reset',       'int']])
   74.10          return fn(req.args, {'dom': self.dom.domid})
   74.11  
   74.12      def op_migrate(self, op, req):
    75.1 --- a/tools/python/xen/xend/server/netif.py	Fri Mar 27 10:54:08 2009 +0900
    75.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Mar 27 11:07:11 2009 +0900
    75.3 @@ -24,7 +24,7 @@ import os
    75.4  import random
    75.5  import re
    75.6  
    75.7 -from xen.xend import XendOptions
    75.8 +from xen.xend import XendOptions, sxp
    75.9  from xen.xend.server.DevController import DevController
   75.10  from xen.xend.XendError import VmError
   75.11  from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
   75.12 @@ -196,3 +196,23 @@ class NetifController(DevController):
   75.13                  result[x] = y
   75.14  
   75.15          return result
   75.16 +
   75.17 +    # match a VIF ID from xenstore, or a MAC address stored in the domain config
   75.18 +    def convertToDeviceNumber(self, devid):
   75.19 +        try:
   75.20 +            return int(devid)
   75.21 +        except ValueError:
   75.22 +            if type(devid) is not str:
   75.23 +                raise VmError("devid %s is wrong type" % str(devid))
   75.24 +            try:
   75.25 +                dev = devid.split('/')[-1]
   75.26 +                return (int(dev))
   75.27 +            except ValueError:
   75.28 +                devs = [d for d in self.vm.info.all_devices_sxpr()
   75.29 +                    if d[0] == 'vif']
   75.30 +                for nr in range(len(devs)):
   75.31 +                    dev_type, dev_info = devs[nr]
   75.32 +                    if (sxp.child_value(dev_info, 'mac').lower() ==
   75.33 +                        devid.lower()):
   75.34 +                        return nr
   75.35 +                raise VmError("unknown devid %s" % str(devid))
    76.1 --- a/tools/python/xen/xend/server/pciif.py	Fri Mar 27 10:54:08 2009 +0900
    76.2 +++ b/tools/python/xen/xend/server/pciif.py	Fri Mar 27 11:07:11 2009 +0900
    76.3 @@ -24,6 +24,7 @@ from xen.xend import sxp
    76.4  from xen.xend import arch
    76.5  from xen.xend.XendError import VmError
    76.6  from xen.xend.XendLogging import log
    76.7 +from xen.xend.XendConstants import *
    76.8  
    76.9  from xen.xend.server.DevController import DevController
   76.10  from xen.xend.server.DevConstants import xenbusState
   76.11 @@ -74,6 +75,7 @@ class PciController(DevController):
   76.12              bus = parse_hex(pci_config.get('bus', 0))
   76.13              slot = parse_hex(pci_config.get('slot', 0))
   76.14              func = parse_hex(pci_config.get('func', 0))            
   76.15 +            vslot = parse_hex(pci_config.get('vslot', 0))
   76.16  
   76.17              opts = pci_config.get('opts', '')
   76.18              if len(opts) > 0:
   76.19 @@ -218,7 +220,7 @@ class PciController(DevController):
   76.20                      try:
   76.21                          dev_dict['vslt'] = slot_list[i]
   76.22                      except IndexError:
   76.23 -                        dev_dict['vslt'] = '0x0'
   76.24 +                        dev_dict['vslt'] = AUTO_PHP_SLOT_STR
   76.25  
   76.26                  pci_devs.append(dev_dict)
   76.27  
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/tools/python/xen/xend/server/udevevent.py	Fri Mar 27 11:07:11 2009 +0900
    77.3 @@ -0,0 +1,68 @@
    77.4 +import socket
    77.5 +
    77.6 +from xen.web import protocol, unix
    77.7 +
    77.8 +from xen.xend.XendLogging import log
    77.9 +from xen.xend import XendNode
   77.10 +from xen.xend import XendOptions
   77.11 +
   77.12 +UDEV_EVENT_PATH = '\0/org/xen/xend/udev_event'
   77.13 +
   77.14 +class UdevEventProtocol(protocol.Protocol):
   77.15 +
   77.16 +    def __init__(self):
   77.17 +        protocol.Protocol.__init__(self)
   77.18 +
   77.19 +    def dataReceived(self, data):
   77.20 +        udev_event = {}
   77.21 +        for entry in data.split('\0'):
   77.22 +            try:
   77.23 +                opt, val = entry.split("=")
   77.24 +                udev_event[opt] = val
   77.25 +            except (TypeError, ValueError):
   77.26 +                pass
   77.27 +        if udev_event.get('ACTION', None) is None:
   77.28 +            log.warn("Invalid udev event received")
   77.29 +            return
   77.30 +
   77.31 +        log.debug("udev event received: %s", udev_event)
   77.32 +
   77.33 +        self._process_event(udev_event)
   77.34 +
   77.35 +    def _process_event(self, udev_event):
   77.36 +        try:
   77.37 +            if (udev_event.get('SUBSYSTEM', None) == 'pci'):
   77.38 +                pci_name = udev_event.get('PCI_SLOT_NAME', None)
   77.39 +                if (udev_event['ACTION'] == 'add'):
   77.40 +                    log.info("Adding pci device %s", pci_name)
   77.41 +                    XendNode.instance().add_PPCI(pci_name)
   77.42 +                elif (udev_event['ACTION'] == 'remove'):
   77.43 +                    log.info("Removing pci device %s", pci_name)
   77.44 +                    XendNode.instance().remove_PPCI(pci_name)
   77.45 +
   77.46 +            elif (udev_event.get('SUBSYSTEMS', None) == 'scsi'):
   77.47 +                if (udev_event['ACTION'] == 'add'):
   77.48 +                    log.info("Adding scsi device")
   77.49 +                    XendNode.instance().add_PSCSI()
   77.50 +                elif (udev_event['ACTION'] == 'remove'):
   77.51 +                    log.info("Removing scci device")
   77.52 +                    XendNode.instance().remove_PSCSI()
   77.53 +
   77.54 +            elif (udev_event.get('SUBSYSTEM', None) == 'net'):
   77.55 +                interface = udev_event.get('INTERFACE', None)
   77.56 +                if (udev_event['ACTION'] == 'add'):
   77.57 +                    log.info("Adding net device %s", interface)
   77.58 +                    XendNode.instance().add_network(interface)
   77.59 +                elif (udev_event['ACTION'] == 'remove'):
   77.60 +                    log.info("Removing net device %s", interface)
   77.61 +                    XendNode.instance().remove_network(interface)
   77.62 +
   77.63 +        except Exception, e:
   77.64 +            log.warn("error while processing udev event(): %s" % str(e))
   77.65 +
   77.66 +
   77.67 +def listenUdevEvent():
   77.68 +    xoptions = XendOptions.instance()
   77.69 +    if xoptions.get_xend_udev_event_server():
   77.70 +        unix.UnixDgramListener(UDEV_EVENT_PATH, UdevEventProtocol)
   77.71 +
    78.1 --- a/tools/python/xen/xm/create.dtd	Fri Mar 27 10:54:08 2009 +0900
    78.2 +++ b/tools/python/xen/xm/create.dtd	Fri Mar 27 11:07:11 2009 +0900
    78.3 @@ -47,6 +47,7 @@
    78.4                   other_config*)> 
    78.5  <!ATTLIST vm     is_a_template          CDATA #REQUIRED
    78.6                   auto_power_on          CDATA #REQUIRED
    78.7 +                 s3_integrity           CDATA #REQUIRED
    78.8                   vcpus_max              CDATA #REQUIRED
    78.9                   vcpus_at_startup       CDATA #REQUIRED
   78.10                   actions_after_shutdown %NORMAL_EXIT; #REQUIRED 
    79.1 --- a/tools/python/xen/xm/create.py	Fri Mar 27 10:54:08 2009 +0900
    79.2 +++ b/tools/python/xen/xm/create.py	Fri Mar 27 11:07:11 2009 +0900
    79.3 @@ -1,4 +1,4 @@
    79.4 -#============================================================================
    79.5 +#============================================================================UTO
    79.6  # This library is free software; you can redistribute it and/or
    79.7  # modify it under the terms of version 2.1 of the GNU Lesser General Public
    79.8  # License as published by the Free Software Foundation.
    79.9 @@ -32,6 +32,7 @@ from xen.xend import PrettyPrint as SXPP
   79.10  from xen.xend import osdep
   79.11  import xen.xend.XendClient
   79.12  from xen.xend.XendBootloader import bootloader
   79.13 +from xen.xend.XendConstants import *
   79.14  from xen.xend.server.DevConstants import xenbusState
   79.15  from xen.util import blkif
   79.16  from xen.util import vscsi_util
   79.17 @@ -322,10 +323,12 @@ gopts.var('disk', val='phy:DEV,VDEV,MODE
   79.18            backend driver domain to use for the disk.
   79.19            The option may be repeated to add more than one disk.""")
   79.20  
   79.21 -gopts.var('pci', val='BUS:DEV.FUNC[,msitranslate=0|1][,power_mgmt=0|1]',
   79.22 +gopts.var('pci', val='BUS:DEV.FUNC[@VSLOT][,msitranslate=0|1][,power_mgmt=0|1]',
   79.23            fn=append_value, default=[],
   79.24            use="""Add a PCI device to a domain, using given params (in hex).
   79.25            For example 'pci=c0:02.1'.
   79.26 +          If VSLOT is supplied the device will be inserted into that
   79.27 +          virtual slot in the guest, else a free slot is selected.
   79.28            If msitranslate is set, MSI-INTx translation is enabled if possible.
   79.29            Guest that doesn't support MSI will get IO-APIC type IRQs
   79.30            translated from physical MSI, HVM only. Default is 1.
   79.31 @@ -611,6 +614,10 @@ gopts.var('pci_power_mgmt', val='POWERMG
   79.32            fn=set_int, default=0,
   79.33            use="""Global PCI Power Management flag (0=disable;1=enable).""")
   79.34  
   79.35 +gopts.var('xen_platform_pci', val='0|1',
   79.36 +           fn=set_int, default=1,
   79.37 +           use="Is xen_platform_pci used?")
   79.38 +
   79.39  def err(msg):
   79.40      """Print an error to stderr and exit.
   79.41      """
   79.42 @@ -692,7 +699,7 @@ def configure_pci(config_devs, vals):
   79.43      """Create the config for pci devices.
   79.44      """
   79.45      config_pci = []
   79.46 -    for (domain, bus, slot, func, opts) in vals.pci:
   79.47 +    for (domain, bus, slot, func, vslot, opts) in vals.pci:
   79.48          config_pci_opts = []
   79.49          d = comma_sep_kv_to_dict(opts)
   79.50  
   79.51 @@ -703,7 +710,7 @@ def configure_pci(config_devs, vals):
   79.52              config_pci_opts.append([k, d[k]])
   79.53  
   79.54          config_pci_bdf = ['dev', ['domain', domain], ['bus', bus], \
   79.55 -                          ['slot', slot], ['func', func]]
   79.56 +                          ['slot', slot], ['func', func], ['vslot', vslot]]
   79.57          map(f, d.keys())
   79.58          if len(config_pci_opts)>0:
   79.59              config_pci_bdf.append(['opts', config_pci_opts])
   79.60 @@ -738,6 +745,9 @@ def configure_vscsis(config_devs, vals):
   79.61  
   79.62          feature_host = 0
   79.63          if v_dev == 'host':
   79.64 +            if serverType == SERVER_XEN_API:
   79.65 +                # TODO
   79.66 +                raise ValueError("SCSI devices assignment by HBA is not implemeted")
   79.67              feature_host = 1
   79.68              scsi_info = []
   79.69              devid = get_devid(p_hctl)
   79.70 @@ -921,7 +931,7 @@ def configure_hvm(config_image, vals):
   79.71               'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet',
   79.72               'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check',
   79.73               'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate',
   79.74 -             'vpt_align', 'pci_power_mgmt' ]
   79.75 +             'vpt_align', 'pci_power_mgmt', 'xen_platform_pci' ]
   79.76  
   79.77      for a in args:
   79.78          if a in vals.__dict__ and vals.__dict__[a] is not None:
   79.79 @@ -1047,16 +1057,21 @@ def preprocess_pci(vals):
   79.80                  r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
   79.81                  r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \
   79.82                  r"(?P<func>[0-7])" + \
   79.83 -                r"(,(?P<opts>.*))?$", pci_dev_str)
   79.84 +                r"(@(?P<vslot>[0-9a-fA-F]))?" + \
   79.85 +                r"(,(?P<opts>.*))?$", \
   79.86 +                pci_dev_str)
   79.87          if pci_match!=None:
   79.88              pci_dev_info = pci_match.groupdict('')
   79.89              if pci_dev_info['domain']=='':
   79.90                  pci_dev_info['domain']='0'
   79.91 +            if pci_dev_info['vslot']=='':
   79.92 +                pci_dev_info['vslot']="%02x" % AUTO_PHP_SLOT
   79.93              try:
   79.94                  pci.append( ('0x'+pci_dev_info['domain'], \
   79.95                          '0x'+pci_dev_info['bus'], \
   79.96                          '0x'+pci_dev_info['slot'], \
   79.97                          '0x'+pci_dev_info['func'], \
   79.98 +                        '0x'+pci_dev_info['vslot'], \
   79.99                          pci_dev_info['opts']))
  79.100              except IndexError:
  79.101                  err('Error in PCI slot syntax "%s"'%(pci_dev_str))
    80.1 --- a/tools/python/xen/xm/main.py	Fri Mar 27 10:54:08 2009 +0900
    80.2 +++ b/tools/python/xen/xm/main.py	Fri Mar 27 11:07:11 2009 +0900
    80.3 @@ -1351,22 +1351,8 @@ def xm_dump_core(args):
    80.4      else:
    80.5          filename = None
    80.6  
    80.7 -    if not live:
    80.8 -        ds = server.xend.domain.pause(dom, True)
    80.9 -
   80.10 -    try:
   80.11 -        print "Dumping core of domain: %s ..." % str(dom)
   80.12 -        server.xend.domain.dump(dom, filename, live, crash)
   80.13 -
   80.14 -        if crash:
   80.15 -            print "Destroying domain: %s ..." % str(dom)
   80.16 -            server.xend.domain.destroy(dom)
   80.17 -        elif reset:
   80.18 -            print "Resetting domain: %s ..." % str(dom)
   80.19 -            server.xend.domain.reset(dom)
   80.20 -    finally:
   80.21 -        if not live and not crash and not reset and ds == DOM_STATE_RUNNING:
   80.22 -            server.xend.domain.unpause(dom)
   80.23 +    print "Dumping core of domain: %s ..." % str(dom)
   80.24 +    server.xend.domain.dump(dom, filename, live, crash, reset)
   80.25  
   80.26  def xm_rename(args):
   80.27      arg_check(args, "rename", 2)
   80.28 @@ -2231,6 +2217,33 @@ def xm_pci_list_assignable_devices(args)
   80.29              print d.name,
   80.30          print
   80.31  
   80.32 +def vscsi_sort(devs):
   80.33 +    def sort_hctl(ds, l):
   80.34 +        s = []
   80.35 +        for d1 in ds:
   80.36 +            for d2 in d1:
   80.37 +                v_dev = sxp.child_value(d2, 'v-dev')
   80.38 +                n = int(v_dev.split(':')[l])
   80.39 +                try:
   80.40 +                    j = s[n]
   80.41 +                except IndexError:
   80.42 +                    j = []
   80.43 +                    s.extend([ [] for _ in range(len(s), n+1) ])
   80.44 +                j.append(d2)
   80.45 +                s[n] = j
   80.46 +        return s
   80.47 +
   80.48 +    for i in range(len(devs)):
   80.49 +        ds1 = [ devs[i][1][0][1] ]
   80.50 +        ds1 = sort_hctl(ds1, 3)
   80.51 +        ds1 = sort_hctl(ds1, 2)
   80.52 +        ds1 = sort_hctl(ds1, 1)
   80.53 +        ds2 = []
   80.54 +        for d in ds1:
   80.55 +            ds2.extend(d)
   80.56 +        devs[i][1][0][1] = ds2
   80.57 +    return devs
   80.58 +
   80.59  def vscsi_convert_sxp_to_dict(dev_sxp):
   80.60      dev_dict = {}
   80.61      for opt_val in dev_sxp[1:]:
   80.62 @@ -2271,6 +2284,9 @@ def xm_scsi_list(args):
   80.63      else:
   80.64          devs = server.xend.domain.getDeviceSxprs(dom, 'vscsi')
   80.65  
   80.66 +    # Sort devs by virtual HCTL.
   80.67 +    devs = vscsi_sort(devs)
   80.68 +
   80.69      if use_long:
   80.70          map(PrettyPrint.prettyprint, devs)
   80.71      else:
   80.72 @@ -2440,7 +2456,7 @@ def parse_pci_configuration(args, state,
   80.73      if len(args) == 3:
   80.74          vslt = args[2]
   80.75      else:
   80.76 -        vslt = '0x0' #chose a free virtual PCI slot
   80.77 +        vslt = AUTO_PHP_SLOT_STR
   80.78      pci=['pci']
   80.79      pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \
   80.80              r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \
   80.81 @@ -2523,6 +2539,9 @@ def parse_scsi_configuration(p_scsi, v_h
   80.82      if p_scsi is not None:
   80.83          # xm scsi-attach
   80.84          if v_hctl == "host":
   80.85 +            if serverType == SERVER_XEN_API:
   80.86 +                # TODO
   80.87 +                raise OptionError("SCSI devices assignment by HBA is not implemeted")
   80.88              host_mode = 1
   80.89              scsi_devices = vscsi_util.vscsi_get_scsidevices()
   80.90          elif len(v_hctl.split(':')) != 4:
    81.1 --- a/tools/python/xen/xm/xenapi_create.py	Fri Mar 27 10:54:08 2009 +0900
    81.2 +++ b/tools/python/xen/xm/xenapi_create.py	Fri Mar 27 11:07:11 2009 +0900
    81.3 @@ -1048,6 +1048,7 @@ class sxp2xml:
    81.4              'hap',
    81.5              'pci_msitranslate',
    81.6              'pci_power_mgmt',
    81.7 +            'xen_platform_pci',
    81.8          ]
    81.9  
   81.10          platform_configs = []
    82.1 --- a/tools/xcutils/xc_save.c	Fri Mar 27 10:54:08 2009 +0900
    82.2 +++ b/tools/xcutils/xc_save.c	Fri Mar 27 11:07:11 2009 +0900
    82.3 @@ -46,97 +46,6 @@ static int compat_suspend(void)
    82.4              !strncmp(ans, "done\n", 5));
    82.5  }
    82.6  
    82.7 -static int suspend_evtchn_release(void)
    82.8 -{
    82.9 -    if (si.suspend_evtchn >= 0) {
   82.10 -        xc_evtchn_unbind(si.xce, si.suspend_evtchn);
   82.11 -        si.suspend_evtchn = -1;
   82.12 -    }
   82.13 -    if (si.xce >= 0) {
   82.14 -        xc_evtchn_close(si.xce);
   82.15 -        si.xce = -1;
   82.16 -    }
   82.17 -
   82.18 -    return 0;
   82.19 -}
   82.20 -
   82.21 -static int await_suspend(void)
   82.22 -{
   82.23 -    int rc;
   82.24 -
   82.25 -    do {
   82.26 -        rc = xc_evtchn_pending(si.xce);
   82.27 -        if (rc < 0) {
   82.28 -            warnx("error polling suspend notification channel: %d", rc);
   82.29 -            return -1;
   82.30 -        }
   82.31 -    } while (rc != si.suspend_evtchn);
   82.32 -
   82.33 -    /* harmless for one-off suspend */
   82.34 -    if (xc_evtchn_unmask(si.xce, si.suspend_evtchn) < 0)
   82.35 -        warnx("failed to unmask suspend notification channel: %d", rc);
   82.36 -
   82.37 -    return 0;
   82.38 -}
   82.39 -
   82.40 -static int suspend_evtchn_init(int xc, int domid)
   82.41 -{
   82.42 -    struct xs_handle *xs;
   82.43 -    char path[128];
   82.44 -    char *portstr;
   82.45 -    unsigned int plen;
   82.46 -    int port;
   82.47 -    int rc;
   82.48 -
   82.49 -    si.xce = -1;
   82.50 -    si.suspend_evtchn = -1;
   82.51 -
   82.52 -    xs = xs_daemon_open();
   82.53 -    if (!xs) {
   82.54 -        warnx("failed to get xenstore handle");
   82.55 -        return -1;
   82.56 -    }
   82.57 -    sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid);
   82.58 -    portstr = xs_read(xs, XBT_NULL, path, &plen);
   82.59 -    xs_daemon_close(xs);
   82.60 -
   82.61 -    if (!portstr || !plen) {
   82.62 -        warnx("could not read suspend event channel");
   82.63 -        return -1;
   82.64 -    }
   82.65 -
   82.66 -    port = atoi(portstr);
   82.67 -    free(portstr);
   82.68 -
   82.69 -    si.xce = xc_evtchn_open();
   82.70 -    if (si.xce < 0) {
   82.71 -        warnx("failed to open event channel handle");
   82.72 -        goto cleanup;
   82.73 -    }
   82.74 -
   82.75 -    si.suspend_evtchn = xc_evtchn_bind_interdomain(si.xce, domid, port);
   82.76 -    if (si.suspend_evtchn < 0) {
   82.77 -        warnx("failed to bind suspend event channel: %d", si.suspend_evtchn);
   82.78 -        goto cleanup;
   82.79 -    }
   82.80 -
   82.81 -    rc = xc_domain_subscribe_for_suspend(xc, domid, port);
   82.82 -    if (rc < 0) {
   82.83 -        warnx("failed to subscribe to domain: %d", rc);
   82.84 -        goto cleanup;
   82.85 -    }
   82.86 -
   82.87 -    /* event channel is pending immediately after binding */
   82.88 -    await_suspend();
   82.89 -
   82.90 -    return 0;
   82.91 -
   82.92 -  cleanup:
   82.93 -    suspend_evtchn_release();
   82.94 -
   82.95 -    return -1;
   82.96 -}
   82.97 -
   82.98  /**
   82.99   * Issue a suspend request to a dedicated event channel in the guest, and
  82.100   * receive the acknowledgement from the subscribe event channel. */
  82.101 @@ -150,7 +59,7 @@ static int evtchn_suspend(void)
  82.102          return 0;
  82.103      }
  82.104  
  82.105 -    if (await_suspend() < 0) {
  82.106 +    if (xc_await_suspend(si.xce, si.suspend_evtchn) < 0) {
  82.107          warnx("suspend failed");
  82.108          return 0;
  82.109      }
  82.110 @@ -303,12 +212,11 @@ static void *init_qemu_maps(int domid, u
  82.111      return seg;
  82.112  }
  82.113  
  82.114 -
  82.115  int
  82.116  main(int argc, char **argv)
  82.117  {
  82.118      unsigned int maxit, max_f;
  82.119 -    int io_fd, ret;
  82.120 +    int io_fd, ret, port;
  82.121  
  82.122      if (argc != 6)
  82.123          errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
  82.124 @@ -323,14 +231,37 @@ main(int argc, char **argv)
  82.125      max_f = atoi(argv[4]);
  82.126      si.flags = atoi(argv[5]);
  82.127  
  82.128 -    if (suspend_evtchn_init(si.xc_fd, si.domid) < 0)
  82.129 -        warnx("suspend event channel initialization failed, using slow path");
  82.130 +    si.suspend_evtchn = si.xce = -1;
  82.131  
  82.132 +    si.xce = xc_evtchn_open();
  82.133 +    if (si.xce < 0)
  82.134 +        warnx("failed to open event channel handle");
  82.135 +
  82.136 +    if (si.xce > 0)
  82.137 +    {
  82.138 +        port = xs_suspend_evtchn_port(si.domid);
  82.139 +
  82.140 +        if (port < 0)
  82.141 +            warnx("faield to get the suspend evtchn port\n");
  82.142 +        else
  82.143 +        {
  82.144 +            si.suspend_evtchn =
  82.145 +              xc_suspend_evtchn_init(si.xc_fd, si.xce, si.domid, port);
  82.146 +
  82.147 +            if (si.suspend_evtchn < 0)
  82.148 +                warnx("suspend event channel initialization failed"
  82.149 +                       "using slow path");
  82.150 +        }
  82.151 +    }
  82.152      ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, 
  82.153                           &suspend, !!(si.flags & XCFLAGS_HVM),
  82.154                           &init_qemu_maps, &qemu_flip_buffer);
  82.155  
  82.156 -    suspend_evtchn_release();
  82.157 +    if (si.suspend_evtchn > 0)
  82.158 +        xc_suspend_evtchn_release(si.xce, si.suspend_evtchn);
  82.159 +
  82.160 +    if (si.xce > 0)
  82.161 +        xc_evtchn_close(si.xce);
  82.162  
  82.163      xc_interface_close(si.xc_fd);
  82.164  
    83.1 --- a/tools/xenstore/Makefile	Fri Mar 27 10:54:08 2009 +0900
    83.2 +++ b/tools/xenstore/Makefile	Fri Mar 27 11:07:11 2009 +0900
    83.3 @@ -97,9 +97,9 @@ install: all
    83.4  	$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)
    83.5  	$(INSTALL_PROG) xenstored $(DESTDIR)$(SBINDIR)
    83.6  	$(INSTALL_PROG) xenstore-control $(DESTDIR)$(BINDIR)
    83.7 -	$(INSTALL_PROG) xenstore $(DESTDIR)/usr/bin
    83.8 +	$(INSTALL_PROG) xenstore $(DESTDIR)$(BINDIR)
    83.9  	set -e ; for c in $(CLIENTS) ; do \
   83.10 -		ln -f $(DESTDIR)/usr/bin/xenstore $(DESTDIR)/usr/bin/$${c} ; \
   83.11 +		ln -f $(DESTDIR)$(BINDIR)/xenstore $(DESTDIR)$(BINDIR)/$${c} ; \
   83.12  	done
   83.13  	$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
   83.14  	$(INSTALL_PROG) libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
    84.1 --- a/tools/xenstore/xs.c	Fri Mar 27 10:54:08 2009 +0900
    84.2 +++ b/tools/xenstore/xs.c	Fri Mar 27 11:07:11 2009 +0900
    84.3 @@ -802,6 +802,31 @@ bool xs_is_domain_introduced(struct xs_h
    84.4  	return rc;
    84.5  }
    84.6  
    84.7 +int xs_suspend_evtchn_port(int domid)
    84.8 +{
    84.9 +    char path[128];
   84.10 +    char *portstr;
   84.11 +    int port;
   84.12 +    unsigned int plen;
   84.13 +    struct xs_handle *xs;
   84.14 +
   84.15 +    xs = xs_daemon_open();
   84.16 +    if (!xs)
   84.17 +        return -1;
   84.18 +
   84.19 +    sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid);
   84.20 +    portstr = xs_read(xs, XBT_NULL, path, &plen);
   84.21 +    xs_daemon_close(xs);
   84.22 +
   84.23 +    if (!portstr || !plen)
   84.24 +        return -1;
   84.25 +
   84.26 +    port = atoi(portstr);
   84.27 +    free(portstr);
   84.28 +
   84.29 +    return port;
   84.30 +}
   84.31 +
   84.32  /* Only useful for DEBUG versions */
   84.33  char *xs_debug_command(struct xs_handle *h, const char *cmd,
   84.34  		       void *data, unsigned int len)
    85.1 --- a/tools/xenstore/xs.h	Fri Mar 27 10:54:08 2009 +0900
    85.2 +++ b/tools/xenstore/xs.h	Fri Mar 27 11:07:11 2009 +0900
    85.3 @@ -163,6 +163,7 @@ bool xs_is_domain_introduced(struct xs_h
    85.4  char *xs_debug_command(struct xs_handle *h, const char *cmd,
    85.5  		       void *data, unsigned int len);
    85.6  
    85.7 +int xs_suspend_evtchn_port(int domid);
    85.8  #endif /* _XS_H */
    85.9  
   85.10  /*
    86.1 --- a/tools/xentrace/formats	Fri Mar 27 10:54:08 2009 +0900
    86.2 +++ b/tools/xentrace/formats	Fri Mar 27 11:07:11 2009 +0900
    86.3 @@ -118,5 +118,5 @@ 0x0040f00f  CPU%(cpu)d  %(tsc)d (+%(relt
    86.4  0x0040f10f  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  shadow_emulate_resync_only        [ gfn = 0x%(1)16x ]
    86.5  
    86.6  0x00801001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_freq_change [ %(1)dMHz -> %(2)dMHz ]
    86.7 -0x00802001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_entry  [ C0 -> C%(1)d ]
    86.8 -0x00802002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_exit   [ C%(1)d -> C0 ]
    86.9 +0x00802001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_entry  [ C0 -> C%(1)d, acpi_pm_tick = %(2)d ]
   86.10 +0x00802002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_idle_exit   [ C%(1)d -> C0, acpi_pm_tick = %(2)d ]
    87.1 --- a/tools/xentrace/xentrace_format	Fri Mar 27 10:54:08 2009 +0900
    87.2 +++ b/tools/xentrace/xentrace_format	Fri Mar 27 11:07:11 2009 +0900
    87.3 @@ -81,7 +81,11 @@ signal.signal(signal.SIGINT,  sighand)
    87.4  
    87.5  interrupted = 0
    87.6  
    87.7 -defs = read_defs(arg[0])
    87.8 +try:
    87.9 +    defs = read_defs(arg[0])
   87.10 +except IOError, exn:
   87.11 +    print exn
   87.12 +    sys.exit(1)
   87.13  
   87.14  # structure of trace record (as output by xentrace):
   87.15  # HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I) D6(I) D7(I)
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/unmodified_drivers/linux-2.6/compat-include/linux/scatterlist.h	Fri Mar 27 11:07:11 2009 +0900
    88.3 @@ -0,0 +1,10 @@
    88.4 +#ifndef _LINUX_SCATTERLIST_H
    88.5 +#define _LINUX_SCATTERLIST_H
    88.6 +
    88.7 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
    88.8 +#error "This version of Linux should not need compat linux/scatterlist.h"
    88.9 +#endif
   88.10 +
   88.11 +#include <asm/scatterlist.h>
   88.12 +
   88.13 +#endif /* _LINUX_SCATTERLIST_H */
    89.1 --- a/xen/arch/ia64/xen/hypercall.c	Fri Mar 27 10:54:08 2009 +0900
    89.2 +++ b/xen/arch/ia64/xen/hypercall.c	Fri Mar 27 11:07:11 2009 +0900
    89.3 @@ -674,6 +674,28 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
    89.4              break;
    89.5      }
    89.6  
    89.7 +    case PHYSDEVOP_manage_pci_add_ext: {
    89.8 +        struct physdev_manage_pci_ext manage_pci_ext;
    89.9 +        struct pci_dev_info pdev_info;
   89.10 +
   89.11 +        ret = -EPERM;
   89.12 +        if ( !IS_PRIV(current->domain) )
   89.13 +            break;
   89.14 +
   89.15 +        ret = -EFAULT;
   89.16 +        if ( copy_from_guest(&manage_pci_ext, arg, 1) != 0 )
   89.17 +            break;
   89.18 +
   89.19 +        pdev_info.is_extfn = manage_pci_ext.is_extfn;
   89.20 +        pdev_info.is_virtfn = manage_pci_ext.is_virtfn;
   89.21 +        pdev_info.physfn.bus = manage_pci_ext.physfn.bus;
   89.22 +        pdev_info.physfn.devfn = manage_pci_ext.physfn.devfn;
   89.23 +        ret = pci_add_device_ext(manage_pci_ext.bus,
   89.24 +                                 manage_pci_ext.devfn,
   89.25 +                                 &pdev_info);
   89.26 +            break;
   89.27 +    }
   89.28 +
   89.29      default:
   89.30          ret = -ENOSYS;
   89.31          printk("not implemented do_physdev_op: %d\n", cmd);
    90.1 --- a/xen/arch/x86/acpi/cpu_idle.c	Fri Mar 27 10:54:08 2009 +0900
    90.2 +++ b/xen/arch/x86/acpi/cpu_idle.c	Fri Mar 27 11:07:11 2009 +0900
    90.3 @@ -167,25 +167,6 @@ static void acpi_idle_do_entry(struct ac
    90.4      }
    90.5  }
    90.6  
    90.7 -static inline void acpi_idle_update_bm_rld(struct acpi_processor_power *power,
    90.8 -                                           struct acpi_processor_cx *target)
    90.9 -{
   90.10 -    if ( !power->flags.bm_check )
   90.11 -        return;
   90.12 -
   90.13 -    if ( power->flags.bm_rld_set && target->type != ACPI_STATE_C3 )
   90.14 -    {
   90.15 -        acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
   90.16 -        power->flags.bm_rld_set = 0;
   90.17 -    }
   90.18 -
   90.19 -    if ( !power->flags.bm_rld_set && target->type == ACPI_STATE_C3 )
   90.20 -    {
   90.21 -        acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
   90.22 -        power->flags.bm_rld_set = 1;
   90.23 -    }
   90.24 -}
   90.25 -
   90.26  static int acpi_idle_bm_check(void)
   90.27  {
   90.28      u32 bm_status = 0;
   90.29 @@ -239,15 +220,9 @@ static void acpi_processor_idle(void)
   90.30      if ( !cx )
   90.31      {
   90.32          if ( pm_idle_save )
   90.33 -        {
   90.34 -            printk(XENLOG_DEBUG "call pm_idle_save()\n");
   90.35              pm_idle_save();
   90.36 -        }
   90.37          else
   90.38 -        {
   90.39 -            printk(XENLOG_DEBUG "call acpi_safe_halt()\n");
   90.40              acpi_safe_halt();
   90.41 -        }
   90.42          return;
   90.43      }
   90.44  
   90.45 @@ -258,24 +233,22 @@ static void acpi_processor_idle(void)
   90.46       * ------
   90.47       * Invoke the current Cx state to put the processor to sleep.
   90.48       */
   90.49 -    acpi_idle_update_bm_rld(power, cx);
   90.50 -
   90.51      switch ( cx->type )
   90.52      {
   90.53      case ACPI_STATE_C1:
   90.54      case ACPI_STATE_C2:
   90.55          if ( cx->type == ACPI_STATE_C1 || local_apic_timer_c2_ok )
   90.56          {
   90.57 -            /* Trace cpu idle entry */
   90.58 -            TRACE_1D(TRC_PM_IDLE_ENTRY, cx->idx);
   90.59              /* Get start time (ticks) */
   90.60              t1 = inl(pmtmr_ioport);
   90.61 +            /* Trace cpu idle entry */
   90.62 +            TRACE_2D(TRC_PM_IDLE_ENTRY, cx->idx, t1);
   90.63              /* Invoke C2 */
   90.64              acpi_idle_do_entry(cx);
   90.65              /* Get end time (ticks) */
   90.66              t2 = inl(pmtmr_ioport);
   90.67              /* Trace cpu idle exit */
   90.68 -            TRACE_1D(TRC_PM_IDLE_EXIT, cx->idx);
   90.69 +            TRACE_2D(TRC_PM_IDLE_EXIT, cx->idx, t2);
   90.70  
   90.71              /* Re-enable interrupts */
   90.72              local_irq_enable();
   90.73 @@ -314,8 +287,6 @@ static void acpi_processor_idle(void)
   90.74              ACPI_FLUSH_CPU_CACHE();
   90.75          }
   90.76  
   90.77 -        /* Trace cpu idle entry */
   90.78 -        TRACE_1D(TRC_PM_IDLE_ENTRY, cx->idx);
   90.79          /*
   90.80           * Before invoking C3, be aware that TSC/APIC timer may be 
   90.81           * stopped by H/W. Without carefully handling of TSC/APIC stop issues,
   90.82 @@ -326,6 +297,8 @@ static void acpi_processor_idle(void)
   90.83  
   90.84          /* Get start time (ticks) */
   90.85          t1 = inl(pmtmr_ioport);
   90.86 +        /* Trace cpu idle entry */
   90.87 +        TRACE_2D(TRC_PM_IDLE_ENTRY, cx->idx, t1);
   90.88          /* Invoke C3 */
   90.89          acpi_idle_do_entry(cx);
   90.90          /* Get end time (ticks) */
   90.91 @@ -334,7 +307,7 @@ static void acpi_processor_idle(void)
   90.92          /* recovering TSC */
   90.93          cstate_restore_tsc();
   90.94          /* Trace cpu idle exit */
   90.95 -        TRACE_1D(TRC_PM_IDLE_EXIT, cx->idx);
   90.96 +        TRACE_2D(TRC_PM_IDLE_EXIT, cx->idx, t2);
   90.97  
   90.98          if ( power->flags.bm_check && power->flags.bm_control )
   90.99          {
  90.100 @@ -491,12 +464,22 @@ static void acpi_processor_power_init_bm
  90.101      else if ( c->x86_vendor == X86_VENDOR_INTEL )
  90.102      {
  90.103          /*
  90.104 -         * Today all CPUs that support C3 share cache.
  90.105 -         * TBD: This needs to look at cache shared map, once
  90.106 -         * multi-core detection patch makes to the base.
  90.107 +         * Today all MP CPUs that support C3 share cache.
  90.108 +         * And caches should not be flushed by software while
  90.109 +         * entering C3 type state.
  90.110           */
  90.111          flags->bm_check = 1;
  90.112      }
  90.113 +
  90.114 +    /*
  90.115 +     * On all recent platforms, ARB_DISABLE is a nop.
  90.116 +     * So, set bm_control to zero to indicate that ARB_DISABLE
  90.117 +     * is not required while entering C3 type state on
  90.118 +     * P4, Core and beyond CPUs
  90.119 +     */
  90.120 +    if ( c->x86_vendor == X86_VENDOR_INTEL &&
  90.121 +        (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 14)) )
  90.122 +            flags->bm_control = 0;
  90.123  }
  90.124  
  90.125  #define VENDOR_INTEL                   (1)
  90.126 @@ -504,7 +487,8 @@ static void acpi_processor_power_init_bm
  90.127  
  90.128  static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx)
  90.129  {
  90.130 -    static int bm_check_flag;
  90.131 +    static int bm_check_flag = -1;
  90.132 +    static int bm_control_flag = -1;
  90.133  
  90.134      switch ( cx->reg.space_id )
  90.135      {
  90.136 @@ -550,15 +534,17 @@ static int check_cx(struct acpi_processo
  90.137          }
  90.138  
  90.139          /* All the logic here assumes flags.bm_check is same across all CPUs */
  90.140 -        if ( !bm_check_flag )
  90.141 +        if ( bm_check_flag == -1 )
  90.142          {
  90.143              /* Determine whether bm_check is needed based on CPU  */
  90.144              acpi_processor_power_init_bm_check(&(power->flags));
  90.145              bm_check_flag = power->flags.bm_check;
  90.146 +            bm_control_flag = power->flags.bm_control;
  90.147          }
  90.148          else
  90.149          {
  90.150              power->flags.bm_check = bm_check_flag;
  90.151 +            power->flags.bm_control = bm_control_flag;
  90.152          }
  90.153  
  90.154          if ( power->flags.bm_check )
  90.155 @@ -579,6 +565,15 @@ static int check_cx(struct acpi_processo
  90.156                          "C3 support without BM control\n"));
  90.157                  }
  90.158              }
  90.159 +            /*
  90.160 +             * On older chipsets, BM_RLD needs to be set
  90.161 +             * in order for Bus Master activity to wake the
  90.162 +             * system from C3.  Newer chipsets handle DMA
  90.163 +             * during C3 automatically and BM_RLD is a NOP.
  90.164 +             * In either case, the proper way to
  90.165 +             * handle BM_RLD is to set it and leave it set.
  90.166 +             */
  90.167 +            acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
  90.168          }
  90.169          else
  90.170          {
    91.1 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c	Fri Mar 27 10:54:08 2009 +0900
    91.2 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c	Fri Mar 27 11:07:11 2009 +0900
    91.3 @@ -232,6 +232,26 @@ static u32 get_cur_val(cpumask_t mask)
    91.4      return cmd.val;
    91.5  }
    91.6  
    91.7 +struct perf_pair {
    91.8 +    union {
    91.9 +        struct {
   91.10 +            uint32_t lo;
   91.11 +            uint32_t hi;
   91.12 +        } split;
   91.13 +        uint64_t whole;
   91.14 +    } aperf, mperf;
   91.15 +};
   91.16 +static DEFINE_PER_CPU(struct perf_pair, gov_perf_pair);
   91.17 +static DEFINE_PER_CPU(struct perf_pair, usr_perf_pair);
   91.18 +
   91.19 +static void read_measured_perf_ctrs(void *_readin)
   91.20 +{
   91.21 +    struct perf_pair *readin = _readin;
   91.22 +
   91.23 +    rdmsr(MSR_IA32_APERF, readin->aperf.split.lo, readin->aperf.split.hi);
   91.24 +    rdmsr(MSR_IA32_MPERF, readin->mperf.split.lo, readin->mperf.split.hi);
   91.25 +}
   91.26 +
   91.27  /*
   91.28   * Return the measured active (C0) frequency on this CPU since last call
   91.29   * to this function.
   91.30 @@ -245,40 +265,13 @@ static u32 get_cur_val(cpumask_t mask)
   91.31   * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
   91.32   * no meaning should be associated with absolute values of these MSRs.
   91.33   */
   91.34 -static void  __get_measured_perf(void *perf_percent)
   91.35 +static unsigned int get_measured_perf(unsigned int cpu, unsigned int flag)
   91.36  {
   91.37 -    unsigned int *ratio = perf_percent;
   91.38 -    union {
   91.39 -        struct {
   91.40 -            uint32_t lo;
   91.41 -            uint32_t hi;
   91.42 -        } split;
   91.43 -        uint64_t whole;
   91.44 -    } aperf_cur, mperf_cur;
   91.45 -
   91.46 -    rdmsr(MSR_IA32_APERF, aperf_cur.split.lo, aperf_cur.split.hi);
   91.47 -    rdmsr(MSR_IA32_MPERF, mperf_cur.split.lo, mperf_cur.split.hi);
   91.48 -
   91.49 -    wrmsr(MSR_IA32_APERF, 0,0);
   91.50 -    wrmsr(MSR_IA32_MPERF, 0,0);
   91.51 -
   91.52 -    if (unlikely(((unsigned long)(-1) / 100) < aperf_cur.whole)) {
   91.53 -        int shift_count = 7;
   91.54 -        aperf_cur.whole >>= shift_count;
   91.55 -        mperf_cur.whole >>= shift_count;
   91.56 -    }
   91.57 -
   91.58 -    if (aperf_cur.whole && mperf_cur.whole)
   91.59 -        *ratio = (aperf_cur.whole * 100) / mperf_cur.whole;
   91.60 -    else
   91.61 -        *ratio = 0;
   91.62 -}
   91.63 -
   91.64 -static unsigned int get_measured_perf(unsigned int cpu)
   91.65 -{
   91.66 -    struct cpufreq_policy *policy;
   91.67 +    struct cpufreq_policy *policy;    
   91.68 +    struct perf_pair readin, cur, *saved;
   91.69      unsigned int perf_percent;
   91.70      cpumask_t cpumask;
   91.71 +    unsigned int retval;
   91.72  
   91.73      if (!cpu_online(cpu))
   91.74          return 0;
   91.75 @@ -287,16 +280,80 @@ static unsigned int get_measured_perf(un
   91.76      if (!policy)
   91.77          return 0;
   91.78  
   91.79 -    /* Usually we take the short path (no IPI) for the sake of performance. */
   91.80 +    switch (flag)
   91.81 +    {
   91.82 +    case GOV_GETAVG:
   91.83 +    {
   91.84 +        saved = &per_cpu(gov_perf_pair, cpu);
   91.85 +        break;
   91.86 +    }
   91.87 +    case USR_GETAVG:
   91.88 +    {
   91.89 +        saved = &per_cpu(usr_perf_pair, cpu);
   91.90 +        break;
   91.91 +    }
   91.92 +    default:
   91.93 +        return 0;
   91.94 +    }
   91.95 +
   91.96      if (cpu == smp_processor_id()) {
   91.97 -        __get_measured_perf((void *)&perf_percent);
   91.98 +        read_measured_perf_ctrs((void *)&readin);
   91.99      } else {
  91.100          cpumask = cpumask_of_cpu(cpu);
  91.101 -        on_selected_cpus(cpumask, __get_measured_perf, 
  91.102 -                        (void *)&perf_percent,0,1);
  91.103 +        on_selected_cpus(cpumask, read_measured_perf_ctrs, 
  91.104 +                        (void *)&readin, 0, 1);
  91.105      }
  91.106  
  91.107 -    return drv_data[cpu]->max_freq * perf_percent / 100;
  91.108 +    cur.aperf.whole = readin.aperf.whole - saved->aperf.whole;
  91.109 +    cur.mperf.whole = readin.mperf.whole - saved->mperf.whole;
  91.110 +    saved->aperf.whole = readin.aperf.whole;
  91.111 +    saved->mperf.whole = readin.mperf.whole;
  91.112 +
  91.113 +#ifdef __i386__
  91.114 +    /*
  91.115 +     * We dont want to do 64 bit divide with 32 bit kernel
  91.116 +     * Get an approximate value. Return failure in case we cannot get
  91.117 +     * an approximate value.
  91.118 +     */
  91.119 +    if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) {
  91.120 +        int shift_count;
  91.121 +        uint32_t h;
  91.122 +
  91.123 +        h = max_t(uint32_t, cur.aperf.split.hi, cur.mperf.split.hi);
  91.124 +        shift_count = fls(h);
  91.125 +
  91.126 +        cur.aperf.whole >>= shift_count;
  91.127 +        cur.mperf.whole >>= shift_count;
  91.128 +    }
  91.129 +
  91.130 +    if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) {
  91.131 +        int shift_count = 7;
  91.132 +        cur.aperf.split.lo >>= shift_count;
  91.133 +        cur.mperf.split.lo >>= shift_count;
  91.134 +    }
  91.135 +
  91.136 +    if (cur.aperf.split.lo && cur.mperf.split.lo)
  91.137 +        perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo;
  91.138 +    else
  91.139 +        perf_percent = 0;
  91.140 +
  91.141 +#else
  91.142 +    if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) {
  91.143 +        int shift_count = 7;
  91.144 +        cur.aperf.whole >>= shift_count;
  91.145 +        cur.mperf.whole >>= shift_count;
  91.146 +    }
  91.147 +
  91.148 +    if (cur.aperf.whole && cur.mperf.whole)
  91.149 +        perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole;
  91.150 +    else
  91.151 +        perf_percent = 0;
  91.152 +
  91.153 +#endif
  91.154 +
  91.155 +    retval = drv_data[policy->cpu]->max_freq * perf_percent / 100;
  91.156 +
  91.157 +    return retval;
  91.158  }
  91.159  
  91.160  static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
    92.1 --- a/xen/arch/x86/acpi/power.c	Fri Mar 27 10:54:08 2009 +0900
    92.2 +++ b/xen/arch/x86/acpi/power.c	Fri Mar 27 11:07:11 2009 +0900
    92.3 @@ -44,16 +44,16 @@ void do_suspend_lowlevel(void);
    92.4  
    92.5  static int device_power_down(void)
    92.6  {
    92.7 -    iommu_suspend();
    92.8 -
    92.9      console_suspend();
   92.10  
   92.11      time_suspend();
   92.12  
   92.13      i8259A_suspend();
   92.14 -    
   92.15 +
   92.16      ioapic_suspend();
   92.17 -    
   92.18 +
   92.19 +    iommu_suspend();
   92.20 +
   92.21      lapic_suspend();
   92.22  
   92.23      return 0;
   92.24 @@ -62,16 +62,16 @@ static int device_power_down(void)
   92.25  static void device_power_up(void)
   92.26  {
   92.27      lapic_resume();
   92.28 -    
   92.29 +
   92.30 +    iommu_resume();
   92.31 +
   92.32      ioapic_resume();
   92.33  
   92.34      i8259A_resume();
   92.35 -    
   92.36 +
   92.37      time_resume();
   92.38  
   92.39      console_resume();
   92.40 -
   92.41 -    iommu_resume();
   92.42  }
   92.43  
   92.44  static void freeze_domains(void)
    93.1 --- a/xen/arch/x86/acpi/suspend.c	Fri Mar 27 10:54:08 2009 +0900
    93.2 +++ b/xen/arch/x86/acpi/suspend.c	Fri Mar 27 11:07:11 2009 +0900
    93.3 @@ -31,13 +31,9 @@ void save_rest_processor_state(void)
    93.4  
    93.5  void restore_rest_processor_state(void)
    93.6  {
    93.7 -    int cpu = smp_processor_id();
    93.8 -    struct tss_struct *t = &init_tss[cpu];
    93.9      struct vcpu *v = current;
   93.10  
   93.11 -    /* Rewriting the TSS desc is necessary to clear the Busy flag. */
   93.12 -    set_tss_desc(cpu, t);
   93.13 -    load_TR(cpu);
   93.14 +    load_TR();
   93.15  
   93.16  #if defined(CONFIG_X86_64)
   93.17      /* Recover syscall MSRs */
   93.18 @@ -47,7 +43,7 @@ void restore_rest_processor_state(void)
   93.19      wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);    
   93.20  #else /* !defined(CONFIG_X86_64) */
   93.21      if ( supervisor_mode_kernel && cpu_has_sep )
   93.22 -        wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0);
   93.23 +        wrmsr(MSR_IA32_SYSENTER_ESP, &init_tss[smp_processor_id()].esp1, 0);
   93.24  #endif
   93.25  
   93.26      /* Maybe load the debug registers. */
    94.1 --- a/xen/arch/x86/boot/build32.mk	Fri Mar 27 10:54:08 2009 +0900
    94.2 +++ b/xen/arch/x86/boot/build32.mk	Fri Mar 27 11:07:11 2009 +0900
    94.3 @@ -10,8 +10,9 @@ include $(XEN_ROOT)/Config.mk
    94.4  
    94.5  CFLAGS += -Werror -fno-builtin -msoft-float
    94.6  
    94.7 +# NB. awk invocation is a portable alternative to 'head -n -1'
    94.8  %.S: %.bin
    94.9 -	(od -v -t x $< | head -n -1 | \
   94.10 +	(od -v -t x $< | awk 'NR > 1 {print s} {s=$$0}' | \
   94.11  	sed 's/ /,0x/g' | sed 's/^[0-9]*,/ .long /') >$@
   94.12  
   94.13  %.bin: %.lnk
    95.1 --- a/xen/arch/x86/cpu/common.c	Fri Mar 27 10:54:08 2009 +0900
    95.2 +++ b/xen/arch/x86/cpu/common.c	Fri Mar 27 11:07:11 2009 +0900
    95.3 @@ -614,8 +614,7 @@ void __cpuinit cpu_init(void)
    95.4  	BUG_ON((get_stack_bottom() & 15) != 0);
    95.5  	t->rsp0 = get_stack_bottom();
    95.6  #endif
    95.7 -	set_tss_desc(cpu,t);
    95.8 -	load_TR(cpu);
    95.9 +	load_TR();
   95.10  	asm volatile ( "lldt %%ax" : : "a" (0) );
   95.11  
   95.12  	/* Clear all 6 debug registers: */
    96.1 --- a/xen/arch/x86/cpu/mcheck/Makefile	Fri Mar 27 10:54:08 2009 +0900
    96.2 +++ b/xen/arch/x86/cpu/mcheck/Makefile	Fri Mar 27 11:07:11 2009 +0900
    96.3 @@ -2,6 +2,7 @@ obj-y += amd_nonfatal.o
    96.4  obj-y += k7.o
    96.5  obj-y += amd_k8.o
    96.6  obj-y += amd_f10.o
    96.7 +obj-y += mctelem.o
    96.8  obj-y += mce.o
    96.9  obj-y += mce_intel.o
   96.10  obj-y += non-fatal.o
    97.1 --- a/xen/arch/x86/cpu/mcheck/amd_f10.c	Fri Mar 27 10:54:08 2009 +0900
    97.2 +++ b/xen/arch/x86/cpu/mcheck/amd_f10.c	Fri Mar 27 11:07:11 2009 +0900
    97.3 @@ -49,20 +49,21 @@
    97.4  #include "x86_mca.h"
    97.5  
    97.6  
    97.7 -static int amd_f10_handler(struct mc_info *mi, uint16_t bank, uint64_t status)
    97.8 +static enum mca_extinfo
    97.9 +amd_f10_handler(struct mc_info *mi, uint16_t bank, uint64_t status)
   97.10  {
   97.11  	struct mcinfo_extended mc_ext;
   97.12  
   97.13  	/* Family 0x10 introduced additional MSR that belong to the
   97.14  	 * northbridge bank (4). */
   97.15 -	if (bank != 4)
   97.16 -		return 0;
   97.17 +	if (mi == NULL || bank != 4)
   97.18 +		return MCA_EXTINFO_IGNORED;
   97.19  
   97.20  	if (!(status & MCi_STATUS_VAL))
   97.21 -		return 0;
   97.22 +		return MCA_EXTINFO_IGNORED;
   97.23  
   97.24  	if (!(status & MCi_STATUS_MISCV))
   97.25 -		return 0;
   97.26 +		return MCA_EXTINFO_IGNORED;
   97.27  
   97.28  	memset(&mc_ext, 0, sizeof(mc_ext));
   97.29  	mc_ext.common.type = MC_TYPE_EXTENDED;
   97.30 @@ -73,28 +74,30 @@ static int amd_f10_handler(struct mc_inf
   97.31  	mc_ext.mc_msr[1].reg = MSR_F10_MC4_MISC2;
   97.32  	mc_ext.mc_msr[2].reg = MSR_F10_MC4_MISC3;
   97.33  
   97.34 -	rdmsrl(MSR_F10_MC4_MISC1, mc_ext.mc_msr[0].value);
   97.35 -	rdmsrl(MSR_F10_MC4_MISC2, mc_ext.mc_msr[1].value);
   97.36 -	rdmsrl(MSR_F10_MC4_MISC3, mc_ext.mc_msr[2].value);
   97.37 +	mca_rdmsrl(MSR_F10_MC4_MISC1, mc_ext.mc_msr[0].value);
   97.38 +	mca_rdmsrl(MSR_F10_MC4_MISC2, mc_ext.mc_msr[1].value);
   97.39 +	mca_rdmsrl(MSR_F10_MC4_MISC3, mc_ext.mc_msr[2].value);
   97.40  	
   97.41  	x86_mcinfo_add(mi, &mc_ext);
   97.42 -	return 1;
   97.43 +	return MCA_EXTINFO_LOCAL;
   97.44  }
   97.45  
   97.46  
   97.47  extern void k8_machine_check(struct cpu_user_regs *regs, long error_code);
   97.48  
   97.49  /* AMD Family10 machine check */
   97.50 -void amd_f10_mcheck_init(struct cpuinfo_x86 *c) 
   97.51 +int amd_f10_mcheck_init(struct cpuinfo_x86 *c) 
   97.52  { 
   97.53  	uint64_t value;
   97.54  	uint32_t i;
   97.55  	int cpu_nr;
   97.56  
   97.57 -	machine_check_vector = k8_machine_check;
   97.58 -	mc_callback_bank_extended = amd_f10_handler;
   97.59 +	if (!cpu_has(c, X86_FEATURE_MCA))
   97.60 +		return 0;
   97.61 +
   97.62 +	x86_mce_vector_register(k8_machine_check);
   97.63 +	x86_mce_callback_register(amd_f10_handler);
   97.64  	cpu_nr = smp_processor_id();
   97.65 -	wmb();
   97.66  
   97.67  	rdmsrl(MSR_IA32_MCG_CAP, value);
   97.68  	if (value & MCG_CTL_P)	/* Control register present ? */
   97.69 @@ -104,18 +107,9 @@ void amd_f10_mcheck_init(struct cpuinfo_
   97.70  	for (i = 0; i < nr_mce_banks; i++) {
   97.71  		switch (i) {
   97.72  		case 4: /* Northbridge */
   97.73 -			/* Enable error reporting of all errors,
   97.74 -			 * enable error checking and
   97.75 -			 * disable sync flooding */
   97.76 -			wrmsrl(MSR_IA32_MC4_CTL, 0x02c3c008ffffffffULL);
   97.77 +			/* Enable error reporting of all errors */
   97.78 +			wrmsrl(MSR_IA32_MC4_CTL, 0xffffffffffffffffULL);
   97.79  			wrmsrl(MSR_IA32_MC4_STATUS, 0x0ULL);
   97.80 -
   97.81 -			/* XXX: We should write the value 0x1087821UL into
   97.82 -			 * to register F3x180 here, which sits in
   97.83 -			 * the PCI extended configuration space.
   97.84 -			 * Since this is not possible here, we can only hope,
   97.85 -			 * Dom0 is doing that.
   97.86 -			 */
   97.87  			break;
   97.88  
   97.89  		default:
   97.90 @@ -128,4 +122,5 @@ void amd_f10_mcheck_init(struct cpuinfo_
   97.91  
   97.92  	set_in_cr4(X86_CR4_MCE);
   97.93  	printk("CPU%i: AMD Family10h machine check reporting enabled.\n", cpu_nr);
   97.94 +	return 1;
   97.95  }
    98.1 --- a/xen/arch/x86/cpu/mcheck/amd_k8.c	Fri Mar 27 10:54:08 2009 +0900
    98.2 +++ b/xen/arch/x86/cpu/mcheck/amd_k8.c	Fri Mar 27 11:07:11 2009 +0900
    98.3 @@ -67,234 +67,27 @@
    98.4  #include <asm/msr.h>
    98.5  
    98.6  #include "mce.h"
    98.7 -#include "x86_mca.h"
    98.8  
    98.9  
   98.10  /* Machine Check Handler for AMD K8 family series */
   98.11  void k8_machine_check(struct cpu_user_regs *regs, long error_code)
   98.12  {
   98.13 -	struct vcpu *vcpu = current;
   98.14 -	struct domain *curdom;
   98.15 -	struct mc_info *mc_data;
   98.16 -	struct mcinfo_global mc_global;
   98.17 -	struct mcinfo_bank mc_info;
   98.18 -	uint64_t status, addrv, miscv, uc;
   98.19 -	uint32_t i;
   98.20 -	unsigned int cpu_nr;
   98.21 -	uint32_t xen_impacted = 0;
   98.22 -#define DOM_NORMAL	0
   98.23 -#define DOM0_TRAP	1
   98.24 -#define DOMU_TRAP	2
   98.25 -#define DOMU_KILLED	4
   98.26 -	uint32_t dom_state = DOM_NORMAL;
   98.27 -
   98.28 -	/* This handler runs as interrupt gate. So IPIs from the
   98.29 -	 * polling service routine are defered until we finished.
   98.30 -	 */
   98.31 -
   98.32 -        /* Disable interrupts for the _vcpu_. It may not re-scheduled to
   98.33 -	 * an other physical CPU or the impacted process in the guest
   98.34 -	 * continues running with corrupted data, otherwise. */
   98.35 -        vcpu_schedule_lock_irq(vcpu);
   98.36 -
   98.37 -	mc_data = x86_mcinfo_getptr();
   98.38 -	cpu_nr = smp_processor_id();
   98.39 -	BUG_ON(cpu_nr != vcpu->processor);
   98.40 -
   98.41 -	curdom = vcpu->domain;
   98.42 -
   98.43 -	memset(&mc_global, 0, sizeof(mc_global));
   98.44 -	mc_global.common.type = MC_TYPE_GLOBAL;
   98.45 -	mc_global.common.size = sizeof(mc_global);
   98.46 -
   98.47 -	mc_global.mc_domid = curdom->domain_id; /* impacted domain */
   98.48 -
   98.49 -	x86_mc_get_cpu_info(cpu_nr, &mc_global.mc_socketid,
   98.50 -	    &mc_global.mc_coreid, &mc_global.mc_core_threadid,
   98.51 -	    &mc_global.mc_apicid, NULL, NULL, NULL);
   98.52 -
   98.53 -	mc_global.mc_vcpuid = vcpu->vcpu_id; /* impacted vcpu */
   98.54 -	mc_global.mc_flags |= MC_FLAG_UNCORRECTABLE;
   98.55 -	rdmsrl(MSR_IA32_MCG_STATUS, mc_global.mc_gstatus);
   98.56 -
   98.57 -	/* Quick check, who is impacted */
   98.58 -	xen_impacted = is_idle_domain(curdom);
   98.59 -
   98.60 -	/* Dom0 */
   98.61 -	x86_mcinfo_clear(mc_data);
   98.62 -	x86_mcinfo_add(mc_data, &mc_global);
   98.63 -
   98.64 -	for (i = 0; i < nr_mce_banks; i++) {
   98.65 -		struct domain *d;
   98.66 -
   98.67 -		rdmsrl(MSR_IA32_MC0_STATUS + 4 * i, status);
   98.68 -
   98.69 -		if (!(status & MCi_STATUS_VAL))
   98.70 -			continue;
   98.71 -
   98.72 -		/* An error happened in this bank.
   98.73 -		 * This is expected to be an uncorrectable error,
   98.74 -		 * since correctable errors get polled.
   98.75 -		 */
   98.76 -		uc = status & MCi_STATUS_UC;
   98.77 -
   98.78 -		memset(&mc_info, 0, sizeof(mc_info));
   98.79 -		mc_info.common.type = MC_TYPE_BANK;
   98.80 -		mc_info.common.size = sizeof(mc_info);
   98.81 -		mc_info.mc_bank = i;
   98.82 -		mc_info.mc_status = status;
   98.83 -
   98.84 -		addrv = 0;
   98.85 -		if (status & MCi_STATUS_ADDRV) {
   98.86 -			rdmsrl(MSR_IA32_MC0_ADDR + 4 * i, addrv);
   98.87 -			
   98.88 -			d = maddr_get_owner(addrv);
   98.89 -			if (d != NULL)
   98.90 -				mc_info.mc_domid = d->domain_id;
   98.91 -		}
   98.92 -
   98.93 -		miscv = 0;
   98.94 -		if (status & MCi_STATUS_MISCV)
   98.95 -			rdmsrl(MSR_IA32_MC0_MISC + 4 * i, miscv);
   98.96 -
   98.97 -		mc_info.mc_addr = addrv;
   98.98 -		mc_info.mc_misc = miscv;
   98.99 -
  98.100 -		x86_mcinfo_add(mc_data, &mc_info); /* Dom0 */
  98.101 -
  98.102 -		if (mc_callback_bank_extended)
  98.103 -			mc_callback_bank_extended(mc_data, i, status);
  98.104 -
  98.105 -		/* clear status */
  98.106 -		wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL);
  98.107 -		wmb();
  98.108 -		add_taint(TAINT_MACHINE_CHECK);
  98.109 -	}
  98.110 -
  98.111 -	status = mc_global.mc_gstatus;
  98.112 -
  98.113 -	/* clear MCIP or cpu enters shutdown state
  98.114 -	 * in case another MCE occurs. */
  98.115 -	status &= ~MCG_STATUS_MCIP;
  98.116 -	wrmsrl(MSR_IA32_MCG_STATUS, status);
  98.117 -	wmb();
  98.118 -
  98.119 -	/* For the details see the discussion "MCE/MCA concept" on xen-devel.
  98.120 -	 * The thread started here:
  98.121 -	 * http://lists.xensource.com/archives/html/xen-devel/2007-05/msg01015.html
  98.122 -	 */
  98.123 -
  98.124 -	/* MCG_STATUS_RIPV: 
  98.125 -	 * When this bit is not set, then the instruction pointer onto the stack
  98.126 -	 * to resume at is not valid. If xen is interrupted, then we panic anyway
  98.127 -	 * right below. Otherwise it is up to the guest to figure out if 
  98.128 -	 * guest kernel or guest userland is affected and should kill either
  98.129 -	 * itself or the affected process.
  98.130 -	 */
  98.131 -
  98.132 -	/* MCG_STATUS_EIPV:
  98.133 -	 * Evaluation of EIPV is the job of the guest.
  98.134 -	 */
  98.135 -
  98.136 -	if (xen_impacted) {
  98.137 -		/* Now we are going to panic anyway. Allow interrupts, so that
  98.138 -		 * printk on serial console can work. */
  98.139 -		vcpu_schedule_unlock_irq(vcpu);
  98.140 -
  98.141 -		/* Uh, that means, machine check exception
  98.142 -		 * inside Xen occured. */
  98.143 -		printk("Machine check exception occured in Xen.\n");
  98.144 -
  98.145 -		/* if MCG_STATUS_EIPV indicates, the IP on the stack is related
  98.146 -		 * to the error then it makes sense to print a stack trace.
  98.147 -		 * That can be useful for more detailed error analysis and/or
  98.148 -		 * error case studies to figure out, if we can clear
  98.149 -		 * xen_impacted and kill a DomU instead
  98.150 -		 * (i.e. if a guest only control structure is affected, but then
  98.151 -		 * we must ensure the bad pages are not re-used again).
  98.152 -		 */
  98.153 -		if (status & MCG_STATUS_EIPV) {
  98.154 -			printk("MCE: Instruction Pointer is related to the error. "
  98.155 -				"Therefore, print the execution state.\n");
  98.156 -			show_execution_state(regs);
  98.157 -		}
  98.158 -		x86_mcinfo_dump(mc_data);
  98.159 -		mc_panic("End of MCE. Use mcelog to decode above error codes.\n");
  98.160 -	}
  98.161 -
  98.162 -	/* If Dom0 registered a machine check handler, which is only possible
  98.163 -	 * with a PV MCA driver, then ... */
  98.164 -	if ( guest_has_trap_callback(dom0, 0, TRAP_machine_check) ) {
  98.165 -		dom_state = DOM0_TRAP;
  98.166 -
  98.167 -		/* ... deliver machine check trap to Dom0. */
  98.168 -		send_guest_trap(dom0, 0, TRAP_machine_check);
  98.169 -
  98.170 -		/* Xen may tell Dom0 now to notify the DomU.
  98.171 -		 * But this will happen through a hypercall. */
  98.172 -	} else
  98.173 -		/* Dom0 did not register a machine check handler, but if DomU
  98.174 -		 * did so, then... */
  98.175 -                if ( guest_has_trap_callback(curdom, vcpu->vcpu_id, TRAP_machine_check) ) {
  98.176 -			dom_state = DOMU_TRAP;
  98.177 -
  98.178 -			/* ... deliver machine check trap to DomU */
  98.179 -			send_guest_trap(curdom, vcpu->vcpu_id, TRAP_machine_check);
  98.180 -	} else {
  98.181 -		/* hmm... noone feels responsible to handle the error.
  98.182 -		 * So, do a quick check if a DomU is impacted or not.
  98.183 -		 */
  98.184 -		if (curdom == dom0) {
  98.185 -			/* Dom0 is impacted. Since noone can't handle
  98.186 -			 * this error, panic! */
  98.187 -			x86_mcinfo_dump(mc_data);
  98.188 -			mc_panic("MCE occured in Dom0, which it can't handle\n");
  98.189 -
  98.190 -			/* UNREACHED */
  98.191 -		} else {
  98.192 -			dom_state = DOMU_KILLED;
  98.193 -
  98.194 -			/* Enable interrupts. This basically results in
  98.195 -			 * calling sti on the *physical* cpu. But after
  98.196 -			 * domain_crash() the vcpu pointer is invalid.
  98.197 -			 * Therefore, we must unlock the irqs before killing
  98.198 -			 * it. */
  98.199 -			vcpu_schedule_unlock_irq(vcpu);
  98.200 -
  98.201 -			/* DomU is impacted. Kill it and continue. */
  98.202 -			domain_crash(curdom);
  98.203 -		}
  98.204 -	}
  98.205 -
  98.206 -
  98.207 -	switch (dom_state) {
  98.208 -	case DOM0_TRAP:
  98.209 -	case DOMU_TRAP:
  98.210 -		/* Enable interrupts. */
  98.211 -		vcpu_schedule_unlock_irq(vcpu);
  98.212 -
  98.213 -		/* guest softirqs and event callbacks are scheduled
  98.214 -		 * immediately after this handler exits. */
  98.215 -		break;
  98.216 -	case DOMU_KILLED:
  98.217 -		/* Nothing to do here. */
  98.218 -		break;
  98.219 -	default:
  98.220 -		BUG();
  98.221 -	}
  98.222 +	mcheck_cmn_handler(regs, error_code, mca_allbanks);
  98.223  }
  98.224  
  98.225 -
  98.226  /* AMD K8 machine check */
  98.227 -void amd_k8_mcheck_init(struct cpuinfo_x86 *c)
  98.228 +int amd_k8_mcheck_init(struct cpuinfo_x86 *c)
  98.229  {
  98.230  	uint64_t value;
  98.231  	uint32_t i;
  98.232  	int cpu_nr;
  98.233  
  98.234 -	machine_check_vector = k8_machine_check;
  98.235 +	/* Check for PPro style MCA; our caller has confirmed MCE support. */
  98.236 +	if (!cpu_has(c, X86_FEATURE_MCA))
  98.237 +		return 0;
  98.238 +
  98.239 +	x86_mce_vector_register(k8_machine_check);
  98.240  	cpu_nr = smp_processor_id();
  98.241 -	wmb();
  98.242  
  98.243  	rdmsrl(MSR_IA32_MCG_CAP, value);
  98.244  	if (value & MCG_CTL_P)	/* Control register present ? */
  98.245 @@ -304,10 +97,8 @@ void amd_k8_mcheck_init(struct cpuinfo_x
  98.246  	for (i = 0; i < nr_mce_banks; i++) {
  98.247  		switch (i) {
  98.248  		case 4: /* Northbridge */
  98.249 -			/* Enable error reporting of all errors,
  98.250 -			 * enable error checking and
  98.251 -			 * disable sync flooding */
  98.252 -			wrmsrl(MSR_IA32_MC4_CTL, 0x02c3c008ffffffffULL);
  98.253 +			/* Enable error reporting of all errors */
  98.254 +			wrmsrl(MSR_IA32_MC4_CTL, 0xffffffffffffffffULL);
  98.255  			wrmsrl(MSR_IA32_MC4_STATUS, 0x0ULL);
  98.256  			break;
  98.257  
  98.258 @@ -321,4 +112,6 @@ void amd_k8_mcheck_init(struct cpuinfo_x
  98.259  
  98.260  	set_in_cr4(X86_CR4_MCE);
  98.261  	printk("CPU%i: AMD K8 machine check reporting enabled.\n", cpu_nr);
  98.262 +
  98.263 +	return 1;
  98.264  }
    99.1 --- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c	Fri Mar 27 10:54:08 2009 +0900
    99.2 +++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c	Fri Mar 27 11:07:11 2009 +0900
    99.3 @@ -58,22 +58,23 @@
    99.4  #include <xen/smp.h>
    99.5  #include <xen/timer.h>
    99.6  #include <xen/event.h>
    99.7 -#include <asm/processor.h> 
    99.8 +
    99.9 +#include <asm/processor.h>
   99.10  #include <asm/system.h>
   99.11  #include <asm/msr.h>
   99.12  
   99.13  #include "mce.h"
   99.14 -#include "x86_mca.h"
   99.15  
   99.16  static struct timer mce_timer;
   99.17  
   99.18 -#define MCE_PERIOD MILLISECS(15000)
   99.19 +#define MCE_PERIOD MILLISECS(10000)
   99.20  #define MCE_MIN    MILLISECS(2000)
   99.21  #define MCE_MAX    MILLISECS(30000)
   99.22  
   99.23  static s_time_t period = MCE_PERIOD;
   99.24  static int hw_threshold = 0;
   99.25  static int adjust = 0;
   99.26 +static int variable_period = 1;
   99.27  
   99.28  /* The polling service routine:
   99.29   * Collects information of correctable errors and notifies
   99.30 @@ -81,99 +82,46 @@ static int adjust = 0;
   99.31   */
   99.32  void mce_amd_checkregs(void *info)
   99.33  {
   99.34 -	struct vcpu *vcpu = current;
   99.35 -	struct mc_info *mc_data;
   99.36 -	struct mcinfo_global mc_global;
   99.37 -	struct mcinfo_bank mc_info;
   99.38 -	uint64_t status, addrv, miscv;
   99.39 -	unsigned int i;
   99.40 +	mctelem_cookie_t mctc;
   99.41 +	struct mca_summary bs;
   99.42  	unsigned int event_enabled;
   99.43 -	unsigned int cpu_nr;
   99.44 -	int error_found;
   99.45 -
   99.46 -	/* We don't need a slot yet. Only allocate one on error. */
   99.47 -	mc_data = NULL;
   99.48 -
   99.49 -	cpu_nr = smp_processor_id();
   99.50 -	BUG_ON(cpu_nr != vcpu->processor);
   99.51 -	event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA);
   99.52 -	error_found = 0;
   99.53 -
   99.54 -	memset(&mc_global, 0, sizeof(mc_global));
   99.55 -	mc_global.common.type = MC_TYPE_GLOBAL;
   99.56 -	mc_global.common.size = sizeof(mc_global);
   99.57 -
   99.58 -	mc_global.mc_domid = vcpu->domain->domain_id; /* impacted domain */
   99.59 -	mc_global.mc_vcpuid = vcpu->vcpu_id; /* impacted vcpu */
   99.60 -
   99.61 -	x86_mc_get_cpu_info(cpu_nr, &mc_global.mc_socketid,
   99.62 -	    &mc_global.mc_coreid, &mc_global.mc_core_threadid,
   99.63 -	    &mc_global.mc_apicid, NULL, NULL, NULL);
   99.64 -
   99.65 -	mc_global.mc_flags |= MC_FLAG_CORRECTABLE;
   99.66 -	rdmsrl(MSR_IA32_MCG_STATUS, mc_global.mc_gstatus);
   99.67 -
   99.68 -	for (i = 0; i < nr_mce_banks; i++) {
   99.69 -		struct domain *d;
   99.70 -
   99.71 -		rdmsrl(MSR_IA32_MC0_STATUS + i * 4, status);
   99.72 -
   99.73 -		if (!(status & MCi_STATUS_VAL))
   99.74 -			continue;
   99.75  
   99.76 -		if (mc_data == NULL) {
   99.77 -			/* Now we need a slot to fill in error telemetry. */
   99.78 -			mc_data = x86_mcinfo_getptr();
   99.79 -			BUG_ON(mc_data == NULL);
   99.80 -			x86_mcinfo_clear(mc_data);
   99.81 -			x86_mcinfo_add(mc_data, &mc_global);
   99.82 -		}
   99.83 -
   99.84 -		memset(&mc_info, 0, sizeof(mc_info));
   99.85 -		mc_info.common.type = MC_TYPE_BANK;
   99.86 -		mc_info.common.size = sizeof(mc_info);
   99.87 -		mc_info.mc_bank = i;
   99.88 -		mc_info.mc_status = status;
   99.89 -
   99.90 -		/* Increase polling frequency */
   99.91 -		error_found = 1;
   99.92 +	mctc = mcheck_mca_logout(MCA_POLLER, mca_allbanks, &bs);
   99.93  
   99.94 -		addrv = 0;
   99.95 -		if (status & MCi_STATUS_ADDRV) {
   99.96 -			rdmsrl(MSR_IA32_MC0_ADDR + i * 4, addrv);
   99.97 -
   99.98 -			d = maddr_get_owner(addrv);
   99.99 -			if (d != NULL)
  99.100 -				mc_info.mc_domid = d->domain_id;
  99.101 -		}
  99.102 +	event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA);
  99.103  
  99.104 -		miscv = 0;
  99.105 -		if (status & MCi_STATUS_MISCV)
  99.106 -			rdmsrl(MSR_IA32_MC0_MISC + i * 4, miscv);
  99.107 +	if (bs.errcnt && mctc != NULL) {
  99.108 +		static uint64_t dumpcount = 0;
  99.109  
  99.110 -		mc_info.mc_addr = addrv;
  99.111 -		mc_info.mc_misc = miscv;
  99.112 -		x86_mcinfo_add(mc_data, &mc_info);
  99.113 +		/* If Dom0 enabled the VIRQ_MCA event, then notify it.
  99.114 +		 * Otherwise, if dom0 has had plenty of time to register
  99.115 +		 * the virq handler but still hasn't then dump telemetry
  99.116 +		 * to the Xen console.  The call count may be incremented
  99.117 +		 * on multiple cpus at once and is indicative only - just
  99.118 +		 * a simple-minded attempt to avoid spamming the console
  99.119 +		 * for corrected errors in early startup. */
  99.120  
  99.121 -		if (mc_callback_bank_extended)
  99.122 -			mc_callback_bank_extended(mc_data, i, status);
  99.123 -
  99.124 -		/* clear status */
  99.125 -		wrmsrl(MSR_IA32_MC0_STATUS + i * 4, 0x0ULL);
  99.126 -		wmb();
  99.127 +		if (event_enabled) {
  99.128 +			mctelem_commit(mctc);
  99.129 +			send_guest_global_virq(dom0, VIRQ_MCA);
  99.130 +		} else if (++dumpcount >= 10) {
  99.131 +			x86_mcinfo_dump((struct mc_info *)mctelem_dataptr(mctc));
  99.132 +			mctelem_dismiss(mctc);
  99.133 +		} else {
  99.134 +			mctelem_dismiss(mctc);
  99.135 +		}
  99.136 +		
  99.137 +	} else if (mctc != NULL) {
  99.138 +		mctelem_dismiss(mctc);
  99.139  	}
  99.140  
  99.141 -	if (error_found > 0) {
  99.142 -		/* If Dom0 enabled the VIRQ_MCA event, then ... */
  99.143 -		if (event_enabled)
  99.144 -			/* ... notify it. */
  99.145 -			send_guest_global_virq(dom0, VIRQ_MCA);
  99.146 -		else
  99.147 -			/* ... or dump it */
  99.148 -			x86_mcinfo_dump(mc_data);
  99.149 -	}
  99.150 -
  99.151 -	adjust += error_found;
  99.152 +	/* adjust is global and all cpus may attempt to increment it without
  99.153 +	 * synchronisation, so they race and the final adjust count
  99.154 +	 * (number of cpus seeing any error) is approximate.  We can
  99.155 +	 * guarantee that if any cpu observes an error that the
  99.156 +	 * adjust count is at least 1. */
  99.157 +	if (bs.errcnt)
  99.158 +		adjust++;
  99.159  }
  99.160  
  99.161  /* polling service routine invoker:
  99.162 @@ -188,7 +136,7 @@ static void mce_amd_work_fn(void *data)
  99.163  	on_each_cpu(mce_amd_checkregs, data, 1, 1);
  99.164  
  99.165  	if (adjust > 0) {
  99.166 -		if ( !guest_enabled_event(dom0->vcpu[0], VIRQ_MCA) ) {
  99.167 +		if (!guest_enabled_event(dom0->vcpu[0], VIRQ_MCA) ) {
  99.168  			/* Dom0 did not enable VIRQ_MCA, so Xen is reporting. */
  99.169  			printk("MCE: polling routine found correctable error. "
  99.170  				" Use mcelog to parse above error output.\n");
  99.171 @@ -199,7 +147,7 @@ static void mce_amd_work_fn(void *data)
  99.172  		uint64_t value;
  99.173  		uint32_t counter;
  99.174  
  99.175 -		rdmsrl(MSR_IA32_MC4_MISC, value);
  99.176 +		mca_rdmsrl(MSR_IA32_MC4_MISC, value);
  99.177  		/* Only the error counter field is of interest
  99.178  		 * Bit field is described in AMD K8 BKDG chapter 6.4.5.5
  99.179  		 */
  99.180 @@ -224,24 +172,24 @@ static void mce_amd_work_fn(void *data)
  99.181  			value &= ~(0x60FFF00000000ULL);
  99.182  			/* Counter enable */
  99.183  			value |= (1ULL << 51);
  99.184 -			wrmsrl(MSR_IA32_MC4_MISC, value);
  99.185 +			mca_wrmsrl(MSR_IA32_MC4_MISC, value);
  99.186  			wmb();
  99.187  		}
  99.188  	}
  99.189  
  99.190 -	if (adjust > 0) {
  99.191 +	if (variable_period && adjust > 0) {
  99.192  		/* Increase polling frequency */
  99.193  		adjust++; /* adjust == 1 must have an effect */
  99.194  		period /= adjust;
  99.195 -	} else {
  99.196 +	} else if (variable_period) {
  99.197  		/* Decrease polling frequency */
  99.198  		period *= 2;
  99.199  	}
  99.200 -	if (period > MCE_MAX) {
  99.201 +	if (variable_period && period > MCE_MAX) {
  99.202  		/* limit: Poll at least every 30s */
  99.203  		period = MCE_MAX;
  99.204  	}
  99.205 -	if (period < MCE_MIN) {
  99.206 +	if (variable_period && period < MCE_MIN) {
  99.207  		/* limit: Poll every 2s.
  99.208  		 * When this is reached an uncorrectable error
  99.209  		 * is expected to happen, if Dom0 does nothing.
  99.210 @@ -262,7 +210,7 @@ void amd_nonfatal_mcheck_init(struct cpu
  99.211  
  99.212  	/* The threshold bitfields in MSR_IA32_MC4_MISC has
  99.213  	 * been introduced along with the SVME feature bit. */
  99.214 -	if (cpu_has(c, X86_FEATURE_SVME)) {
  99.215 +	if (variable_period && cpu_has(c, X86_FEATURE_SVME)) {
  99.216  		uint64_t value;
  99.217  
  99.218  		/* hw threshold registers present */
   100.1 --- a/xen/arch/x86/cpu/mcheck/k7.c	Fri Mar 27 10:54:08 2009 +0900
   100.2 +++ b/xen/arch/x86/cpu/mcheck/k7.c	Fri Mar 27 11:07:11 2009 +0900
   100.3 @@ -68,13 +68,16 @@ static fastcall void k7_machine_check(st
   100.4  
   100.5  
   100.6  /* AMD K7 machine check */
   100.7 -void amd_k7_mcheck_init(struct cpuinfo_x86 *c)
   100.8 +int amd_k7_mcheck_init(struct cpuinfo_x86 *c)
   100.9  {
  100.10  	u32 l, h;
  100.11  	int i;
  100.12  
  100.13 -	machine_check_vector = k7_machine_check;
  100.14 -	wmb();
  100.15 +	/* Check for PPro style MCA; our caller has confirmed MCE support. */
  100.16 +	if (!cpu_has(c, X86_FEATURE_MCA))
  100.17 +		return 0;
  100.18 +
  100.19 +	x86_mce_vector_register(k7_machine_check);
  100.20  
  100.21  	rdmsr (MSR_IA32_MCG_CAP, l, h);
  100.22  	if (l & (1<<8))	/* Control register present ? */
  100.23 @@ -92,4 +95,6 @@ void amd_k7_mcheck_init(struct cpuinfo_x
  100.24  	set_in_cr4 (X86_CR4_MCE);
  100.25  	printk (KERN_INFO "CPU%d: AMD K7 machine check reporting enabled.\n",
  100.26  		smp_processor_id());
  100.27 +
  100.28 +	return 1;
  100.29  }
   101.1 --- a/xen/arch/x86/cpu/mcheck/mce.c	Fri Mar 27 10:54:08 2009 +0900
   101.2 +++ b/xen/arch/x86/cpu/mcheck/mce.c	Fri Mar 27 11:07:11 2009 +0900
   101.3 @@ -10,104 +10,492 @@
   101.4  #include <xen/smp.h>
   101.5  #include <xen/errno.h>
   101.6  #include <xen/console.h>
   101.7 +#include <xen/sched.h>
   101.8 +#include <xen/sched-if.h>
   101.9 +#include <xen/cpumask.h>
  101.10 +#include <xen/event.h>
  101.11 +#include <xen/guest_access.h>
  101.12  
  101.13 -#include <asm/processor.h> 
  101.14 +#include <asm/processor.h>
  101.15  #include <asm/system.h>
  101.16 +#include <asm/msr.h>
  101.17  
  101.18  #include "mce.h"
  101.19 -#include "x86_mca.h"
  101.20  
  101.21  int mce_disabled = 0;
  101.22  unsigned int nr_mce_banks;
  101.23  
  101.24  EXPORT_SYMBOL_GPL(nr_mce_banks);	/* non-fatal.o */
  101.25  
  101.26 -/* XXX For now a fixed array is used. Later this should be changed
  101.27 - * to a dynamic allocated array with the size calculated in relation
  101.28 - * to physical cpus present in the machine.
  101.29 - * The more physical cpus are available, the more entries you need.
  101.30 - */
  101.31 -#define MAX_MCINFO	20
  101.32 -
  101.33 -struct mc_machine_notify {
  101.34 -	struct mc_info mc;
  101.35 -	uint32_t fetch_idx;
  101.36 -	uint32_t valid;
  101.37 -};
  101.38 -
  101.39 -struct mc_machine {
  101.40 -
  101.41 -	/* Array structure used for collecting machine check error telemetry. */
  101.42 -	struct mc_info mc[MAX_MCINFO];
  101.43 +static void intpose_init(void);
  101.44 +static void mcinfo_clear(struct mc_info *);
  101.45  
  101.46 -	/* We handle multiple machine check reports lockless by
  101.47 -	 * iterating through the array using the producer/consumer concept.
  101.48 -	 */
  101.49 -	/* Producer array index to fill with machine check error data.
  101.50 -	 * Index must be increased atomically. */
  101.51 -	uint32_t error_idx;
  101.52 -
  101.53 -	/* Consumer array index to fetch machine check error data from.
  101.54 -	 * Index must be increased atomically. */
  101.55 -	uint32_t fetch_idx;
  101.56 +#define	SEG_PL(segsel)			((segsel) & 0x3)
  101.57 +#define _MC_MSRINJ_F_REQ_HWCR_WREN	(1 << 16)
  101.58  
  101.59 -	/* Integer array holding the indeces of the mc array that allows
  101.60 -         * a Dom0 to notify a DomU to re-fetch the same machine check error
  101.61 -         * data. The notification and refetch also uses its own 
  101.62 -	 * producer/consumer mechanism, because Dom0 may decide to not report
  101.63 -	 * every error to the impacted DomU.
  101.64 -	 */
  101.65 -	struct mc_machine_notify notify[MAX_MCINFO];
  101.66 +#if 1	/* XXFM switch to 0 for putback */
  101.67  
  101.68 -	/* Array index to get fetch_idx from.
  101.69 -	 * Index must be increased atomically. */
  101.70 -	uint32_t notifyproducer_idx;
  101.71 -	uint32_t notifyconsumer_idx;
  101.72 -};
  101.73 +#define	x86_mcerr(str, err) _x86_mcerr(str, err)
  101.74  
  101.75 -/* Global variable with machine check information. */
  101.76 -struct mc_machine mc_data;
  101.77 +static int _x86_mcerr(const char *msg, int err)
  101.78 +{
  101.79 +	printk("x86_mcerr: %s, returning %d\n",
  101.80 +	    msg != NULL ? msg : "", err);
  101.81 +	return err;
  101.82 +}
  101.83 +#else
  101.84 +#define x86_mcerr(str,err)
  101.85 +#endif
  101.86 +
  101.87 +cpu_banks_t mca_allbanks;
  101.88  
  101.89  /* Handle unconfigured int18 (should never happen) */
  101.90  static void unexpected_machine_check(struct cpu_user_regs *regs, long error_code)
  101.91 -{	
  101.92 +{
  101.93  	printk(XENLOG_ERR "CPU#%d: Unexpected int18 (Machine Check).\n",
  101.94  		smp_processor_id());
  101.95  }
  101.96  
  101.97  
  101.98 +static x86_mce_vector_t _machine_check_vector = unexpected_machine_check;
  101.99 +
 101.100 +void x86_mce_vector_register(x86_mce_vector_t hdlr)
 101.101 +{
 101.102 +	_machine_check_vector = hdlr;
 101.103 +	wmb();
 101.104 +}
 101.105 +
 101.106  /* Call the installed machine check handler for this CPU setup. */
 101.107 -void (*machine_check_vector)(struct cpu_user_regs *regs, long error_code) = unexpected_machine_check;
 101.108 +
 101.109 +void machine_check_vector(struct cpu_user_regs *regs, long error_code)
 101.110 +{
 101.111 +	_machine_check_vector(regs, error_code);
 101.112 +}
 101.113  
 101.114  /* Init machine check callback handler
 101.115   * It is used to collect additional information provided by newer
 101.116   * CPU families/models without the need to duplicate the whole handler.
 101.117   * This avoids having many handlers doing almost nearly the same and each
 101.118   * with its own tweaks ands bugs. */
 101.119 -int (*mc_callback_bank_extended)(struct mc_info *, uint16_t, uint64_t) = NULL;
 101.120 +static x86_mce_callback_t mc_callback_bank_extended = NULL;
 101.121 +
 101.122 +void x86_mce_callback_register(x86_mce_callback_t cbfunc)
 101.123 +{
 101.124 +	mc_callback_bank_extended = cbfunc;
 101.125 +}
 101.126 +
 101.127 +/* Utility function to perform MCA bank telemetry readout and to push that
 101.128 + * telemetry towards an interested dom0 for logging and diagnosis.
 101.129 + * The caller - #MC handler or MCA poll function - must arrange that we
 101.130 + * do not migrate cpus. */
 101.131 +
 101.132 +/* XXFM Could add overflow counting? */
 101.133 +mctelem_cookie_t mcheck_mca_logout(enum mca_source who, cpu_banks_t bankmask,
 101.134 +    struct mca_summary *sp)
 101.135 +{
 101.136 +	struct vcpu *v = current;
 101.137 +	struct domain *d;
 101.138 +	uint64_t gstatus, status, addr, misc;
 101.139 +	struct mcinfo_global mcg;	/* on stack */
 101.140 +	struct mcinfo_common *mic;
 101.141 +	struct mcinfo_global *mig;	/* on stack */
 101.142 +	mctelem_cookie_t mctc = NULL;
 101.143 +	uint32_t uc = 0, pcc = 0;
 101.144 +	struct mc_info *mci = NULL;
 101.145 +	mctelem_class_t which = MC_URGENT;	/* XXXgcc */
 101.146 +	unsigned int cpu_nr;
 101.147 +	int errcnt = 0;
 101.148 +	int i;
 101.149 +	enum mca_extinfo cbret = MCA_EXTINFO_IGNORED;
 101.150 +
 101.151 +	cpu_nr = smp_processor_id();
 101.152 +	BUG_ON(cpu_nr != v->processor);
 101.153 +
 101.154 +	mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
 101.155 +
 101.156 +	memset(&mcg, 0, sizeof (mcg));
 101.157 +	mcg.common.type = MC_TYPE_GLOBAL;
 101.158 +	mcg.common.size = sizeof (mcg);
 101.159 +	if (v != NULL && ((d = v->domain) != NULL)) {
 101.160 +		mcg.mc_domid = d->domain_id;
 101.161 +		mcg.mc_vcpuid = v->vcpu_id;
 101.162 +	} else {
 101.163 +		mcg.mc_domid = -1;
 101.164 +		mcg.mc_vcpuid = -1;
 101.165 +	}
 101.166 +	mcg.mc_gstatus = gstatus;	/* MCG_STATUS */
 101.167 +
 101.168 +	switch (who) {
 101.169 +	case MCA_MCE_HANDLER:
 101.170 +		mcg.mc_flags = MC_FLAG_MCE;
 101.171 +		which = MC_URGENT;
 101.172 +		break;
 101.173 +
 101.174 +	case MCA_POLLER:
 101.175 +	case MCA_RESET:
 101.176 +		mcg.mc_flags = MC_FLAG_POLLED;
 101.177 +		which = MC_NONURGENT;
 101.178 +		break;
 101.179 +
 101.180 +	case MCA_CMCI_HANDLER:
 101.181 +		mcg.mc_flags = MC_FLAG_CMCI;
 101.182 +		which = MC_NONURGENT;
 101.183 +		break;
 101.184 +
 101.185 +	default:
 101.186 +		BUG();
 101.187 +	}
 101.188 +
 101.189 +	/* Retrieve detector information */
 101.190 +	x86_mc_get_cpu_info(cpu_nr, &mcg.mc_socketid,
 101.191 +	    &mcg.mc_coreid, &mcg.mc_core_threadid,
 101.192 +	    &mcg.mc_apicid, NULL, NULL, NULL);
 101.193 +
 101.194 +	for (i = 0; i < 32 && i < nr_mce_banks; i++) {
 101.195 +		struct mcinfo_bank mcb;		/* on stack */
 101.196 +
 101.197 +		/* Skip bank if corresponding bit in bankmask is clear */
 101.198 +		if (!test_bit(i, bankmask))
 101.199 +			continue;
 101.200 +
 101.201 +		mca_rdmsrl(MSR_IA32_MC0_STATUS + i * 4, status);
 101.202 +		if (!(status & MCi_STATUS_VAL))
 101.203 +			continue;	/* this bank has no valid telemetry */
 101.204 +
 101.205 +		/* If this is the first bank with valid MCA DATA, then
 101.206 +		 * try to reserve an entry from the urgent/nonurgent queue
 101.207 +		 * depending on whethere we are called from an exception or
 101.208 +		 * a poller;  this can fail (for example dom0 may not
 101.209 +		 * yet have consumed past telemetry). */
 101.210 +		if (errcnt == 0) {
 101.211 +			if ((mctc = mctelem_reserve(which)) != NULL) {
 101.212 +				mci = mctelem_dataptr(mctc);
 101.213 +				mcinfo_clear(mci);
 101.214 +			}
 101.215 +		}
 101.216 +
 101.217 +		memset(&mcb, 0, sizeof (mcb));
 101.218 +		mcb.common.type = MC_TYPE_BANK;
 101.219 +		mcb.common.size = sizeof (mcb);
 101.220 +		mcb.mc_bank = i;
 101.221 +		mcb.mc_status = status;
 101.222 +
 101.223 +		/* form a mask of which banks have logged uncorrected errors */
 101.224 +		if ((status & MCi_STATUS_UC) != 0)
 101.225 +			uc |= (1 << i);
 101.226 +
 101.227 +		/* likewise for those with processor context corrupt */
 101.228 +		if ((status & MCi_STATUS_PCC) != 0)
 101.229 +			pcc |= (1 << i);
 101.230 +
 101.231 +		addr = misc = 0;
 101.232 +
 101.233 +		if (status & MCi_STATUS_ADDRV) {
 101.234 +			mca_rdmsrl(MSR_IA32_MC0_ADDR + 4 * i, addr);
 101.235 +			d = maddr_get_owner(addr);
 101.236 +			if (d != NULL && (who == MCA_POLLER ||
 101.237 +			    who == MCA_CMCI_HANDLER))
 101.238 +				mcb.mc_domid = d->domain_id;
 101.239 +		}
 101.240 +
 101.241 +		if (status & MCi_STATUS_MISCV)
 101.242 +			mca_rdmsrl(MSR_IA32_MC0_MISC + 4 * i, misc);
 101.243 +
 101.244 +		mcb.mc_addr = addr;
 101.245 +		mcb.mc_misc = misc;
 101.246 +
 101.247 +		if (who == MCA_CMCI_HANDLER) {
 101.248 +			mca_rdmsrl(MSR_IA32_MC0_CTL2 + i, mcb.mc_ctrl2);
 101.249 +			rdtscll(mcb.mc_tsc);
 101.250 +		}
 101.251 +
 101.252 +		/* Increment the error count;  if this is the first bank
 101.253 +		 * with a valid error then add the global info to the mcinfo. */
 101.254 +		if (errcnt++ == 0 && mci != NULL)
 101.255 +			x86_mcinfo_add(mci, &mcg);
 101.256 +
 101.257 +		/* Add the bank data */
 101.258 +		if (mci != NULL)
 101.259 +			x86_mcinfo_add(mci, &mcb);
 101.260 +
 101.261 +		if (mc_callback_bank_extended && cbret != MCA_EXTINFO_GLOBAL) {
 101.262 +			cbret = mc_callback_bank_extended(mci, i, status);
 101.263 +		}
 101.264 +
 101.265 +		/* Clear status */
 101.266 +		mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL);
 101.267 +		wmb();
 101.268 +	}
 101.269 +
 101.270 +	if (mci != NULL && errcnt > 0) {
 101.271 +		x86_mcinfo_lookup(mic, mci, MC_TYPE_GLOBAL);
 101.272 +		mig = (struct mcinfo_global *)mic;
 101.273 +		if (pcc)
 101.274 +			mcg.mc_flags |= MC_FLAG_UNCORRECTABLE;
 101.275 +		else if (uc)
 101.276 +			mcg.mc_flags |= MC_FLAG_RECOVERABLE;
 101.277 +		else
 101.278 +			mcg.mc_flags |= MC_FLAG_CORRECTABLE;
 101.279 +	}
 101.280  
 101.281  
 101.282 -static void amd_mcheck_init(struct cpuinfo_x86 *ci)
 101.283 +	if (sp) {
 101.284 +		sp->errcnt = errcnt;
 101.285 +		sp->ripv = (gstatus & MCG_STATUS_RIPV) != 0;
 101.286 +		sp->eipv = (gstatus & MCG_STATUS_EIPV) != 0;
 101.287 +		sp->uc = uc;
 101.288 +		sp->pcc = pcc;
 101.289 +	}
 101.290 +
 101.291 +	return mci != NULL ? mctc : NULL;	/* may be NULL */
 101.292 +}
 101.293 +
 101.294 +#define DOM_NORMAL	0
 101.295 +#define DOM0_TRAP	1
 101.296 +#define DOMU_TRAP	2
 101.297 +#define DOMU_KILLED	4
 101.298 +
 101.299 +/* Shared #MC handler. */
 101.300 +void mcheck_cmn_handler(struct cpu_user_regs *regs, long error_code,
 101.301 +    cpu_banks_t bankmask)
 101.302  {
 101.303 +	int xen_state_lost, dom0_state_lost, domU_state_lost;
 101.304 +	struct vcpu *v = current;
 101.305 +	struct domain *curdom = v->domain;
 101.306 +	domid_t domid = curdom->domain_id;
 101.307 +	int ctx_xen, ctx_dom0, ctx_domU;
 101.308 +	uint32_t dom_state = DOM_NORMAL;
 101.309 +	mctelem_cookie_t mctc = NULL;
 101.310 +	struct mca_summary bs;
 101.311 +	struct mc_info *mci = NULL;
 101.312 +	int irqlocked = 0;
 101.313 +	uint64_t gstatus;
 101.314 +	int ripv;
 101.315 +
 101.316 +	/* This handler runs as interrupt gate. So IPIs from the
 101.317 +	 * polling service routine are defered until we're finished.
 101.318 +	 */
 101.319 +
 101.320 +	/* Disable interrupts for the _vcpu_. It may not re-scheduled to
 101.321 +	 * another physical CPU. */
 101.322 +	vcpu_schedule_lock_irq(v);
 101.323 +	irqlocked = 1;
 101.324 +
 101.325 +	/* Read global status;  if it does not indicate machine check
 101.326 +	 * in progress then bail as long as we have a valid ip to return to. */
 101.327 +	mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
 101.328 +	ripv = ((gstatus & MCG_STATUS_RIPV) != 0);
 101.329 +	if (!(gstatus & MCG_STATUS_MCIP) && ripv) {
 101.330 +		add_taint(TAINT_MACHINE_CHECK); /* questionable */
 101.331 +		vcpu_schedule_unlock_irq(v);
 101.332 +		irqlocked = 0;
 101.333 +		goto cmn_handler_done;
 101.334 +	}
 101.335 +
 101.336 +	/* Go and grab error telemetry.  We must choose whether to commit
 101.337 +	 * for logging or dismiss the cookie that is returned, and must not
 101.338 +	 * reference the cookie after that action.
 101.339 +	 */
 101.340 +	mctc = mcheck_mca_logout(MCA_MCE_HANDLER, bankmask, &bs);
 101.341 +	if (mctc != NULL)
 101.342 +		mci = (struct mc_info *)mctelem_dataptr(mctc);
 101.343 +
 101.344 +	/* Clear MCIP or another #MC will enter shutdown state */
 101.345 +	gstatus &= ~MCG_STATUS_MCIP;
 101.346 +	mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus);
 101.347 +	wmb();
 101.348 +
 101.349 +	/* If no valid errors and our stack is intact, we're done */
 101.350 +	if (ripv && bs.errcnt == 0) {
 101.351 +		vcpu_schedule_unlock_irq(v);
 101.352 +		irqlocked = 0;
 101.353 +		goto cmn_handler_done;
 101.354 +	}
 101.355 +
 101.356 +	if (bs.uc || bs.pcc)
 101.357 +		add_taint(TAINT_MACHINE_CHECK);
 101.358 +
 101.359 +	/* Machine check exceptions will usually be for UC and/or PCC errors,
 101.360 +	 * but it is possible to configure machine check for some classes
 101.361 +	 * of corrected error.
 101.362 +	 *
 101.363 +	 * UC errors could compromise any domain or the hypervisor
 101.364 +	 * itself - for example a cache writeback of modified data that
 101.365 +	 * turned out to be bad could be for data belonging to anyone, not
 101.366 +	 * just the current domain.  In the absence of known data poisoning
 101.367 +	 * to prevent consumption of such bad data in the system we regard
 101.368 +	 * all UC errors as terminal.  It may be possible to attempt some
 101.369 +	 * heuristics based on the address affected, which guests have
 101.370 +	 * mappings to that mfn etc.
 101.371 +	 *
 101.372 +	 * PCC errors apply to the current context.
 101.373 +	 *
 101.374 +	 * If MCG_STATUS indicates !RIPV then even a #MC that is not UC
 101.375 +	 * and not PCC is terminal - the return instruction pointer
 101.376 +	 * pushed onto the stack is bogus.  If the interrupt context is
 101.377 +	 * the hypervisor or dom0 the game is over, otherwise we can
 101.378 +	 * limit the impact to a single domU but only if we trampoline
 101.379 +	 * somewhere safely - we can't return and unwind the stack.
 101.380 +	 * Since there is no trampoline in place we will treat !RIPV
 101.381 +	 * as terminal for any context.
 101.382 +	 */
 101.383 +	ctx_xen = SEG_PL(regs->cs) == 0;
 101.384 +	ctx_dom0 = !ctx_xen && (domid == dom0->domain_id);
 101.385 +	ctx_domU = !ctx_xen && !ctx_dom0;
 101.386 +
 101.387 +	xen_state_lost = bs.uc != 0 || (ctx_xen && (bs.pcc || !ripv)) ||
 101.388 +	    !ripv;
 101.389 +	dom0_state_lost = bs.uc != 0 || (ctx_dom0 && (bs.pcc || !ripv));
 101.390 +	domU_state_lost = bs.uc != 0 || (ctx_domU && (bs.pcc || !ripv));
 101.391 +
 101.392 +	if (xen_state_lost) {
 101.393 +		/* Now we are going to panic anyway. Allow interrupts, so that
 101.394 +		 * printk on serial console can work. */
 101.395 +		vcpu_schedule_unlock_irq(v);
 101.396 +		irqlocked = 0;
 101.397 +
 101.398 +		printk("Terminal machine check exception occured in "
 101.399 +		    "hypervisor context.\n");
 101.400 +
 101.401 +		/* If MCG_STATUS_EIPV indicates, the IP on the stack is related
 101.402 +		 * to the error then it makes sense to print a stack trace.
 101.403 +		 * That can be useful for more detailed error analysis and/or
 101.404 +		 * error case studies to figure out, if we can clear
 101.405 +		 * xen_impacted and kill a DomU instead
 101.406 +		 * (i.e. if a guest only control structure is affected, but then
 101.407 +		 * we must ensure the bad pages are not re-used again).
 101.408 +		 */
 101.409 +		if (bs.eipv & MCG_STATUS_EIPV) {
 101.410 +			printk("MCE: Instruction Pointer is related to the "
 101.411 +			    "error, therefore print the execution state.\n");
 101.412 +			show_execution_state(regs);
 101.413 +		}
 101.414 +
 101.415 +		/* Commit the telemetry so that panic flow can find it. */
 101.416 +		if (mctc != NULL) {
 101.417 +			x86_mcinfo_dump(mci);
 101.418 +			mctelem_commit(mctc);
 101.419 +		}
 101.420 +		mc_panic("Hypervisor state lost due to machine check "
 101.421 +		    "exception.\n");
 101.422 +		/*NOTREACHED*/
 101.423 +	}
 101.424 +
 101.425 +	/*
 101.426 +	 * Xen hypervisor state is intact.  If dom0 state is lost then
 101.427 +	 * give it a chance to decide what to do if it has registered
 101.428 +	 * a handler for this event, otherwise panic.
 101.429 +	 *
 101.430 +	 * XXFM Could add some Solaris dom0 contract kill here?
 101.431 +	 */
 101.432 +	if (dom0_state_lost) {
 101.433 +		if (guest_has_trap_callback(dom0, 0, TRAP_machine_check)) {
 101.434 +			dom_state = DOM0_TRAP;
 101.435 +			send_guest_trap(dom0, 0, TRAP_machine_check);
 101.436 +			/* XXFM case of return with !ripv ??? */
 101.437 +		} else {
 101.438 +			/* Commit telemetry for panic flow. */
 101.439 +			if (mctc != NULL) {
 101.440 +				x86_mcinfo_dump(mci);
 101.441 +				mctelem_commit(mctc);
 101.442 +			}
 101.443 +			mc_panic("Dom0 state lost due to machine check "
 101.444 +			    "exception\n");
 101.445 +			/*NOTREACHED*/
 101.446 +		}
 101.447 +	}
 101.448 +
 101.449 +	/*
 101.450 +	 * If a domU has lost state then send it a trap if it has registered
 101.451 +	 * a handler, otherwise crash the domain.
 101.452 +	 * XXFM Revisit this functionality.
 101.453 +	 */
 101.454 +	if (domU_state_lost) {
 101.455 +		if (guest_has_trap_callback(v->domain, v->vcpu_id,
 101.456 +		    TRAP_machine_check)) {
 101.457 +			dom_state = DOMU_TRAP;
 101.458 +			send_guest_trap(curdom, v->vcpu_id,
 101.459 +			    TRAP_machine_check);
 101.460 +		} else {
 101.461 +			dom_state = DOMU_KILLED;
 101.462 +			/* Enable interrupts. This basically results in
 101.463 +			 * calling sti on the *physical* cpu. But after
 101.464 +			 * domain_crash() the vcpu pointer is invalid.
 101.465 +			 * Therefore, we must unlock the irqs before killing
 101.466 +			 * it. */
 101.467 +			vcpu_schedule_unlock_irq(v);
 101.468 +			irqlocked = 0;
 101.469 +
 101.470 +			/* DomU is impacted. Kill it and continue. */
 101.471 +			domain_crash(curdom);
 101.472 +		}
 101.473 +	}
 101.474 +
 101.475 +	switch (dom_state) {
 101.476 +	case DOM0_TRAP:
 101.477 +	case DOMU_TRAP:
 101.478 +		/* Enable interrupts. */
 101.479 +		vcpu_schedule_unlock_irq(v);
 101.480 +		irqlocked = 0;
 101.481 +
 101.482 +		/* guest softirqs and event callbacks are scheduled
 101.483 +		 * immediately after this handler exits. */
 101.484 +		break;
 101.485 +	case DOMU_KILLED:
 101.486 +		/* Nothing to do here. */
 101.487 +		break;
 101.488 +
 101.489 +	case DOM_NORMAL:
 101.490 +		vcpu_schedule_unlock_irq(v);
 101.491 +		irqlocked = 0;
 101.492 +		break;
 101.493 +	}
 101.494 +
 101.495 +cmn_handler_done:
 101.496 +	BUG_ON(irqlocked);
 101.497 +	BUG_ON(!ripv);
 101.498 +
 101.499 +	if (bs.errcnt) {
 101.500 +		/* Not panicing, so forward telemetry to dom0 now if it
 101.501 +		 * is interested. */
 101.502 +		if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
 101.503 +			if (mctc != NULL)
 101.504 +				mctelem_commit(mctc);
 101.505 +			send_guest_global_virq(dom0, VIRQ_MCA);
 101.506 +		} else {
 101.507 +			x86_mcinfo_dump(mci);
 101.508 +			if (mctc != NULL)
 101.509 +				mctelem_dismiss(mctc);
 101.510 +		}
 101.511 +	} else if (mctc != NULL) {
 101.512 +		mctelem_dismiss(mctc);
 101.513 +	}
 101.514 +}
 101.515 +
 101.516 +static int amd_mcheck_init(struct cpuinfo_x86 *ci)
 101.517 +{
 101.518 +	int rc = 0;
 101.519  
 101.520  	switch (ci->x86) {
 101.521  	case 6:
 101.522 -		amd_k7_mcheck_init(ci);
 101.523 +		rc = amd_k7_mcheck_init(ci);
 101.524  		break;
 101.525  
 101.526  	case 0xf:
 101.527 -		amd_k8_mcheck_init(ci);
 101.528 +		rc = amd_k8_mcheck_init(ci);
 101.529  		break;
 101.530  
 101.531  	case 0x10:
 101.532 -		amd_f10_mcheck_init(ci);
 101.533 +		rc = amd_f10_mcheck_init(ci);
 101.534  		break;
 101.535  
 101.536  	default:
 101.537  		/* Assume that machine check support is available.
 101.538  		 * The minimum provided support is at least the K8. */
 101.539 -		amd_k8_mcheck_init(ci);
 101.540 +		rc = amd_k8_mcheck_init(ci);
 101.541  	}
 101.542 +
 101.543 +	return rc;
 101.544  }
 101.545  
 101.546  /*check the existence of Machine Check*/
 101.547 @@ -116,50 +504,82 @@ int mce_available(struct cpuinfo_x86 *c)
 101.548  	return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA);
 101.549  }
 101.550  
 101.551 +/*
 101.552 + * Check if bank 0 is usable for MCE. It isn't for AMD K7,
 101.553 + * and Intel P6 family before model 0x1a.
 101.554 + */
 101.555 +int mce_firstbank(struct cpuinfo_x86 *c)
 101.556 +{
 101.557 +	if (c->x86 == 6) {
 101.558 +		if (c->x86_vendor == X86_VENDOR_AMD)
 101.559 +			return 1;
 101.560 +
 101.561 +		if (c->x86_vendor == X86_VENDOR_INTEL && c->x86_model < 0x1a)
 101.562 +			return 1;
 101.563 +	}
 101.564 +
 101.565 +	return 0;
 101.566 +}
 101.567 +
 101.568  /* This has to be run for each processor */
 101.569  void mcheck_init(struct cpuinfo_x86 *c)
 101.570  {
 101.571 +	int inited = 0, i;
 101.572 +
 101.573  	if (mce_disabled == 1) {
 101.574  		printk(XENLOG_INFO "MCE support disabled by bootparam\n");
 101.575  		return;
 101.576  	}
 101.577  
 101.578 +	for (i = 0; i < MAX_NR_BANKS; i++)
 101.579 +		set_bit(i,mca_allbanks);
 101.580 +
 101.581 +	/* Enforce at least MCE support in CPUID information.  Individual
 101.582 +	 * families may also need to enforce a check for MCA support. */
 101.583  	if (!cpu_has(c, X86_FEATURE_MCE)) {
 101.584  		printk(XENLOG_INFO "CPU%i: No machine check support available\n",
 101.585  			smp_processor_id());
 101.586  		return;
 101.587  	}
 101.588  
 101.589 -	memset(&mc_data, 0, sizeof(struct mc_machine));
 101.590 +	intpose_init();
 101.591 +	mctelem_init(sizeof (struct mc_info));
 101.592  
 101.593  	switch (c->x86_vendor) {
 101.594  	case X86_VENDOR_AMD:
 101.595 -		amd_mcheck_init(c);
 101.596 +		inited = amd_mcheck_init(c);
 101.597  		break;
 101.598  
 101.599  	case X86_VENDOR_INTEL:
 101.600 +		switch (c->x86) {
 101.601 +		case 5:
 101.602  #ifndef CONFIG_X86_64
 101.603 -		if (c->x86==5)
 101.604 -			intel_p5_mcheck_init(c);
 101.605 +			inited = intel_p5_mcheck_init(c);
 101.606  #endif
 101.607 -		/*If it is P6 or P4 family, including CORE 2 DUO series*/
 101.608 -		if (c->x86 == 6 || c->x86==15)
 101.609 -		{
 101.610 -			printk(KERN_DEBUG "MCE: Intel newly family MC Init\n");
 101.611 -			intel_mcheck_init(c);
 101.612 +			break;
 101.613 +
 101.614 +		case 6:
 101.615 +		case 15:
 101.616 +			inited = intel_mcheck_init(c);
 101.617 +			break;
 101.618  		}
 101.619  		break;
 101.620  
 101.621  #ifndef CONFIG_X86_64
 101.622  	case X86_VENDOR_CENTAUR:
 101.623 -		if (c->x86==5)
 101.624 -			winchip_mcheck_init(c);
 101.625 +		if (c->x86==5) {
 101.626 +			inited = winchip_mcheck_init(c);
 101.627 +		}
 101.628  		break;
 101.629  #endif
 101.630  
 101.631  	default:
 101.632  		break;
 101.633  	}
 101.634 +
 101.635 +	if (!inited)
 101.636 +		printk(XENLOG_INFO "CPU%i: No machine check initialization\n",
 101.637 +		    smp_processor_id());
 101.638  }
 101.639  
 101.640  
 101.641 @@ -176,191 +596,12 @@ static void __init mcheck_enable(char *s
 101.642  custom_param("nomce", mcheck_disable);
 101.643  custom_param("mce", mcheck_enable);
 101.644  
 101.645 -
 101.646 -#include <xen/guest_access.h>
 101.647 -#include <asm/traps.h>
 101.648 -
 101.649 -struct mc_info *x86_mcinfo_getptr(void)
 101.650 -{
 101.651 -	struct mc_info *mi;
 101.652 -	uint32_t entry, next;
 101.653 -
 101.654 -	for (;;) {
 101.655 -		entry = mc_data.error_idx;
 101.656 -		smp_rmb();
 101.657 -		next = entry + 1;
 101.658 -		if (cmpxchg(&mc_data.error_idx, entry, next) == entry)
 101.659 -			break;
 101.660 -	}
 101.661 -
 101.662 -	mi = &(mc_data.mc[(entry % MAX_MCINFO)]);
 101.663 -	BUG_ON(mc_data.error_idx < mc_data.fetch_idx);
 101.664 -
 101.665 -	return mi;
 101.666 -}
 101.667 -
 101.668 -static int x86_mcinfo_matches_guest(const struct mc_info *mi,
 101.669 -			const struct domain *d, const struct vcpu *v)
 101.670 -{
 101.671 -	struct mcinfo_common *mic;
 101.672 -	struct mcinfo_global *mig;
 101.673 -
 101.674 -	x86_mcinfo_lookup(mic, mi, MC_TYPE_GLOBAL);
 101.675 -	mig = (struct mcinfo_global *)mic;
 101.676 -	if (mig == NULL)
 101.677 -		return 0;
 101.678 -
 101.679 -	if (d->domain_id != mig->mc_domid)
 101.680 -		return 0;
 101.681 -
 101.682 -	if (v->vcpu_id != mig->mc_vcpuid)
 101.683 -		return 0;
 101.684 -
 101.685 -	return 1;
 101.686 -}
 101.687 -
 101.688 -
 101.689 -#define x86_mcinfo_mcdata(idx) (mc_data.mc[(idx % MAX_MCINFO)])
 101.690 -
 101.691 -static struct mc_info *x86_mcinfo_getfetchptr(uint32_t *fetch_idx,
 101.692 -				const struct domain *d, const struct vcpu *v)
 101.693 -{
 101.694 -	struct mc_info *mi;
 101.695 -
 101.696 -	/* This function is called from the fetch hypercall with
 101.697 -	 * the mc_lock spinlock held. Thus, no need for locking here.
 101.698 -	 */
 101.699 -	mi = &(x86_mcinfo_mcdata(mc_data.fetch_idx));
 101.700 -	if ((d != dom0) && !x86_mcinfo_matches_guest(mi, d, v)) {
 101.701 -		/* Bogus domU command detected. */
 101.702 -		*fetch_idx = 0;
 101.703 -		return NULL;
 101.704 -	}
 101.705 -
 101.706 -	*fetch_idx = mc_data.fetch_idx;
 101.707 -	mc_data.fetch_idx++;
 101.708 -	BUG_ON(mc_data.fetch_idx > mc_data.error_idx);
 101.709 -
 101.710 -	return mi;
 101.711 -}
 101.712 -
 101.713 -
 101.714 -static void x86_mcinfo_marknotified(struct xen_mc_notifydomain *mc_notifydomain)
 101.715 -{
 101.716 -	struct mc_machine_notify *mn;
 101.717 -	struct mcinfo_common *mic = NULL;
 101.718 -	struct mcinfo_global *mig;
 101.719 -	struct domain *d;
 101.720 -	int i;
 101.721 -
 101.722 -	/* This function is called from the notifier hypercall with
 101.723 -	 * the mc_notify_lock spinlock held. Thus, no need for locking here.
 101.724 -	 */
 101.725 -
 101.726 -	/* First invalidate entries for guests that disappeared after
 101.727 -	 * notification (e.g. shutdown/crash). This step prevents the
 101.728 -	 * notification array from filling up with stalling/leaking entries.
 101.729 -	 */
 101.730 -	for (i = mc_data.notifyconsumer_idx; i < mc_data.notifyproducer_idx; i++) {
 101.731 -		mn = &(mc_data.notify[(i % MAX_MCINFO)]);
 101.732 -		x86_mcinfo_lookup(mic, &mn->mc, MC_TYPE_GLOBAL);
 101.733 -		BUG_ON(mic == NULL);
 101.734 -		mig = (struct mcinfo_global *)mic;
 101.735 -		d = get_domain_by_id(mig->mc_domid);
 101.736 -		if (d == NULL) {
 101.737 -			/* Domain does not exist. */
 101.738 -			mn->valid = 0;
 101.739 -		}
 101.740 -		if ((!mn->valid) && (i == mc_data.notifyconsumer_idx))
 101.741 -			mc_data.notifyconsumer_idx++;
 101.742 -	}
 101.743 -
 101.744 -	/* Now put in the error telemetry. Since all error data fetchable
 101.745 -	 * by domUs are uncorrectable errors, they are very important.
 101.746 -	 * So we dump them before overriding them. When a guest takes that long,
 101.747 -	 * then we can assume something bad already happened (crash, hang, etc.)
 101.748 -	 */
 101.749 -	mn = &(mc_data.notify[(mc_data.notifyproducer_idx % MAX_MCINFO)]);
 101.750 -
 101.751 -	if (mn->valid) {
 101.752 -		struct mcinfo_common *mic = NULL;
 101.753 -		struct mcinfo_global *mig;
 101.754 -
 101.755 -		/* To not loose the information, we dump it. */
 101.756 -		x86_mcinfo_lookup(mic, &mn->mc, MC_TYPE_GLOBAL);
 101.757 -		BUG_ON(mic == NULL);
 101.758 -		mig = (struct mcinfo_global *)mic;
 101.759 -		printk(XENLOG_WARNING "Domain ID %u was notified by Dom0 to "
 101.760 -			"fetch machine check error telemetry. But Domain ID "
 101.761 -			"did not do that in time.\n",
 101.762 -			mig->mc_domid);
 101.763 -		x86_mcinfo_dump(&mn->mc);
 101.764 -	}
 101.765 -
 101.766 -	memcpy(&mn->mc, &(x86_mcinfo_mcdata(mc_notifydomain->fetch_idx)),
 101.767 -		sizeof(struct mc_info));
 101.768 -	mn->fetch_idx = mc_notifydomain->fetch_idx;
 101.769 -	mn->valid = 1;
 101.770 -
 101.771 -	mc_data.notifyproducer_idx++;
 101.772 -
 101.773 -	/* By design there can never be more notifies than machine check errors.
 101.774 -	 * If that ever happens, then we hit a bug. */
 101.775 -	BUG_ON(mc_data.notifyproducer_idx > mc_data.fetch_idx);
 101.776 -	BUG_ON(mc_data.notifyconsumer_idx > mc_data.notifyproducer_idx);
 101.777 -}
 101.778 -
 101.779 -static struct mc_info *x86_mcinfo_getnotifiedptr(uint32_t *fetch_idx,
 101.780 -				const struct domain *d, const struct vcpu *v)
 101.781 -{
 101.782 -	struct mc_machine_notify *mn = NULL;
 101.783 -	uint32_t i;
 101.784 -	int found;
 101.785 -
 101.786 -	/* This function is called from the fetch hypercall with
 101.787 -	 * the mc_notify_lock spinlock held. Thus, no need for locking here.
 101.788 -	 */
 101.789 -
 101.790 -	/* The notifier data is filled in the order guests get notified, but
 101.791 -	 * guests may fetch them in a different order. That's why we need
 101.792 -	 * the game with valid/invalid entries. */
 101.793 -	found = 0;
 101.794 -	for (i = mc_data.notifyconsumer_idx; i < mc_data.notifyproducer_idx; i++) {
 101.795 -		mn = &(mc_data.notify[(i % MAX_MCINFO)]);
 101.796 -		if (!mn->valid) {
 101.797 -			if (i == mc_data.notifyconsumer_idx)
 101.798 -				mc_data.notifyconsumer_idx++;
 101.799 -			continue;
 101.800 -		}
 101.801 -		if (x86_mcinfo_matches_guest(&mn->mc, d, v)) {
 101.802 -			found = 1;
 101.803 -			break;
 101.804 -		}
 101.805 -	}
 101.806 -
 101.807 -	if (!found) {
 101.808 -		/* This domain has never been notified. This must be
 101.809 -		 * a bogus domU command. */
 101.810 -		*fetch_idx = 0;
 101.811 -		return NULL;
 101.812 -	}
 101.813 -
 101.814 -	BUG_ON(mn == NULL);
 101.815 -	*fetch_idx = mn->fetch_idx;
 101.816 -	mn->valid = 0;
 101.817 -
 101.818 -	BUG_ON(mc_data.notifyconsumer_idx > mc_data.notifyproducer_idx);
 101.819 -	return &mn->mc;
 101.820 -}
 101.821 -
 101.822 -
 101.823 -void x86_mcinfo_clear(struct mc_info *mi)
 101.824 +static void mcinfo_clear(struct mc_info *mi)
 101.825  {
 101.826  	memset(mi, 0, sizeof(struct mc_info));
 101.827  	x86_mcinfo_nentries(mi) = 0;
 101.828  }
 101.829  
 101.830 -
 101.831  int x86_mcinfo_add(struct mc_info *mi, void *mcinfo)
 101.832  {
 101.833  	int i;
 101.834 @@ -380,7 +621,7 @@ int x86_mcinfo_add(struct mc_info *mi, v
 101.835  	end2 = (unsigned long)((uint8_t *)mic_index + mic->size);
 101.836  
 101.837  	if (end1 < end2)
 101.838 -		return -ENOSPC; /* No space. Can't add entry. */
 101.839 +		return x86_mcerr("mcinfo_add: no more sparc", -ENOSPC);
 101.840  
 101.841  	/* there's enough space. add entry. */
 101.842  	memcpy(mic_index, mic, mic->size);
 101.843 @@ -389,7 +630,6 @@ int x86_mcinfo_add(struct mc_info *mi, v
 101.844  	return 0;
 101.845  }
 101.846  
 101.847 -
 101.848  /* Dump machine check information in a format,
 101.849   * mcelog can parse. This is used only when
 101.850   * Dom0 does not take the notification. */
 101.851 @@ -404,7 +644,7 @@ void x86_mcinfo_dump(struct mc_info *mi)
 101.852  	if (mic == NULL)
 101.853  		return;
 101.854  	mc_global = (struct mcinfo_global *)mic;
 101.855 -	if (mc_global->mc_flags & MC_FLAG_UNCORRECTABLE) {
 101.856 +	if (mc_global->mc_flags & MC_FLAG_MCE) {
 101.857  		printk(XENLOG_WARNING
 101.858  			"CPU%d: Machine Check Exception: %16"PRIx64"\n",
 101.859  			mc_global->mc_coreid, mc_global->mc_gstatus);
 101.860 @@ -424,7 +664,7 @@ void x86_mcinfo_dump(struct mc_info *mi)
 101.861  			goto next;
 101.862  
 101.863  		mc_bank = (struct mcinfo_bank *)mic;
 101.864 -	
 101.865 +
 101.866  		printk(XENLOG_WARNING "Bank %d: %16"PRIx64,
 101.867  			mc_bank->mc_bank,
 101.868  			mc_bank->mc_status);
 101.869 @@ -441,8 +681,6 @@ next:
 101.870  	} while (1);
 101.871  }
 101.872  
 101.873 -
 101.874 -
 101.875  static void do_mc_get_cpu_info(void *v)
 101.876  {
 101.877  	int cpu = smp_processor_id();
 101.878 @@ -533,183 +771,394 @@ void x86_mc_get_cpu_info(unsigned cpu, u
 101.879  	}
 101.880  }
 101.881  
 101.882 +#define	INTPOSE_NENT	50
 101.883 +
 101.884 +static struct intpose_ent {
 101.885 +	unsigned  int cpu_nr;
 101.886 +	uint64_t msr;
 101.887 +	uint64_t val;
 101.888 +} intpose_arr[INTPOSE_NENT];
 101.889 +
 101.890 +static void intpose_init(void)
 101.891 +{
 101.892 +	static int done;
 101.893 +	int i;
 101.894 +
 101.895 +	if (done++ > 0)
 101.896 +		return;
 101.897 +
 101.898 +	for (i = 0; i < INTPOSE_NENT; i++) {
 101.899 +		intpose_arr[i].cpu_nr = -1;
 101.900 +	}
 101.901 +
 101.902 +}
 101.903 +
 101.904 +struct intpose_ent *intpose_lookup(unsigned int cpu_nr, uint64_t msr,
 101.905 +    uint64_t *valp)
 101.906 +{
 101.907 +	int i;
 101.908 +
 101.909 +	for (i = 0; i < INTPOSE_NENT; i++) {
 101.910 +		if (intpose_arr[i].cpu_nr == cpu_nr &&
 101.911 +		    intpose_arr[i].msr == msr) {
 101.912 +			if (valp != NULL)
 101.913 +				*valp = intpose_arr[i].val;
 101.914 +			return &intpose_arr[i];
 101.915 +		}
 101.916 +	}
 101.917 +
 101.918 +	return NULL;
 101.919 +}
 101.920 +
 101.921 +static void intpose_add(unsigned int cpu_nr, uint64_t msr, uint64_t val)
 101.922 +{
 101.923 +	struct intpose_ent *ent;
 101.924 +	int i;
 101.925 +
 101.926 +	if ((ent = intpose_lookup(cpu_nr, msr, NULL)) != NULL) {
 101.927 +		ent->val = val;
 101.928 +		return;
 101.929 +	}
 101.930 +
 101.931 +	for (i = 0, ent = &intpose_arr[0]; i < INTPOSE_NENT; i++, ent++) {
 101.932 +		if (ent->cpu_nr == -1) {
 101.933 +			ent->cpu_nr = cpu_nr;
 101.934 +			ent->msr = msr;
 101.935 +			ent->val = val;
 101.936 +			return;
 101.937 +		}
 101.938 +	}
 101.939 +
 101.940 +	printk("intpose_add: interpose array full - request dropped\n");
 101.941 +}
 101.942 +
 101.943 +void intpose_inval(unsigned int cpu_nr, uint64_t msr)
 101.944 +{
 101.945 +	struct intpose_ent *ent;
 101.946 +
 101.947 +	if ((ent = intpose_lookup(cpu_nr, msr, NULL)) != NULL) {
 101.948 +		ent->cpu_nr = -1;
 101.949 +	}
 101.950 +}
 101.951 +
 101.952 +#define	IS_MCA_BANKREG(r) \
 101.953 +    ((r) >= MSR_IA32_MC0_CTL && \
 101.954 +    (r) <= MSR_IA32_MC0_MISC + (nr_mce_banks - 1) * 4 && \
 101.955 +    ((r) - MSR_IA32_MC0_CTL) % 4 != 0)	/* excludes MCi_CTL */
 101.956 +
 101.957 +static int x86_mc_msrinject_verify(struct xen_mc_msrinject *mci)
 101.958 +{
 101.959 +	struct cpuinfo_x86 *c;
 101.960 +	int i, errs = 0;
 101.961 +
 101.962 +	c = &cpu_data[smp_processor_id()];
 101.963 +
 101.964 +	for (i = 0; i < mci->mcinj_count; i++) {
 101.965 +		uint64_t reg = mci->mcinj_msr[i].reg;
 101.966 +		const char *reason = NULL;
 101.967 +
 101.968 +		if (IS_MCA_BANKREG(reg)) {
 101.969 +			if (c->x86_vendor == X86_VENDOR_AMD) {
 101.970 +				/* On AMD we can se