direct-io.hg

changeset 10404:e74c47d073ee

merge with xen-unstable.hg
author awilliam@xenbuild.aw
date Tue Jun 13 12:12:24 2006 -0600 (2006-06-13)
parents b8f6089cbce3 912588576817
children db31c4e5e22f
files linux-2.6-xen-sparse/arch/ia64/Kconfig linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile linux-2.6-xen-sparse/arch/ia64/xen/drivers/README linux-2.6-xen-sparse/arch/ia64/xen/drivers/coreMakefile linux-2.6-xen-sparse/drivers/xen/blktap/Makefile linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c linux-2.6-xen-sparse/drivers/xen/blktap/common.h linux-2.6-xen-sparse/drivers/xen/blktap/interface.c linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c linux-2.6-xen-sparse/include/asm-ia64/page.h tools/libxc/xc_ia64_stubs.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/xensetup.c xen/include/public/arch-ia64.h
line diff
     1.1 --- a/buildconfigs/linux-defconfig_xen0_ia64	Tue Jun 13 09:00:32 2006 -0600
     1.2 +++ b/buildconfigs/linux-defconfig_xen0_ia64	Tue Jun 13 12:12:24 2006 -0600
     1.3 @@ -1529,14 +1529,12 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
     1.4  CONFIG_XEN_BACKEND=y
     1.5  # CONFIG_XEN_PCIDEV_BACKEND is not set
     1.6  CONFIG_XEN_BLKDEV_BACKEND=y
     1.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     1.8  CONFIG_XEN_NETDEV_BACKEND=y
     1.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    1.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    1.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    1.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    1.13  CONFIG_XEN_NETDEV_FRONTEND=y
    1.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    1.15  # CONFIG_XEN_SCRUB_PAGES is not set
    1.16  # CONFIG_XEN_DISABLE_SERIAL is not set
    1.17  CONFIG_XEN_SYSFS=y
     2.1 --- a/buildconfigs/linux-defconfig_xen0_x86_32	Tue Jun 13 09:00:32 2006 -0600
     2.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_32	Tue Jun 13 12:12:24 2006 -0600
     2.3 @@ -1322,14 +1322,12 @@ CONFIG_XEN_PCIDEV_BACKEND=y
     2.4  CONFIG_XEN_PCIDEV_BACKEND_PASS=y
     2.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     2.6  CONFIG_XEN_BLKDEV_BACKEND=y
     2.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     2.8  CONFIG_XEN_NETDEV_BACKEND=y
     2.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    2.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    2.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    2.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    2.13  CONFIG_XEN_NETDEV_FRONTEND=y
    2.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    2.15  CONFIG_XEN_SCRUB_PAGES=y
    2.16  CONFIG_XEN_DISABLE_SERIAL=y
    2.17  CONFIG_XEN_SYSFS=y
     3.1 --- a/buildconfigs/linux-defconfig_xen0_x86_64	Tue Jun 13 09:00:32 2006 -0600
     3.2 +++ b/buildconfigs/linux-defconfig_xen0_x86_64	Tue Jun 13 12:12:24 2006 -0600
     3.3 @@ -1263,14 +1263,12 @@ CONFIG_XEN_PCIDEV_BACKEND=y
     3.4  CONFIG_XEN_PCIDEV_BACKEND_PASS=y
     3.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     3.6  CONFIG_XEN_BLKDEV_BACKEND=y
     3.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     3.8  CONFIG_XEN_NETDEV_BACKEND=y
     3.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    3.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    3.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    3.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    3.13  CONFIG_XEN_NETDEV_FRONTEND=y
    3.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    3.15  CONFIG_XEN_SCRUB_PAGES=y
    3.16  CONFIG_XEN_DISABLE_SERIAL=y
    3.17  CONFIG_XEN_SYSFS=y
     4.1 --- a/buildconfigs/linux-defconfig_xen_ia64	Tue Jun 13 09:00:32 2006 -0600
     4.2 +++ b/buildconfigs/linux-defconfig_xen_ia64	Tue Jun 13 12:12:24 2006 -0600
     4.3 @@ -1535,14 +1535,12 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
     4.4  CONFIG_XEN_BACKEND=y
     4.5  # CONFIG_XEN_PCIDEV_BACKEND is not set
     4.6  CONFIG_XEN_BLKDEV_BACKEND=y
     4.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     4.8  CONFIG_XEN_NETDEV_BACKEND=y
     4.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    4.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    4.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    4.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    4.13  CONFIG_XEN_NETDEV_FRONTEND=y
    4.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    4.15  # CONFIG_XEN_SCRUB_PAGES is not set
    4.16  # CONFIG_XEN_DISABLE_SERIAL is not set
    4.17  CONFIG_XEN_SYSFS=y
     5.1 --- a/buildconfigs/linux-defconfig_xen_x86_32	Tue Jun 13 09:00:32 2006 -0600
     5.2 +++ b/buildconfigs/linux-defconfig_xen_x86_32	Tue Jun 13 12:12:24 2006 -0600
     5.3 @@ -3022,14 +3022,12 @@ CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
     5.4  # CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
     5.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     5.6  CONFIG_XEN_BLKDEV_BACKEND=y
     5.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     5.8  CONFIG_XEN_NETDEV_BACKEND=y
     5.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    5.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    5.11  # CONFIG_XEN_TPMDEV_BACKEND is not set
    5.12  CONFIG_XEN_BLKDEV_FRONTEND=y
    5.13  CONFIG_XEN_NETDEV_FRONTEND=y
    5.14 -# CONFIG_XEN_BLKDEV_TAP is not set
    5.15  CONFIG_XEN_SCRUB_PAGES=y
    5.16  CONFIG_XEN_DISABLE_SERIAL=y
    5.17  CONFIG_XEN_SYSFS=y
     6.1 --- a/buildconfigs/linux-defconfig_xen_x86_64	Tue Jun 13 09:00:32 2006 -0600
     6.2 +++ b/buildconfigs/linux-defconfig_xen_x86_64	Tue Jun 13 12:12:24 2006 -0600
     6.3 @@ -2854,7 +2854,6 @@ CONFIG_XEN_PCIDEV_BACKEND=m
     6.4  CONFIG_XEN_PCIDEV_BACKEND_PASS=y
     6.5  # CONFIG_XEN_PCIDEV_BE_DEBUG is not set
     6.6  CONFIG_XEN_BLKDEV_BACKEND=y
     6.7 -# CONFIG_XEN_BLKDEV_TAP_BE is not set
     6.8  CONFIG_XEN_NETDEV_BACKEND=y
     6.9  # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
    6.10  CONFIG_XEN_NETDEV_LOOPBACK=y
    6.11 @@ -2862,7 +2861,6 @@ CONFIG_XEN_TPMDEV_BACKEND=m
    6.12  # CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS is not set
    6.13  CONFIG_XEN_BLKDEV_FRONTEND=y
    6.14  CONFIG_XEN_NETDEV_FRONTEND=y
    6.15 -# CONFIG_XEN_BLKDEV_TAP is not set
    6.16  CONFIG_XEN_SCRUB_PAGES=y
    6.17  CONFIG_XEN_DISABLE_SERIAL=y
    6.18  CONFIG_XEN_SYSFS=y
     7.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Tue Jun 13 09:00:32 2006 -0600
     7.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S	Tue Jun 13 12:12:24 2006 -0600
     7.3 @@ -173,7 +173,7 @@ ENTRY(cpu_gdt_table)
     7.4  	.ascii	         "|pae_pgdir_above_4gb"
     7.5  	.ascii	         "|supervisor_mode_kernel"
     7.6  #ifdef CONFIG_X86_PAE
     7.7 -	.ascii	",PAE=yes"
     7.8 +	.ascii	",PAE=yes[extended-cr3]"
     7.9  #else
    7.10  	.ascii	",PAE=no"
    7.11  #endif
     8.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Tue Jun 13 09:00:32 2006 -0600
     8.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c	Tue Jun 13 12:12:24 2006 -0600
     8.3 @@ -1378,7 +1378,6 @@ legacy_init_iomem_resources(struct e820e
     8.4  		res->end = res->start + e820[i].size - 1;
     8.5  		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
     8.6  		request_resource(&iomem_resource, res);
     8.7 -#ifndef CONFIG_XEN
     8.8  		if (e820[i].type == E820_RAM) {
     8.9  			/*
    8.10  			 *  We don't know which RAM region contains kernel data,
    8.11 @@ -1391,7 +1390,6 @@ legacy_init_iomem_resources(struct e820e
    8.12  			request_resource(res, &crashk_res);
    8.13  #endif
    8.14  		}
    8.15 -#endif
    8.16  	}
    8.17  }
    8.18  
    8.19 @@ -1460,8 +1458,11 @@ static void __init register_memory(void)
    8.20  	int	      i;
    8.21  
    8.22  	/* Nothing to do if not running in dom0. */
    8.23 -	if (!(xen_start_info->flags & SIF_INITDOMAIN))
    8.24 +	if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
    8.25 +		legacy_init_iomem_resources(e820.map, e820.nr_map,
    8.26 +					    &code_resource, &data_resource);
    8.27  		return;
    8.28 +	}
    8.29  
    8.30  #ifdef CONFIG_XEN
    8.31  	machine_e820 = alloc_bootmem_low_pages(PAGE_SIZE);
    8.32 @@ -1698,11 +1699,10 @@ void __init setup_arch(char **cmdline_p)
    8.33  	init_mm.brk = (PFN_UP(__pa(xen_start_info->pt_base)) +
    8.34  		       xen_start_info->nr_pt_frames) << PAGE_SHIFT;
    8.35  
    8.36 -	/* XEN: This is nonsense: kernel may not even be contiguous in RAM. */
    8.37 -	/*code_resource.start = virt_to_phys(_text);*/
    8.38 -	/*code_resource.end = virt_to_phys(_etext)-1;*/
    8.39 -	/*data_resource.start = virt_to_phys(_etext);*/
    8.40 -	/*data_resource.end = virt_to_phys(_edata)-1;*/
    8.41 +	code_resource.start = virt_to_phys(_text);
    8.42 +	code_resource.end = virt_to_phys(_etext)-1;
    8.43 +	data_resource.start = virt_to_phys(_etext);
    8.44 +	data_resource.end = virt_to_phys(_edata)-1;
    8.45  
    8.46  	parse_cmdline_early(cmdline_p);
    8.47  
     9.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Tue Jun 13 09:00:32 2006 -0600
     9.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c	Tue Jun 13 12:12:24 2006 -0600
     9.3 @@ -47,6 +47,9 @@ EXPORT_SYMBOL(swiotlb);
     9.4   */
     9.5  #define IO_TLB_SHIFT 11
     9.6  
     9.7 +/* Width of DMA addresses in the IO TLB. 31 bits is an aacraid limitation. */
     9.8 +#define IO_TLB_DMA_BITS 31
     9.9 +
    9.10  static int swiotlb_force;
    9.11  static char *iotlb_virt_start;
    9.12  static unsigned long iotlb_nslabs;
    9.13 @@ -56,10 +59,16 @@ static unsigned long iotlb_nslabs;
    9.14   * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
    9.15   * API.
    9.16   */
    9.17 -static dma_addr_t iotlb_bus_start, iotlb_bus_end, iotlb_bus_mask;
    9.18 +static unsigned long iotlb_pfn_start, iotlb_pfn_end;
    9.19  
    9.20  /* Does the given dma address reside within the swiotlb aperture? */
    9.21 -#define in_swiotlb_aperture(a) (!(((a) ^ iotlb_bus_start) & iotlb_bus_mask))
    9.22 +static inline int in_swiotlb_aperture(dma_addr_t dev_addr)
    9.23 +{
    9.24 +	unsigned long pfn = mfn_to_local_pfn(dev_addr >> PAGE_SHIFT);
    9.25 +	return (pfn_valid(pfn)
    9.26 +		&& (pfn >= iotlb_pfn_start)
    9.27 +		&& (pfn < iotlb_pfn_end));
    9.28 +}
    9.29  
    9.30  /*
    9.31   * When the IOMMU overflows we return a fallback buffer. This sets the size.
    9.32 @@ -125,7 +134,6 @@ void
    9.33  swiotlb_init_with_default_size (size_t default_size)
    9.34  {
    9.35  	unsigned long i, bytes;
    9.36 -	int rc;
    9.37  
    9.38  	if (!iotlb_nslabs) {
    9.39  		iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
    9.40 @@ -146,10 +154,13 @@ swiotlb_init_with_default_size (size_t d
    9.41  		      "Use dom0_mem Xen boot parameter to reserve\n"
    9.42  		      "some DMA memory (e.g., dom0_mem=-128M).\n");
    9.43  
    9.44 -	/* Hardcode 31 address bits for now: aacraid limitation. */
    9.45 -	rc = xen_create_contiguous_region(
    9.46 -		(unsigned long)iotlb_virt_start, get_order(bytes), 31);
    9.47 -	BUG_ON(rc);
    9.48 +	for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE) {
    9.49 +		int rc = xen_create_contiguous_region(
    9.50 +			(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
    9.51 +			get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
    9.52 +			IO_TLB_DMA_BITS);
    9.53 +		BUG_ON(rc);
    9.54 +	}
    9.55  
    9.56  	/*
    9.57  	 * Allocate and initialize the free list array.  This array is used
    9.58 @@ -167,17 +178,13 @@ swiotlb_init_with_default_size (size_t d
    9.59  	 */
    9.60  	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
    9.61  
    9.62 -	iotlb_bus_start = virt_to_bus(iotlb_virt_start);
    9.63 -	iotlb_bus_end   = iotlb_bus_start + bytes;
    9.64 -	iotlb_bus_mask  = ~(dma_addr_t)(bytes - 1);
    9.65 +	iotlb_pfn_start = __pa(iotlb_virt_start) >> PAGE_SHIFT;
    9.66 +	iotlb_pfn_end   = iotlb_pfn_start + (bytes >> PAGE_SHIFT);
    9.67  
    9.68  	printk(KERN_INFO "Software IO TLB enabled: \n"
    9.69  	       " Aperture:     %lu megabytes\n"
    9.70 -	       " Bus range:    0x%016lx - 0x%016lx\n"
    9.71  	       " Kernel range: 0x%016lx - 0x%016lx\n",
    9.72  	       bytes >> 20,
    9.73 -	       (unsigned long)iotlb_bus_start,
    9.74 -	       (unsigned long)iotlb_bus_end,
    9.75  	       (unsigned long)iotlb_virt_start,
    9.76  	       (unsigned long)iotlb_virt_start + bytes);
    9.77  }
    9.78 @@ -647,7 +654,7 @@ swiotlb_dma_mapping_error(dma_addr_t dma
    9.79  int
    9.80  swiotlb_dma_supported (struct device *hwdev, u64 mask)
    9.81  {
    9.82 -	return (mask >= (iotlb_bus_end - 1));
    9.83 +	return (mask >= ((1UL << IO_TLB_DMA_BITS) - 1));
    9.84  }
    9.85  
    9.86  EXPORT_SYMBOL(swiotlb_init);
    10.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Tue Jun 13 09:00:32 2006 -0600
    10.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Tue Jun 13 12:12:24 2006 -0600
    10.3 @@ -978,12 +978,19 @@ static void stop_hz_timer(void)
    10.4  	unsigned int cpu = smp_processor_id();
    10.5  	unsigned long j;
    10.6  
    10.7 -	/* We must do this /before/ checking rcu_pending(). */
    10.8  	cpu_set(cpu, nohz_cpu_mask);
    10.9 +
   10.10 +	/* See matching smp_mb in rcu_start_batch in rcupdate.c.  These mbs  */
   10.11 +	/* ensure that if __rcu_pending (nested in rcu_needs_cpu) fetches a  */
   10.12 +	/* value of rcp->cur that matches rdp->quiescbatch and allows us to  */
   10.13 +	/* stop the hz timer then the cpumasks created for subsequent values */
   10.14 +	/* of cur in rcu_start_batch are guaranteed to pick up the updated   */
   10.15 +	/* nohz_cpu_mask and so will not depend on this cpu.                 */
   10.16 +
   10.17  	smp_mb();
   10.18  
   10.19  	/* Leave ourselves in 'tick mode' if rcu or softirq pending. */
   10.20 -	if (rcu_pending(cpu) || local_softirq_pending()) {
   10.21 +	if (rcu_needs_cpu(cpu) || local_softirq_pending()) {
   10.22  		cpu_clear(cpu, nohz_cpu_mask);
   10.23  		j = jiffies + 1;
   10.24  	} else {
    11.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c	Tue Jun 13 09:00:32 2006 -0600
    11.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/vm86.c	Tue Jun 13 12:12:24 2006 -0600
    11.3 @@ -132,7 +132,9 @@ struct pt_regs * fastcall save_v86_state
    11.4  	current->thread.sysenter_cs = __KERNEL_CS;
    11.5  	load_esp0(tss, &current->thread);
    11.6  	current->thread.saved_esp0 = 0;
    11.7 +#ifndef CONFIG_X86_NO_TSS
    11.8  	put_cpu();
    11.9 +#endif
   11.10  
   11.11  	loadsegment(fs, current->thread.saved_fs);
   11.12  	loadsegment(gs, current->thread.saved_gs);
   11.13 @@ -310,7 +312,9 @@ static void do_sys_vm86(struct kernel_vm
   11.14  	if (cpu_has_sep)
   11.15  		tsk->thread.sysenter_cs = 0;
   11.16  	load_esp0(tss, &tsk->thread);
   11.17 +#ifndef CONFIG_X86_NO_TSS
   11.18  	put_cpu();
   11.19 +#endif
   11.20  
   11.21  	tsk->thread.screen_bitmap = info->screen_bitmap;
   11.22  	if (info->flags & VM86_SCREEN_BITMAP)
    12.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c	Tue Jun 13 09:00:32 2006 -0600
    12.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c	Tue Jun 13 12:12:24 2006 -0600
    12.3 @@ -558,15 +558,11 @@ void __init paging_init(void)
    12.4  
    12.5  	kmap_init();
    12.6  
    12.7 -	if (!xen_feature(XENFEAT_auto_translated_physmap) ||
    12.8 -	    xen_start_info->shared_info >= xen_start_info->nr_pages) {
    12.9 -		/* Switch to the real shared_info page, and clear the
   12.10 -		 * dummy page. */
   12.11 -		set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
   12.12 -		HYPERVISOR_shared_info =
   12.13 -			(shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   12.14 -		memset(empty_zero_page, 0, sizeof(empty_zero_page));
   12.15 -	}
   12.16 +	/* Switch to the real shared_info page, and clear the
   12.17 +	 * dummy page. */
   12.18 +	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
   12.19 +	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   12.20 +	memset(empty_zero_page, 0, sizeof(empty_zero_page));
   12.21  
   12.22  	/* Setup mapping of lower 1st MB */
   12.23  	for (i = 0; i < NR_FIX_ISAMAPS; i++)
    13.1 --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig	Tue Jun 13 09:00:32 2006 -0600
    13.2 +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig	Tue Jun 13 12:12:24 2006 -0600
    13.3 @@ -66,7 +66,7 @@ config XEN_IA64_DOM0_VP
    13.4  
    13.5  config XEN_IA64_DOM0_NON_VP
    13.6  	bool
    13.7 -	depends on !(XEN && XEN_IA64_DOM0_VP)
    13.8 +	depends on XEN && !XEN_IA64_DOM0_VP
    13.9  	default y
   13.10  	help
   13.11  	  dom0 P=M model
   13.12 @@ -489,15 +489,39 @@ source "security/Kconfig"
   13.13  
   13.14  source "crypto/Kconfig"
   13.15  
   13.16 +#
   13.17  # override default values of drivers/xen/Kconfig
   13.18 -if !XEN_IA64_DOM0_VP
   13.19 +#
   13.20 +if XEN
   13.21 +config XEN_UTIL
   13.22 +	default n if XEN_IA64_DOM0_VP
   13.23 +
   13.24  config HAVE_ARCH_ALLOC_SKB
   13.25 -        bool
   13.26 -        default n
   13.27 +	default n if !XEN_IA64_DOM0_VP
   13.28  
   13.29  config HAVE_ARCH_DEV_ALLOC_SKB
   13.30 -        bool
   13.31 -        default n
   13.32 +	default n if !XEN_IA64_DOM0_VP
   13.33 +
   13.34 +config XEN_BALLOON
   13.35 +	default n if !XEN_IA64_DOM0_VP
   13.36 +
   13.37 +config XEN_SKBUFF
   13.38 +	default n if !XEN_IA64_DOM0_VP
   13.39 +
   13.40 +config XEN_NETDEV_BACKEND
   13.41 +	default n if !XEN_IA64_DOM0_VP
   13.42 +
   13.43 +config XEN_NETDEV_FRONTEND
   13.44 +	default n if !XEN_IA64_DOM0_VP
   13.45 +
   13.46 +config XEN_DEVMEM
   13.47 +	default n
   13.48 +
   13.49 +config XEN_REBOOT
   13.50 +	default n
   13.51 +
   13.52 +config XEN_SMPBOOT
   13.53 +	default n
   13.54  endif
   13.55  
   13.56  source "drivers/xen/Kconfig"
    14.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre	Tue Jun 13 09:00:32 2006 -0600
    14.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen-mkbuildtree-pre	Tue Jun 13 12:12:24 2006 -0600
    14.3 @@ -10,8 +10,3 @@
    14.4  #eventually asm-xsi-offsets needs to be part of hypervisor.h/hypercall.h
    14.5  ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/asm-ia64/xen/
    14.6  
    14.7 -#ia64 drivers/xen isn't fully functional yet, workaround...
    14.8 -#also ignore core/evtchn.c which uses a different irq mechanism than ia64
    14.9 -#(warning: there be dragons here if these files diverge)
   14.10 -ln -sf ../../arch/ia64/xen/drivers/Makefile drivers/xen/Makefile
   14.11 -ln -sf ../../../arch/ia64/xen/drivers/coreMakefile drivers/xen/core/Makefile
    15.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/Makefile	Tue Jun 13 09:00:32 2006 -0600
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,21 +0,0 @@
    15.4 -
    15.5 -ifneq ($(CONFIG_XEN_IA64_DOM0_VP),y)
    15.6 -obj-y   += util.o
    15.7 -endif
    15.8 -
    15.9 -obj-y	+= core/
   15.10 -#obj-y	+= char/
   15.11 -obj-y	+= console/
   15.12 -obj-y	+= evtchn/
   15.13 -obj-$(CONFIG_XEN_IA64_DOM0_VP)	+= balloon/
   15.14 -obj-y	+= privcmd/
   15.15 -obj-y	+= xenbus/
   15.16 -
   15.17 -obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
   15.18 -obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
   15.19 -obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmback/
   15.20 -obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
   15.21 -obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
   15.22 -obj-$(CONFIG_XEN_BLKDEV_TAP)		+= blktap/
   15.23 -obj-$(CONFIG_XEN_PCIDEV_BACKEND)	+= pciback/
   15.24 -obj-$(CONFIG_XEN_PCIDEV_FRONTEND)	+= pcifront/
    16.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/README	Tue Jun 13 09:00:32 2006 -0600
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,2 +0,0 @@
    16.4 -This is a temporary location for source/Makefiles that need to be
    16.5 -patched/reworked in drivers/xen to work with xenlinux/ia64.
    17.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/coreMakefile	Tue Jun 13 09:00:32 2006 -0600
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,19 +0,0 @@
    17.4 -#
    17.5 -# Makefile for the linux kernel.
    17.6 -#
    17.7 -
    17.8 -obj-y   := gnttab.o features.o
    17.9 -obj-$(CONFIG_PROC_FS) += xen_proc.o
   17.10 -
   17.11 -ifeq ($(ARCH),ia64)
   17.12 -obj-y   += evtchn.o
   17.13 -ifeq ($(CONFIG_XEN_IA64_DOM0_VP),y)
   17.14 -obj-$(CONFIG_NET)     += skbuff.o
   17.15 -endif
   17.16 -else
   17.17 -obj-y   += reboot.o evtchn.o fixup.o 
   17.18 -obj-$(CONFIG_SMP)     += smp.o		# setup_profiling_timer def'd in ia64
   17.19 -obj-$(CONFIG_NET)     += skbuff.o	# until networking is up on ia64
   17.20 -endif
   17.21 -obj-$(CONFIG_SYSFS)   += hypervisor_sysfs.o
   17.22 -obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o
    18.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Tue Jun 13 09:00:32 2006 -0600
    18.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c	Tue Jun 13 12:12:24 2006 -0600
    18.3 @@ -44,9 +44,7 @@ unsigned long end_pfn_map;
    18.4   */
    18.5  unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
    18.6  
    18.7 -#ifndef CONFIG_XEN
    18.8  extern struct resource code_resource, data_resource;
    18.9 -#endif
   18.10  
   18.11  /* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
   18.12  static inline int bad_addr(unsigned long *addrp, unsigned long size)
   18.13 @@ -251,8 +249,7 @@ void __init e820_reserve_resources(struc
   18.14  		res->end = res->start + e820[i].size - 1;
   18.15  		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
   18.16  		request_resource(&iomem_resource, res);
   18.17 -#ifndef CONFIG_XEN
   18.18 -		if (e820.map[i].type == E820_RAM) {
   18.19 +		if (e820[i].type == E820_RAM) {
   18.20  			/*
   18.21  			 *  We don't know which RAM region contains kernel data,
   18.22  			 *  so we try it repeatedly and let the resource manager
   18.23 @@ -264,7 +261,6 @@ void __init e820_reserve_resources(struc
   18.24  			request_resource(res, &crashk_res);
   18.25  #endif
   18.26  		}
   18.27 -#endif
   18.28  	}
   18.29  }
   18.30  
    19.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Tue Jun 13 09:00:32 2006 -0600
    19.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Tue Jun 13 12:12:24 2006 -0600
    19.3 @@ -19,6 +19,56 @@
    19.4  #include <linux/thread_info.h>
    19.5  #include <xen/interface/physdev.h>
    19.6  
    19.7 +/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
    19.8 +static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
    19.9 +{
   19.10 +	int i;
   19.11 +
   19.12 +	if (new_value)
   19.13 +		for (i = base; i < base + extent; i++)
   19.14 +			__set_bit(i, bitmap);
   19.15 +	else
   19.16 +		for (i = base; i < base + extent; i++)
   19.17 +			clear_bit(i, bitmap);
   19.18 +}
   19.19 +
   19.20 +/*
   19.21 + * this changes the io permissions bitmap in the current task.
   19.22 + */
   19.23 +asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
   19.24 +{
   19.25 +	struct thread_struct * t = &current->thread;
   19.26 +	unsigned long *bitmap;
   19.27 +	struct physdev_set_iobitmap set_iobitmap;
   19.28 +
   19.29 +	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
   19.30 +		return -EINVAL;
   19.31 +	if (turn_on && !capable(CAP_SYS_RAWIO))
   19.32 +		return -EPERM;
   19.33 +
   19.34 +	/*
   19.35 +	 * If it's the first ioperm() call in this thread's lifetime, set the
   19.36 +	 * IO bitmap up. ioperm() is much less timing critical than clone(),
   19.37 +	 * this is why we delay this operation until now:
   19.38 +	 */
   19.39 +	if (!t->io_bitmap_ptr) {
   19.40 +		bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
   19.41 +		if (!bitmap)
   19.42 +			return -ENOMEM;
   19.43 +
   19.44 +		memset(bitmap, 0xff, IO_BITMAP_BYTES);
   19.45 +		t->io_bitmap_ptr = bitmap;
   19.46 +
   19.47 +		set_iobitmap.bitmap   = (char *)bitmap;
   19.48 +		set_iobitmap.nr_ports = IO_BITMAP_BITS;
   19.49 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
   19.50 +	}
   19.51 +
   19.52 +	set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
   19.53 +
   19.54 +	return 0;
   19.55 +}
   19.56 +
   19.57  /*
   19.58   * sys_iopl has to be used when you want to access the IO ports
   19.59   * beyond the 0x3ff range: to get the full 65536 ports bitmapped
   19.60 @@ -47,11 +97,3 @@ asmlinkage long sys_iopl(unsigned int ne
   19.61  
   19.62  	return 0;
   19.63  }
   19.64 -
   19.65 -/*
   19.66 - * this changes the io permissions bitmap in the current task.
   19.67 - */
   19.68 -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
   19.69 -{
   19.70 -  return turn_on ? sys_iopl(3, NULL) : 0;
   19.71 -}
    20.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Tue Jun 13 09:00:32 2006 -0600
    20.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c	Tue Jun 13 12:12:24 2006 -0600
    20.3 @@ -665,13 +665,6 @@ void __init setup_arch(char **cmdline_p)
    20.4  
    20.5  	setup_xen_features();
    20.6  
    20.7 -	if (xen_feature(XENFEAT_auto_translated_physmap) &&
    20.8 -	    xen_start_info->shared_info < xen_start_info->nr_pages) {
    20.9 -		HYPERVISOR_shared_info =
   20.10 -			(shared_info_t *)__va(xen_start_info->shared_info);
   20.11 -		memset(empty_zero_page, 0, sizeof(empty_zero_page));
   20.12 -	}
   20.13 -
   20.14  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
   20.15  			     VMASST_TYPE_writable_pagetables);
   20.16  
   20.17 @@ -699,12 +692,10 @@ void __init setup_arch(char **cmdline_p)
   20.18  	init_mm.end_data = (unsigned long) &_edata;
   20.19  	init_mm.brk = (unsigned long) &_end;
   20.20  
   20.21 -#ifndef CONFIG_XEN
   20.22  	code_resource.start = virt_to_phys(&_text);
   20.23  	code_resource.end = virt_to_phys(&_etext)-1;
   20.24  	data_resource.start = virt_to_phys(&_etext);
   20.25  	data_resource.end = virt_to_phys(&_edata)-1;
   20.26 -#endif
   20.27  
   20.28  	parse_cmdline_early(cmdline_p);
   20.29  
   20.30 @@ -826,14 +817,6 @@ void __init setup_arch(char **cmdline_p)
   20.31  #ifdef CONFIG_XEN
   20.32  	{
   20.33  		int i, j, k, fpp;
   20.34 -		unsigned long va;
   20.35 -
   20.36 -		/* 'Initial mapping' of initrd must be destroyed. */
   20.37 -		for (va = xen_start_info->mod_start;
   20.38 -		     va < (xen_start_info->mod_start+xen_start_info->mod_len);
   20.39 -		     va += PAGE_SIZE) {
   20.40 -			HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
   20.41 -		}
   20.42  
   20.43  		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
   20.44  			/* Make sure we have a large enough P->M table. */
   20.45 @@ -849,14 +832,6 @@ void __init setup_arch(char **cmdline_p)
   20.46  				PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
   20.47  						sizeof(unsigned long))));
   20.48  
   20.49 -			/* Destroyed 'initial mapping' of old p2m table. */
   20.50 -			for (va = xen_start_info->mfn_list;
   20.51 -			     va < (xen_start_info->mfn_list +
   20.52 -				   (xen_start_info->nr_pages*sizeof(unsigned long)));
   20.53 -			     va += PAGE_SIZE) {
   20.54 -				HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
   20.55 -			}
   20.56 -
   20.57  			/*
   20.58  			 * Initialise the list of the frames that specify the
   20.59  			 * list of frames that make up the p2m table. Used by
   20.60 @@ -944,8 +919,11 @@ void __init setup_arch(char **cmdline_p)
   20.61  		BUG_ON(HYPERVISOR_memory_op(XENMEM_machine_memory_map, &memmap));
   20.62  
   20.63  		e820_reserve_resources(machine_e820, memmap.nr_entries);
   20.64 -	}
   20.65 -#elif !defined(CONFIG_XEN)
   20.66 +	} else if (!(xen_start_info->flags & SIF_INITDOMAIN))
   20.67 +		e820_reserve_resources(e820.map, e820.nr_map);
   20.68 +#elif defined(CONFIG_XEN)
   20.69 +	e820_reserve_resources(e820.map, e820.nr_map);
   20.70 +#else
   20.71  	probe_roms();
   20.72  	e820_reserve_resources(e820.map, e820.nr_map);
   20.73  #endif
    21.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c	Tue Jun 13 09:00:32 2006 -0600
    21.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/smp-xen.c	Tue Jun 13 12:12:24 2006 -0600
    21.3 @@ -488,7 +488,7 @@ static void smp_really_stop_cpu(void *du
    21.4  {
    21.5  	smp_stop_cpu(); 
    21.6  	for (;;) 
    21.7 -		asm("hlt"); 
    21.8 +		halt();
    21.9  } 
   21.10  
   21.11  void smp_send_stop(void)
    22.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Jun 13 09:00:32 2006 -0600
    22.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c	Tue Jun 13 12:12:24 2006 -0600
    22.3 @@ -666,7 +666,34 @@ void __meminit init_memory_mapping(unsig
    22.4  			set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
    22.5  	}
    22.6  
    22.7 -	BUG_ON(!after_bootmem && start_pfn != table_end);
    22.8 +	if (!after_bootmem) {
    22.9 +		BUG_ON(start_pfn != table_end);
   22.10 +
   22.11 +		/* Re-vector virtual addresses pointing into the initial
   22.12 +		   mapping to the just-established permanent ones. */
   22.13 +		xen_start_info = __va(__pa(xen_start_info));
   22.14 +		xen_start_info->pt_base = (unsigned long)
   22.15 +			__va(__pa(xen_start_info->pt_base));
   22.16 +		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
   22.17 +			phys_to_machine_mapping =
   22.18 +				__va(__pa(xen_start_info->mfn_list));
   22.19 +			xen_start_info->mfn_list = (unsigned long)
   22.20 +				phys_to_machine_mapping;
   22.21 +		}
   22.22 +		if (xen_start_info->mod_start)
   22.23 +			xen_start_info->mod_start = (unsigned long)
   22.24 +				__va(__pa(xen_start_info->mod_start));
   22.25 +
   22.26 +		/* Destroy the Xen-created mappings beyond the kernel image as
   22.27 +		 * well as the temporary mappings created above. Prevents
   22.28 +		 * overlap with modules area (if init mapping is very big).
   22.29 +		 */
   22.30 +		start = PAGE_ALIGN((unsigned long)_end);
   22.31 +		end   = __START_KERNEL_map + (table_end << PAGE_SHIFT);
   22.32 +		for (; start < end; start += PAGE_SIZE)
   22.33 +			WARN_ON(HYPERVISOR_update_va_mapping(
   22.34 +				start, __pte_ma(0), 0));
   22.35 +	}
   22.36  
   22.37  	__flush_tlb_all();
   22.38  }
   22.39 @@ -752,15 +779,11 @@ void __init paging_init(void)
   22.40  	free_area_init_node(0, NODE_DATA(0), zones,
   22.41  			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
   22.42  
   22.43 -	if (!xen_feature(XENFEAT_auto_translated_physmap) ||
   22.44 -	    xen_start_info->shared_info >= xen_start_info->nr_pages) {
   22.45 -		/* Switch to the real shared_info page, and clear the
   22.46 -		 * dummy page. */
   22.47 -		set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
   22.48 -		HYPERVISOR_shared_info =
   22.49 -			(shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   22.50 -		memset(empty_zero_page, 0, sizeof(empty_zero_page));
   22.51 -	}
   22.52 +	/* Switch to the real shared_info page, and clear the
   22.53 +	 * dummy page. */
   22.54 +	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
   22.55 +	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
   22.56 +	memset(empty_zero_page, 0, sizeof(empty_zero_page));
   22.57  
   22.58  	init_mm.context.pinned = 1;
   22.59  
   22.60 @@ -859,6 +882,7 @@ static struct kcore_list kcore_mem, kcor
   22.61  void __init mem_init(void)
   22.62  {
   22.63  	long codesize, reservedpages, datasize, initsize;
   22.64 +	unsigned long pfn;
   22.65  
   22.66  	contiguous_bitmap = alloc_bootmem_low_pages(
   22.67  		(end_pfn + 2*BITS_PER_LONG) >> 3);
   22.68 @@ -887,6 +911,12 @@ void __init mem_init(void)
   22.69  #else
   22.70  	totalram_pages = free_all_bootmem();
   22.71  #endif
   22.72 +	/* XEN: init and count pages outside initial allocation. */
   22.73 +	for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
   22.74 +		ClearPageReserved(&mem_map[pfn]);
   22.75 +		set_page_count(&mem_map[pfn], 1);
   22.76 +		totalram_pages++;
   22.77 +	}
   22.78  	reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
   22.79  
   22.80  	after_bootmem = 1;
    23.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Tue Jun 13 09:00:32 2006 -0600
    23.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Tue Jun 13 12:12:24 2006 -0600
    23.3 @@ -274,7 +274,7 @@ static int talk_to_backend(struct xenbus
    23.4  {
    23.5  	const char *message = NULL;
    23.6  	int err;
    23.7 -	xenbus_transaction_t xbt;
    23.8 +	struct xenbus_transaction xbt;
    23.9  
   23.10  	err = setup_tpmring(dev, tp);
   23.11  	if (err) {
   23.12 @@ -331,7 +331,7 @@ out:
   23.13  static void backend_changed(struct xenbus_device *dev,
   23.14  			    enum xenbus_state backend_state)
   23.15  {
   23.16 -	struct tpm_private *tp = dev->data;
   23.17 +	struct tpm_private *tp = dev->dev.driver_data;
   23.18  	DPRINTK("\n");
   23.19  
   23.20  	switch (backend_state) {
   23.21 @@ -369,7 +369,7 @@ static int tpmfront_probe(struct xenbus_
   23.22  	if (!tp)
   23.23  		return -ENOMEM;
   23.24  
   23.25 -	err = xenbus_scanf(XBT_NULL, dev->nodename,
   23.26 +	err = xenbus_scanf(XBT_NIL, dev->nodename,
   23.27  	                   "handle", "%i", &handle);
   23.28  	if (XENBUS_EXIST_ERR(err))
   23.29  		return err;
   23.30 @@ -380,12 +380,12 @@ static int tpmfront_probe(struct xenbus_
   23.31  	}
   23.32  
   23.33  	tp->dev = dev;
   23.34 -	dev->data = tp;
   23.35 +	dev->dev.driver_data = tp;
   23.36  
   23.37  	err = talk_to_backend(dev, tp);
   23.38  	if (err) {
   23.39  		tpm_private_put();
   23.40 -		dev->data = NULL;
   23.41 +		dev->dev.driver_data = NULL;
   23.42  		return err;
   23.43  	}
   23.44  	return 0;
   23.45 @@ -394,14 +394,14 @@ static int tpmfront_probe(struct xenbus_
   23.46  
   23.47  static int tpmfront_remove(struct xenbus_device *dev)
   23.48  {
   23.49 -	struct tpm_private *tp = (struct tpm_private *)dev->data;
   23.50 +	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
   23.51  	destroy_tpmring(tp);
   23.52  	return 0;
   23.53  }
   23.54  
   23.55  static int tpmfront_suspend(struct xenbus_device *dev)
   23.56  {
   23.57 -	struct tpm_private *tp = (struct tpm_private *)dev->data;
   23.58 +	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
   23.59  	u32 ctr;
   23.60  
   23.61  	/* lock, so no app can send */
   23.62 @@ -431,7 +431,7 @@ static int tpmfront_suspend(struct xenbu
   23.63  
   23.64  static int tpmfront_resume(struct xenbus_device *dev)
   23.65  {
   23.66 -	struct tpm_private *tp = (struct tpm_private *)dev->data;
   23.67 +	struct tpm_private *tp = (struct tpm_private *)dev->dev.driver_data;
   23.68  	destroy_tpmring(tp);
   23.69  	return talk_to_backend(dev, tp);
   23.70  }
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/Kconfig	Tue Jun 13 09:00:32 2006 -0600
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig	Tue Jun 13 12:12:24 2006 -0600
    24.3 @@ -84,19 +84,6 @@ config XEN_BLKDEV_BACKEND
    24.4  	  block devices to other guests via a high-performance shared-memory
    24.5  	  interface.
    24.6  
    24.7 -config XEN_BLKDEV_TAP_BE
    24.8 -        tristate "Block Tap support for backend driver (DANGEROUS)"
    24.9 -        depends on XEN_BLKDEV_BACKEND
   24.10 -        default n
   24.11 -        help
   24.12 -          If you intend to use the block tap driver, the backend domain will
   24.13 -          not know the domain id of the real frontend, and so will not be able
   24.14 -          to map its data pages.  This modifies the backend to attempt to map
   24.15 -          from both the tap domain and the real frontend.  This presents a
   24.16 -          security risk, and so should ONLY be used for development
   24.17 -          with the blktap.  This option will be removed as the block drivers are
   24.18 -          modified to use grant tables.
   24.19 -
   24.20  config XEN_NETDEV_BACKEND
   24.21  	tristate "Network-device backend driver"
   24.22          depends on XEN_BACKEND && NET
   24.23 @@ -163,16 +150,6 @@ config XEN_NETDEV_FRONTEND
   24.24  	  dedicated device-driver domain, or your master control domain
   24.25  	  (domain 0), then you almost certainly want to say Y here.
   24.26  
   24.27 -config XEN_BLKDEV_TAP
   24.28 -	tristate "Block device tap driver"
   24.29 -        depends on XEN_BACKEND
   24.30 -	default n
   24.31 -	help
   24.32 -	  This driver allows a VM to interact on block device channels
   24.33 -	  to other VMs.  Block messages may be passed through or redirected
   24.34 -	  to a character device, allowing device prototyping in application
   24.35 -	  space.  Odds are that you want to say N here.
   24.36 -
   24.37  config XEN_SCRUB_PAGES
   24.38  	bool "Scrub memory before freeing it to Xen"
   24.39  	default y
   24.40 @@ -224,8 +201,38 @@ config HAVE_ARCH_DEV_ALLOC_SKB
   24.41  	bool
   24.42  	default y
   24.43  
   24.44 +config HAVE_IRQ_IGNORE_UNHANDLED
   24.45 +	bool
   24.46 +	default y
   24.47 +
   24.48  config NO_IDLE_HZ
   24.49  	bool
   24.50  	default y
   24.51  
   24.52 +config XEN_UTIL
   24.53 +	bool
   24.54 +	default y
   24.55 +
   24.56 +config XEN_BALLOON
   24.57 +	bool
   24.58 +	default y
   24.59 +
   24.60 +config XEN_DEVMEM
   24.61 +	bool
   24.62 +	default y
   24.63 +
   24.64 +config XEN_SKBUFF
   24.65 +	bool
   24.66 +	default y
   24.67 +	depends on NET
   24.68 +
   24.69 +config XEN_REBOOT
   24.70 +	bool
   24.71 +	default y
   24.72 +
   24.73 +config XEN_SMPBOOT
   24.74 +	bool
   24.75 +	default y
   24.76 +	depends on SMP
   24.77 +
   24.78  endif
    25.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Tue Jun 13 09:00:32 2006 -0600
    25.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Tue Jun 13 12:12:24 2006 -0600
    25.3 @@ -1,20 +1,16 @@
    25.4 -
    25.5 -obj-y	+= util.o
    25.6 -
    25.7  obj-y	+= core/
    25.8 -obj-y	+= char/
    25.9  obj-y	+= console/
   25.10  obj-y	+= evtchn/
   25.11 -obj-y	+= balloon/
   25.12  obj-y	+= privcmd/
   25.13  obj-y	+= xenbus/
   25.14  
   25.15 +obj-$(CONFIG_XEN_UTIL)			+= util.o
   25.16 +obj-$(CONFIG_XEN_BALLOON)		+= balloon/
   25.17 +obj-$(CONFIG_XEN_DEVMEM)		+= char/
   25.18  obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= blkback/
   25.19  obj-$(CONFIG_XEN_NETDEV_BACKEND)	+= netback/
   25.20  obj-$(CONFIG_XEN_TPMDEV_BACKEND)	+= tpmback/
   25.21  obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= blkfront/
   25.22  obj-$(CONFIG_XEN_NETDEV_FRONTEND)	+= netfront/
   25.23 -obj-$(CONFIG_XEN_BLKDEV_TAP)    	+= blktap/
   25.24  obj-$(CONFIG_XEN_PCIDEV_BACKEND)	+= pciback/
   25.25  obj-$(CONFIG_XEN_PCIDEV_FRONTEND)	+= pcifront/
   25.26 -
    26.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Tue Jun 13 09:00:32 2006 -0600
    26.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Tue Jun 13 12:12:24 2006 -0600
    26.3 @@ -222,7 +222,7 @@ static int increase_reservation(unsigned
    26.4  		/* Update P->M and M->P tables. */
    26.5  		set_phys_to_machine(pfn, frame_list[i]);
    26.6  		xen_machphys_update(frame_list[i], pfn);
    26.7 -            
    26.8 +
    26.9  		/* Link back into the page tables if not highmem. */
   26.10  		if (pfn < max_low_pfn) {
   26.11  			int ret;
   26.12 @@ -378,22 +378,21 @@ static void watch_target(struct xenbus_w
   26.13  	unsigned long long new_target;
   26.14  	int err;
   26.15  
   26.16 -	err = xenbus_scanf(XBT_NULL, "memory", "target", "%llu", &new_target);
   26.17 +	err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target);
   26.18  	if (err != 1) {
   26.19  		/* This is ok (for domain0 at least) - so just return */
   26.20  		return;
   26.21 -	} 
   26.22 -        
   26.23 +	}
   26.24 +
   26.25  	/* The given memory/target value is in KiB, so it needs converting to
   26.26 -	   pages.  PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
   26.27 -	*/
   26.28 +	 * pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
   26.29 +	 */
   26.30  	set_new_target(new_target >> (PAGE_SHIFT - 10));
   26.31 -    
   26.32  }
   26.33  
   26.34  static int balloon_init_watcher(struct notifier_block *notifier,
   26.35 -                                unsigned long event,
   26.36 -                                void *data)
   26.37 +				unsigned long event,
   26.38 +				void *data)
   26.39  {
   26.40  	int err;
   26.41  
   26.42 @@ -402,11 +401,10 @@ static int balloon_init_watcher(struct n
   26.43  		printk(KERN_ERR "Failed to set balloon watcher\n");
   26.44  
   26.45  	return NOTIFY_DONE;
   26.46 -    
   26.47  }
   26.48  
   26.49  static int balloon_write(struct file *file, const char __user *buffer,
   26.50 -                         unsigned long count, void *data)
   26.51 +			 unsigned long count, void *data)
   26.52  {
   26.53  	char memstring[64], *endchar;
   26.54  	unsigned long long target_bytes;
   26.55 @@ -430,7 +428,7 @@ static int balloon_write(struct file *fi
   26.56  }
   26.57  
   26.58  static int balloon_read(char *page, char **start, off_t off,
   26.59 -                        int count, int *eof, void *data)
   26.60 +			int count, int *eof, void *data)
   26.61  {
   26.62  	int len;
   26.63  
    27.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Tue Jun 13 09:00:32 2006 -0600
    27.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Tue Jun 13 12:12:24 2006 -0600
    27.3 @@ -105,24 +105,12 @@ static inline unsigned long vaddr(pendin
    27.4  	(pending_grant_handles[vaddr_pagenr(_req, _seg)])
    27.5  
    27.6  
    27.7 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
    27.8 -/*
    27.9 - * If the tap driver is used, we may get pages belonging to either the tap
   27.10 - * or (more likely) the real frontend.  The backend must specify which domain
   27.11 - * a given page belongs to in update_va_mapping though.  For the moment, 
   27.12 - * the tap rewrites the ID field of the request to contain the request index
   27.13 - * and the id of the real front end domain.
   27.14 - */
   27.15 -#define BLKTAP_COOKIE 0xbeadfeed
   27.16 -static inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); }
   27.17 -#endif
   27.18 -
   27.19  static int do_block_io_op(blkif_t *blkif);
   27.20  static void dispatch_rw_block_io(blkif_t *blkif,
   27.21  				 blkif_request_t *req,
   27.22  				 pending_req_t *pending_req);
   27.23  static void make_response(blkif_t *blkif, unsigned long id, 
   27.24 -                          unsigned short op, int st);
   27.25 +			  unsigned short op, int st);
   27.26  
   27.27  /******************************************************************
   27.28   * misc small helpers
   27.29 @@ -446,7 +434,7 @@ static void dispatch_rw_block_io(blkif_t
   27.30  			bio = biolist[nbio++] = bio_alloc(GFP_KERNEL, nseg-i);
   27.31  			if (unlikely(bio == NULL))
   27.32  				goto fail_put_bio;
   27.33 -                
   27.34 +
   27.35  			bio->bi_bdev    = preq.bdev;
   27.36  			bio->bi_private = pending_req;
   27.37  			bio->bi_end_io  = end_block_io_op;
   27.38 @@ -483,7 +471,7 @@ static void dispatch_rw_block_io(blkif_t
   27.39  
   27.40  
   27.41  static void make_response(blkif_t *blkif, unsigned long id, 
   27.42 -                          unsigned short op, int st)
   27.43 +			  unsigned short op, int st)
   27.44  {
   27.45  	blkif_response_t *resp;
   27.46  	unsigned long     flags;
    28.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Jun 13 09:00:32 2006 -0600
    28.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Tue Jun 13 12:12:24 2006 -0600
    28.3 @@ -45,8 +45,9 @@
    28.4  #include <xen/gnttab.h>
    28.5  #include <xen/driver_util.h>
    28.6  
    28.7 -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
    28.8 -                                    __FILE__ , __LINE__ , ## _a )
    28.9 +#define DPRINTK(_f, _a...)			\
   28.10 +	pr_debug("(file=%s, line=%d) " _f,	\
   28.11 +		 __FILE__ , __LINE__ , ## _a )
   28.12  
   28.13  struct vbd {
   28.14  	blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
   28.15 @@ -73,10 +74,6 @@ typedef struct blkif_st {
   28.16  	/* Back pointer to the backend_info. */
   28.17  	struct backend_info *be; 
   28.18  	/* Private fields. */
   28.19 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
   28.20 -	/* Is this a blktap frontend */
   28.21 -	unsigned int     is_blktap;
   28.22 -#endif
   28.23  	spinlock_t       blk_ring_lock;
   28.24  	atomic_t         refcnt;
   28.25  
    29.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Jun 13 09:00:32 2006 -0600
    29.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Tue Jun 13 12:12:24 2006 -0600
    29.3 @@ -77,7 +77,7 @@ static ssize_t show_physical_device(stru
    29.4  				    struct device_attribute *attr, char *buf)
    29.5  {
    29.6  	struct xenbus_device *dev = to_xenbus_device(_dev);
    29.7 -	struct backend_info *be = dev->data;
    29.8 +	struct backend_info *be = dev->dev.driver_data;
    29.9  	return sprintf(buf, "%x:%x\n", be->major, be->minor);
   29.10  }
   29.11  DEVICE_ATTR(physical_device, S_IRUSR | S_IRGRP | S_IROTH,
   29.12 @@ -88,7 +88,7 @@ static ssize_t show_mode(struct device *
   29.13  			 char *buf)
   29.14  {
   29.15  	struct xenbus_device *dev = to_xenbus_device(_dev);
   29.16 -	struct backend_info *be = dev->data;
   29.17 +	struct backend_info *be = dev->dev.driver_data;
   29.18  	return sprintf(buf, "%s\n", be->mode);
   29.19  }
   29.20  DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_IROTH, show_mode, NULL);
   29.21 @@ -96,7 +96,7 @@ DEVICE_ATTR(mode, S_IRUSR | S_IRGRP | S_
   29.22  
   29.23  static int blkback_remove(struct xenbus_device *dev)
   29.24  {
   29.25 -	struct backend_info *be = dev->data;
   29.26 +	struct backend_info *be = dev->dev.driver_data;
   29.27  
   29.28  	DPRINTK("");
   29.29  
   29.30 @@ -116,7 +116,7 @@ static int blkback_remove(struct xenbus_
   29.31  	device_remove_file(&dev->dev, &dev_attr_mode);
   29.32  
   29.33  	kfree(be);
   29.34 -	dev->data = NULL;
   29.35 +	dev->dev.driver_data = NULL;
   29.36  	return 0;
   29.37  }
   29.38  
   29.39 @@ -138,7 +138,7 @@ static int blkback_probe(struct xenbus_d
   29.40  		return -ENOMEM;
   29.41  	}
   29.42  	be->dev = dev;
   29.43 -	dev->data = be;
   29.44 +	dev->dev.driver_data = be;
   29.45  
   29.46  	be->blkif = blkif_alloc(dev->otherend_id);
   29.47  	if (IS_ERR(be->blkif)) {
   29.48 @@ -186,7 +186,7 @@ static void backend_changed(struct xenbu
   29.49  
   29.50  	DPRINTK("");
   29.51  
   29.52 -	err = xenbus_scanf(XBT_NULL, dev->nodename, "physical-device", "%x:%x",
   29.53 +	err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x",
   29.54  			   &major, &minor);
   29.55  	if (XENBUS_EXIST_ERR(err)) {
   29.56  		/* Since this watch will fire once immediately after it is
   29.57 @@ -208,7 +208,7 @@ static void backend_changed(struct xenbu
   29.58  		return;
   29.59  	}
   29.60  
   29.61 -	be->mode = xenbus_read(XBT_NULL, dev->nodename, "mode", NULL);
   29.62 +	be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL);
   29.63  	if (IS_ERR(be->mode)) {
   29.64  		err = PTR_ERR(be->mode);
   29.65  		be->mode = NULL;
   29.66 @@ -249,7 +249,7 @@ static void backend_changed(struct xenbu
   29.67  static void frontend_changed(struct xenbus_device *dev,
   29.68  			     enum xenbus_state frontend_state)
   29.69  {
   29.70 -	struct backend_info *be = dev->data;
   29.71 +	struct backend_info *be = dev->dev.driver_data;
   29.72  	int err;
   29.73  
   29.74  	DPRINTK("");
   29.75 @@ -299,7 +299,7 @@ static void frontend_changed(struct xenb
   29.76   */
   29.77  static void connect(struct backend_info *be)
   29.78  {
   29.79 -	xenbus_transaction_t xbt;
   29.80 +	struct xenbus_transaction xbt;
   29.81  	int err;
   29.82  	struct xenbus_device *dev = be->dev;
   29.83  
   29.84 @@ -364,7 +364,7 @@ static int connect_ring(struct backend_i
   29.85  
   29.86  	DPRINTK("%s", dev->otherend);
   29.87  
   29.88 -	err = xenbus_gather(XBT_NULL, dev->otherend, "ring-ref", "%lu", &ring_ref,
   29.89 +	err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref,
   29.90  			    "event-channel", "%u", &evtchn, NULL);
   29.91  	if (err) {
   29.92  		xenbus_dev_fatal(dev, err,
    30.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jun 13 09:00:32 2006 -0600
    30.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Tue Jun 13 12:12:24 2006 -0600
    30.3 @@ -83,7 +83,7 @@ static int blkfront_probe(struct xenbus_
    30.4  	struct blkfront_info *info;
    30.5  
    30.6  	/* FIXME: Use dynamic device id if this is not set. */
    30.7 -	err = xenbus_scanf(XBT_NULL, dev->nodename,
    30.8 +	err = xenbus_scanf(XBT_NIL, dev->nodename,
    30.9  			   "virtual-device", "%i", &vdevice);
   30.10  	if (err != 1) {
   30.11  		xenbus_dev_fatal(dev, err, "reading virtual-device");
   30.12 @@ -107,12 +107,12 @@ static int blkfront_probe(struct xenbus_
   30.13  
   30.14  	/* Front end dir is a number, which is used as the id. */
   30.15  	info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
   30.16 -	dev->data = info;
   30.17 +	dev->dev.driver_data = info;
   30.18  
   30.19  	err = talk_to_backend(dev, info);
   30.20  	if (err) {
   30.21  		kfree(info);
   30.22 -		dev->data = NULL;
   30.23 +		dev->dev.driver_data = NULL;
   30.24  		return err;
   30.25  	}
   30.26  
   30.27 @@ -128,7 +128,7 @@ static int blkfront_probe(struct xenbus_
   30.28   */
   30.29  static int blkfront_resume(struct xenbus_device *dev)
   30.30  {
   30.31 -	struct blkfront_info *info = dev->data;
   30.32 +	struct blkfront_info *info = dev->dev.driver_data;
   30.33  	int err;
   30.34  
   30.35  	DPRINTK("blkfront_resume: %s\n", dev->nodename);
   30.36 @@ -148,7 +148,7 @@ static int talk_to_backend(struct xenbus
   30.37  			   struct blkfront_info *info)
   30.38  {
   30.39  	const char *message = NULL;
   30.40 -	xenbus_transaction_t xbt;
   30.41 +	struct xenbus_transaction xbt;
   30.42  	int err;
   30.43  
   30.44  	/* Create shared ring, alloc event channel. */
   30.45 @@ -249,7 +249,7 @@ fail:
   30.46  static void backend_changed(struct xenbus_device *dev,
   30.47  			    enum xenbus_state backend_state)
   30.48  {
   30.49 -	struct blkfront_info *info = dev->data;
   30.50 +	struct blkfront_info *info = dev->dev.driver_data;
   30.51  	struct block_device *bd;
   30.52  
   30.53  	DPRINTK("blkfront:backend_changed.\n");
   30.54 @@ -303,7 +303,7 @@ static void connect(struct blkfront_info
   30.55  
   30.56  	DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
   30.57  
   30.58 -	err = xenbus_gather(XBT_NULL, info->xbdev->otherend,
   30.59 +	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
   30.60  			    "sectors", "%lu", &sectors,
   30.61  			    "info", "%u", &binfo,
   30.62  			    "sector-size", "%lu", &sector_size,
   30.63 @@ -318,7 +318,7 @@ static void connect(struct blkfront_info
   30.64  	err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
   30.65  	if (err) {
   30.66  		xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
   30.67 -		                 info->xbdev->otherend);
   30.68 +				 info->xbdev->otherend);
   30.69  		return;
   30.70  	}
   30.71  
   30.72 @@ -341,7 +341,7 @@ static void connect(struct blkfront_info
   30.73   */
   30.74  static void blkfront_closing(struct xenbus_device *dev)
   30.75  {
   30.76 -	struct blkfront_info *info = dev->data;
   30.77 +	struct blkfront_info *info = dev->dev.driver_data;
   30.78  
   30.79  	DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
   30.80  
   30.81 @@ -353,7 +353,7 @@ static void blkfront_closing(struct xenb
   30.82  
   30.83  static int blkfront_remove(struct xenbus_device *dev)
   30.84  {
   30.85 -	struct blkfront_info *info = dev->data;
   30.86 +	struct blkfront_info *info = dev->dev.driver_data;
   30.87  
   30.88  	DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
   30.89  
   30.90 @@ -444,7 +444,7 @@ int blkif_release(struct inode *inode, s
   30.91  
   30.92  
   30.93  int blkif_ioctl(struct inode *inode, struct file *filep,
   30.94 -                unsigned command, unsigned long argument)
   30.95 +		unsigned command, unsigned long argument)
   30.96  {
   30.97  	int i;
   30.98  
   30.99 @@ -452,10 +452,6 @@ int blkif_ioctl(struct inode *inode, str
  30.100  		      command, (long)argument, inode->i_rdev);
  30.101  
  30.102  	switch (command) {
  30.103 -	case HDIO_GETGEO:
  30.104 -		/* return ENOSYS to use defaults */
  30.105 -		return -ENOSYS;
  30.106 -
  30.107  	case CDROMMULTISESSION:
  30.108  		DPRINTK("FIXME: support multisession CDs later\n");
  30.109  		for (i = 0; i < sizeof(struct cdrom_multisession); i++)
  30.110 @@ -473,6 +469,23 @@ int blkif_ioctl(struct inode *inode, str
  30.111  }
  30.112  
  30.113  
  30.114 +int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
  30.115 +{
  30.116 +	/* We don't have real geometry info, but let's at least return
  30.117 +	   values consistent with the size of the device */
  30.118 +	sector_t nsect = get_capacity(bd->bd_disk);
  30.119 +	sector_t cylinders = nsect;
  30.120 +
  30.121 +	hg->heads = 0xff;
  30.122 +	hg->sectors = 0x3f;
  30.123 +	sector_div(cylinders, hg->heads * hg->sectors);
  30.124 +	hg->cylinders = cylinders;
  30.125 +	if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
  30.126 +		hg->cylinders = 0xffff;
  30.127 +	return 0;
  30.128 +}
  30.129 +
  30.130 +
  30.131  /*
  30.132   * blkif_queue_request
  30.133   *
    31.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Tue Jun 13 09:00:32 2006 -0600
    31.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Tue Jun 13 12:12:24 2006 -0600
    31.3 @@ -59,15 +59,15 @@
    31.4  #include <asm/uaccess.h>
    31.5  
    31.6  #if 1
    31.7 -#define IPRINTK(fmt, args...) \
    31.8 -    printk(KERN_INFO "xen_blk: " fmt, ##args)
    31.9 +#define IPRINTK(fmt, args...)				\
   31.10 +	printk(KERN_INFO "xen_blk: " fmt, ##args)
   31.11  #else
   31.12  #define IPRINTK(fmt, args...) ((void)0)
   31.13  #endif
   31.14  
   31.15  #if 1
   31.16 -#define WPRINTK(fmt, args...) \
   31.17 -    printk(KERN_WARNING "xen_blk: " fmt, ##args)
   31.18 +#define WPRINTK(fmt, args...)				\
   31.19 +	printk(KERN_WARNING "xen_blk: " fmt, ##args)
   31.20  #else
   31.21  #define WPRINTK(fmt, args...) ((void)0)
   31.22  #endif
   31.23 @@ -139,7 +139,8 @@ extern spinlock_t blkif_io_lock;
   31.24  extern int blkif_open(struct inode *inode, struct file *filep);
   31.25  extern int blkif_release(struct inode *inode, struct file *filep);
   31.26  extern int blkif_ioctl(struct inode *inode, struct file *filep,
   31.27 -                       unsigned command, unsigned long argument);
   31.28 +		       unsigned command, unsigned long argument);
   31.29 +extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
   31.30  extern int blkif_check(dev_t dev);
   31.31  extern int blkif_revalidate(dev_t dev);
   31.32  extern void do_blkif_request (request_queue_t *rq);
    32.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Tue Jun 13 09:00:32 2006 -0600
    32.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Tue Jun 13 12:12:24 2006 -0600
    32.3 @@ -91,6 +91,7 @@ static struct block_device_operations xl
    32.4  	.open = blkif_open,
    32.5  	.release = blkif_release,
    32.6  	.ioctl  = blkif_ioctl,
    32.7 +	.getgeo = blkif_getgeo
    32.8  };
    32.9  
   32.10  DEFINE_SPINLOCK(blkif_io_lock);
    33.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/Makefile	Tue Jun 13 09:00:32 2006 -0600
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,3 +0,0 @@
    33.4 -
    33.5 -obj-y	:= xenbus.o interface.o blktap.o 
    33.6 -
    34.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Tue Jun 13 09:00:32 2006 -0600
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,900 +0,0 @@
    34.4 -/******************************************************************************
    34.5 - * arch/xen/drivers/blkif/blktap/blktap.c
    34.6 - * 
    34.7 - * This is a modified version of the block backend driver that remaps requests
    34.8 - * to a user-space memory region.  It is intended to be used to write 
    34.9 - * application-level servers that provide block interfaces to client VMs.
   34.10 - */
   34.11 -
   34.12 -#include <linux/kernel.h>
   34.13 -#include <linux/spinlock.h>
   34.14 -#include <xen/balloon.h>
   34.15 -#include <linux/kernel.h>
   34.16 -#include <linux/fs.h>
   34.17 -#include <linux/mm.h>
   34.18 -#include <linux/miscdevice.h>
   34.19 -#include <linux/errno.h>
   34.20 -#include <linux/major.h>
   34.21 -#include <linux/gfp.h>
   34.22 -#include <linux/poll.h>
   34.23 -#include <asm/tlbflush.h>
   34.24 -#include "common.h"
   34.25 -
   34.26 -/* Only one process may open /dev/xen/blktap at any time. */
   34.27 -static unsigned long blktap_dev_inuse;
   34.28 -unsigned long blktap_ring_ok; /* make this ring->state */
   34.29 -
   34.30 -/* Rings up to user space. */
   34.31 -static blkif_front_ring_t blktap_ufe_ring;
   34.32 -
   34.33 -/* for poll: */
   34.34 -static wait_queue_head_t blktap_wait;
   34.35 -
   34.36 -/* current switching mode */
   34.37 -static unsigned long blktap_mode;
   34.38 -
   34.39 -/* local prototypes */
   34.40 -static int blktap_read_ufe_ring(void);
   34.41 -
   34.42 -
   34.43 -/* /dev/xen/blktap resides at device number major=10, minor=200        */ 
   34.44 -#define BLKTAP_MINOR 202
   34.45 -
   34.46 -/* blktap IOCTLs:                                                      */
   34.47 -#define BLKTAP_IOCTL_KICK_FE         1
   34.48 -#define BLKTAP_IOCTL_KICK_BE         2 /* currently unused */
   34.49 -#define BLKTAP_IOCTL_SETMODE         3
   34.50 -#define BLKTAP_IOCTL_PRINT_IDXS      100  
   34.51 -
   34.52 -/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
   34.53 -#define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
   34.54 -#define BLKTAP_MODE_INTERCEPT_FE     0x00000001
   34.55 -#define BLKTAP_MODE_INTERCEPT_BE     0x00000002  /* unimp. */
   34.56 -#define BLKTAP_MODE_COPY_FE          0x00000004  /* unimp. */
   34.57 -#define BLKTAP_MODE_COPY_BE          0x00000008  /* unimp. */
   34.58 -#define BLKTAP_MODE_COPY_FE_PAGES    0x00000010  /* unimp. */
   34.59 -#define BLKTAP_MODE_COPY_BE_PAGES    0x00000020  /* unimp. */
   34.60 -
   34.61 -#define BLKTAP_MODE_INTERPOSE \
   34.62 -           (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
   34.63 -
   34.64 -#define BLKTAP_MODE_COPY_BOTH \
   34.65 -           (BLKTAP_MODE_COPY_FE | BLKTAP_MODE_COPY_BE)
   34.66 -
   34.67 -#define BLKTAP_MODE_COPY_BOTH_PAGES \
   34.68 -           (BLKTAP_MODE_COPY_FE_PAGES | BLKTAP_MODE_COPY_BE_PAGES)
   34.69 -
   34.70 -static inline int BLKTAP_MODE_VALID(unsigned long arg)
   34.71 -{
   34.72 -	return ((arg == BLKTAP_MODE_PASSTHROUGH ) ||
   34.73 -		(arg == BLKTAP_MODE_INTERCEPT_FE) ||
   34.74 -		(arg == BLKTAP_MODE_INTERPOSE   ));
   34.75 -/*
   34.76 -  return (
   34.77 -  ( arg == BLKTAP_MODE_PASSTHROUGH  ) ||
   34.78 -  ( arg == BLKTAP_MODE_INTERCEPT_FE ) ||
   34.79 -  ( arg == BLKTAP_MODE_INTERCEPT_BE ) ||
   34.80 -  ( arg == BLKTAP_MODE_INTERPOSE    ) ||
   34.81 -  ( (arg & ~BLKTAP_MODE_COPY_FE_PAGES) == BLKTAP_MODE_COPY_FE ) ||
   34.82 -  ( (arg & ~BLKTAP_MODE_COPY_BE_PAGES) == BLKTAP_MODE_COPY_BE ) ||
   34.83 -  ( (arg & ~BLKTAP_MODE_COPY_BOTH_PAGES) == BLKTAP_MODE_COPY_BOTH )
   34.84 -  );
   34.85 -*/
   34.86 -}
   34.87 -
   34.88 -
   34.89 -/******************************************************************
   34.90 - * MMAP REGION
   34.91 - */
   34.92 -
   34.93 -/*
   34.94 - * We use a big chunk of address space to map in-flight requests into,
   34.95 - * and export this region up to user-space.  See the comments in blkback
   34.96 - * about this -- the two must be kept in sync if the tap is used as a 
   34.97 - * passthrough.
   34.98 - */
   34.99 -
  34.100 -#define MAX_PENDING_REQS 64
  34.101 -#define BATCH_PER_DOMAIN 16
  34.102 -
  34.103 -/* immediately before the mmap area, we have a bunch of pages reserved
  34.104 - * for shared memory rings.
  34.105 - */
  34.106 -#define RING_PAGES 1 /* Front */ 
  34.107 -
  34.108 -/* Where things are inside the device mapping. */
  34.109 -struct vm_area_struct *blktap_vma = NULL;
  34.110 -unsigned long mmap_vstart;  /* Kernel pages for mapping in data. */
  34.111 -unsigned long rings_vstart; /* start of mmaped vma               */
  34.112 -unsigned long user_vstart;  /* start of user mappings            */
  34.113 -
  34.114 -#define MMAP_PAGES						\
  34.115 -	(MAX_PENDING_REQS * BLKIF_MAX_SEGMENTS_PER_REQUEST)
  34.116 -#define MMAP_VADDR(_start, _req,_seg)					\
  34.117 -	(_start +							\
  34.118 -	 ((_req) * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE) +	\
  34.119 -	 ((_seg) * PAGE_SIZE))
  34.120 -
  34.121 -/*
  34.122 - * Each outstanding request that we've passed to the lower device layers has a 
  34.123 - * 'pending_req' allocated to it. Each buffer_head that completes decrements 
  34.124 - * the pendcnt towards zero. When it hits zero, the specified domain has a 
  34.125 - * response queued for it, with the saved 'id' passed back.
  34.126 - */
  34.127 -typedef struct {
  34.128 -	blkif_t       *blkif;
  34.129 -	unsigned long  id;
  34.130 -	int            nr_pages;
  34.131 -	atomic_t       pendcnt;
  34.132 -	unsigned short operation;
  34.133 -	int            status;
  34.134 -} pending_req_t;
  34.135 -
  34.136 -/*
  34.137 - * We can't allocate pending_req's in order, since they may complete out of 
  34.138 - * order. We therefore maintain an allocation ring. This ring also indicates 
  34.139 - * when enough work has been passed down -- at that point the allocation ring 
  34.140 - * will be empty.
  34.141 - */
  34.142 -static pending_req_t pending_reqs[MAX_PENDING_REQS];
  34.143 -static unsigned char pending_ring[MAX_PENDING_REQS];
  34.144 -static DEFINE_SPINLOCK(pend_prod_lock);
  34.145 -/* NB. We use a different index type to differentiate from shared blk rings. */
  34.146 -typedef unsigned int PEND_RING_IDX;
  34.147 -#define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
  34.148 -static PEND_RING_IDX pending_prod, pending_cons;
  34.149 -#define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons)
  34.150 -
  34.151 -/* Requests passing through the tap to the backend hijack the id field
  34.152 - * in the request message.  In it we put the AR index _AND_ the fe domid.
  34.153 - * the domid is used by the backend to map the pages properly.
  34.154 - */
  34.155 -
  34.156 -static inline unsigned long MAKE_ID(domid_t fe_dom, PEND_RING_IDX idx)
  34.157 -{
  34.158 -	return ((fe_dom << 16) | MASK_PEND_IDX(idx));
  34.159 -}
  34.160 -
  34.161 -extern inline PEND_RING_IDX ID_TO_IDX(unsigned long id) 
  34.162 -{ 
  34.163 -	return (PEND_RING_IDX)(id & 0x0000ffff);
  34.164 -}
  34.165 -
  34.166 -extern inline domid_t ID_TO_DOM(unsigned long id) 
  34.167 -{ 
  34.168 -	return (domid_t)(id >> 16); 
  34.169 -}
  34.170 -
  34.171 -
  34.172 -
  34.173 -/******************************************************************
  34.174 - * GRANT HANDLES
  34.175 - */
  34.176 -
  34.177 -/* When using grant tables to map a frame for device access then the
  34.178 - * handle returned must be used to unmap the frame. This is needed to
  34.179 - * drop the ref count on the frame.
  34.180 - */
  34.181 -struct grant_handle_pair
  34.182 -{
  34.183 -	grant_handle_t kernel;
  34.184 -	grant_handle_t user;
  34.185 -};
  34.186 -static struct grant_handle_pair pending_grant_handles[MMAP_PAGES];
  34.187 -#define pending_handle(_idx, _i) \
  34.188 -    (pending_grant_handles[((_idx) * BLKIF_MAX_SEGMENTS_PER_REQUEST) + (_i)])
  34.189 -#define BLKTAP_INVALID_HANDLE(_g) \
  34.190 -    (((_g->kernel) == 0xFFFF) && ((_g->user) == 0xFFFF))
  34.191 -#define BLKTAP_INVALIDATE_HANDLE(_g) do {       \
  34.192 -    (_g)->kernel = 0xFFFF; (_g)->user = 0xFFFF; \
  34.193 -    } while(0)
  34.194 -
  34.195 -
  34.196 -/******************************************************************
  34.197 - * BLKTAP VM OPS
  34.198 - */
  34.199 -
  34.200 -static struct page *blktap_nopage(struct vm_area_struct *vma,
  34.201 -				  unsigned long address,
  34.202 -				  int *type)
  34.203 -{
  34.204 -	/*
  34.205 -	 * if the page has not been mapped in by the driver then generate
  34.206 -	 * a SIGBUS to the domain.
  34.207 -	 */
  34.208 -	force_sig(SIGBUS, current);
  34.209 -
  34.210 -	return 0;
  34.211 -}
  34.212 -
  34.213 -struct vm_operations_struct blktap_vm_ops = {
  34.214 -	.nopage = blktap_nopage,
  34.215 -};
  34.216 -
  34.217 -/******************************************************************
  34.218 - * BLKTAP FILE OPS
  34.219 - */
  34.220 -
  34.221 -static int blktap_open(struct inode *inode, struct file *filp)
  34.222 -{
  34.223 -	blkif_sring_t *sring;
  34.224 -
  34.225 -	if (test_and_set_bit(0, &blktap_dev_inuse))
  34.226 -		return -EBUSY;
  34.227 -    
  34.228 -	/* Allocate the fe ring. */
  34.229 -	sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
  34.230 -	if (sring == NULL)
  34.231 -		return -ENOMEM;
  34.232 -
  34.233 -	SetPageReserved(virt_to_page(sring));
  34.234 -    
  34.235 -	SHARED_RING_INIT(sring);
  34.236 -	FRONT_RING_INIT(&blktap_ufe_ring, sring, PAGE_SIZE);
  34.237 -
  34.238 -	return 0;
  34.239 -}
  34.240 -
  34.241 -static int blktap_release(struct inode *inode, struct file *filp)
  34.242 -{
  34.243 -	blktap_dev_inuse = 0;
  34.244 -	blktap_ring_ok = 0;
  34.245 -
  34.246 -	/* Free the ring page. */
  34.247 -	ClearPageReserved(virt_to_page(blktap_ufe_ring.sring));
  34.248 -	free_page((unsigned long) blktap_ufe_ring.sring);
  34.249 -
  34.250 -	/* Clear any active mappings and free foreign map table */
  34.251 -	if (blktap_vma != NULL) {
  34.252 -		zap_page_range(
  34.253 -			blktap_vma, blktap_vma->vm_start, 
  34.254 -			blktap_vma->vm_end - blktap_vma->vm_start, NULL);
  34.255 -		blktap_vma = NULL;
  34.256 -	}
  34.257 -
  34.258 -	return 0;
  34.259 -}
  34.260 -
  34.261 -
  34.262 -/* Note on mmap:
  34.263 - * We need to map pages to user space in a way that will allow the block
  34.264 - * subsystem set up direct IO to them.  This couldn't be done before, because
  34.265 - * there isn't really a sane way to translate a user virtual address down to a 
  34.266 - * physical address when the page belongs to another domain.
  34.267 - *
  34.268 - * My first approach was to map the page in to kernel memory, add an entry
  34.269 - * for it in the physical frame list (using alloc_lomem_region as in blkback)
  34.270 - * and then attempt to map that page up to user space.  This is disallowed
  34.271 - * by xen though, which realizes that we don't really own the machine frame
  34.272 - * underlying the physical page.
  34.273 - *
  34.274 - * The new approach is to provide explicit support for this in xen linux.
  34.275 - * The VMA now has a flag, VM_FOREIGN, to indicate that it contains pages
  34.276 - * mapped from other vms.  vma->vm_private_data is set up as a mapping 
  34.277 - * from pages to actual page structs.  There is a new clause in get_user_pages
  34.278 - * that does the right thing for this sort of mapping.
  34.279 - */
  34.280 -static int blktap_mmap(struct file *filp, struct vm_area_struct *vma)
  34.281 -{
  34.282 -	int size;
  34.283 -	struct page **map;
  34.284 -	int i;
  34.285 -
  34.286 -	DPRINTK(KERN_ALERT "blktap mmap (%lx, %lx)\n",
  34.287 -		vma->vm_start, vma->vm_end);
  34.288 -
  34.289 -	vma->vm_flags |= VM_RESERVED;
  34.290 -	vma->vm_ops = &blktap_vm_ops;
  34.291 -
  34.292 -	size = vma->vm_end - vma->vm_start;
  34.293 -	if (size != ((MMAP_PAGES + RING_PAGES) << PAGE_SHIFT)) {
  34.294 -		printk(KERN_INFO 
  34.295 -		       "blktap: you _must_ map exactly %d pages!\n",
  34.296 -		       MMAP_PAGES + RING_PAGES);
  34.297 -		return -EAGAIN;
  34.298 -	}
  34.299 -
  34.300 -	size >>= PAGE_SHIFT;
  34.301 -	DPRINTK(KERN_INFO "blktap: 2 rings + %d pages.\n", size-1);
  34.302 -    
  34.303 -	rings_vstart = vma->vm_start;
  34.304 -	user_vstart  = rings_vstart + (RING_PAGES << PAGE_SHIFT);
  34.305 -    
  34.306 -	/* Map the ring pages to the start of the region and reserve it. */
  34.307 -
  34.308 -	/* not sure if I really need to do this... */
  34.309 -	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  34.310 -
  34.311 -	if (remap_pfn_range(vma, vma->vm_start, 
  34.312 -			    __pa(blktap_ufe_ring.sring) >> PAGE_SHIFT, 
  34.313 -			    PAGE_SIZE, vma->vm_page_prot)) {
  34.314 -		WPRINTK("Mapping user ring failed!\n");
  34.315 -		goto fail;
  34.316 -	}
  34.317 -
  34.318 -	/* Mark this VM as containing foreign pages, and set up mappings. */
  34.319 -	map = kmalloc(((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)
  34.320 -		      * sizeof(struct page_struct*),
  34.321 -		      GFP_KERNEL);
  34.322 -	if (map == NULL) {
  34.323 -		WPRINTK("Couldn't alloc VM_FOREIGH map.\n");
  34.324 -		goto fail;
  34.325 -	}
  34.326 -
  34.327 -	for (i = 0; i < ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); i++)
  34.328 -		map[i] = NULL;
  34.329 -    
  34.330 -	vma->vm_private_data = map;
  34.331 -	vma->vm_flags |= VM_FOREIGN;
  34.332 -
  34.333 -	blktap_vma = vma;
  34.334 -	blktap_ring_ok = 1;
  34.335 -
  34.336 -	return 0;
  34.337 - fail:
  34.338 -	/* Clear any active mappings. */
  34.339 -	zap_page_range(vma, vma->vm_start, 
  34.340 -		       vma->vm_end - vma->vm_start, NULL);
  34.341 -
  34.342 -	return -ENOMEM;
  34.343 -}
  34.344 -
  34.345 -static int blktap_ioctl(struct inode *inode, struct file *filp,
  34.346 -                        unsigned int cmd, unsigned long arg)
  34.347 -{
  34.348 -	switch(cmd) {
  34.349 -	case BLKTAP_IOCTL_KICK_FE: /* There are fe messages to process. */
  34.350 -		return blktap_read_ufe_ring();
  34.351 -
  34.352 -	case BLKTAP_IOCTL_SETMODE:
  34.353 -		if (BLKTAP_MODE_VALID(arg)) {
  34.354 -			blktap_mode = arg;
  34.355 -			/* XXX: may need to flush rings here. */
  34.356 -			printk(KERN_INFO "blktap: set mode to %lx\n", arg);
  34.357 -			return 0;
  34.358 -		}
  34.359 -	case BLKTAP_IOCTL_PRINT_IDXS:
  34.360 -        {
  34.361 -		//print_fe_ring_idxs();
  34.362 -		WPRINTK("User Rings: \n-----------\n");
  34.363 -		WPRINTK("UF: rsp_cons: %2d, req_prod_prv: %2d "
  34.364 -			"| req_prod: %2d, rsp_prod: %2d\n",
  34.365 -			blktap_ufe_ring.rsp_cons,
  34.366 -			blktap_ufe_ring.req_prod_pvt,
  34.367 -			blktap_ufe_ring.sring->req_prod,
  34.368 -			blktap_ufe_ring.sring->rsp_prod);
  34.369 -            
  34.370 -        }
  34.371 -	}
  34.372 -	return -ENOIOCTLCMD;
  34.373 -}
  34.374 -
  34.375 -static unsigned int blktap_poll(struct file *file, poll_table *wait)
  34.376 -{
  34.377 -	poll_wait(file, &blktap_wait, wait);
  34.378 -	if (blktap_ufe_ring.req_prod_pvt != blktap_ufe_ring.sring->req_prod) {
  34.379 -		flush_tlb_all();
  34.380 -		RING_PUSH_REQUESTS(&blktap_ufe_ring);
  34.381 -		return POLLIN | POLLRDNORM;
  34.382 -	}
  34.383 -
  34.384 -	return 0;
  34.385 -}
  34.386 -
  34.387 -void blktap_kick_user(void)
  34.388 -{
  34.389 -	/* blktap_ring->req_prod = blktap_req_prod; */
  34.390 -	wake_up_interruptible(&blktap_wait);
  34.391 -}
  34.392 -
  34.393 -static struct file_operations blktap_fops = {
  34.394 -	.owner   = THIS_MODULE,
  34.395 -	.poll    = blktap_poll,
  34.396 -	.ioctl   = blktap_ioctl,
  34.397 -	.open    = blktap_open,
  34.398 -	.release = blktap_release,
  34.399 -	.mmap    = blktap_mmap,
  34.400 -};
  34.401 -
  34.402 -
  34.403 -
  34.404 -static int do_block_io_op(blkif_t *blkif, int max_to_do);
  34.405 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req);
  34.406 -static void make_response(blkif_t *blkif, unsigned long id, 
  34.407 -                          unsigned short op, int st);
  34.408 -
  34.409 -
  34.410 -static void fast_flush_area(int idx, int nr_pages)
  34.411 -{
  34.412 -	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
  34.413 -	unsigned int i, op = 0;
  34.414 -	struct grant_handle_pair *handle;
  34.415 -	uint64_t ptep;
  34.416 -	int ret;
  34.417 -
  34.418 -	for ( i = 0; i < nr_pages; i++)
  34.419 -	{
  34.420 -		handle = &pending_handle(idx, i);
  34.421 -		if (BLKTAP_INVALID_HANDLE(handle))
  34.422 -			continue;
  34.423 -
  34.424 -		gnttab_set_unmap_op(&unmap[op],
  34.425 -				    MMAP_VADDR(mmap_vstart, idx, i),
  34.426 -				    GNTMAP_host_map, handle->kernel);
  34.427 -		op++;
  34.428 -
  34.429 -		if (create_lookup_pte_addr(
  34.430 -			    blktap_vma->vm_mm,
  34.431 -			    MMAP_VADDR(user_vstart, idx, i), 
  34.432 -			    &ptep) !=0) {
  34.433 -			DPRINTK("Couldn't get a pte addr!\n");
  34.434 -			return;
  34.435 -		}
  34.436 -		gnttab_set_unmap_grnat_ref(&unmap[op], ptep,
  34.437 -					   GNTMAP_host_map |
  34.438 -					   GNTMAP_application_map |
  34.439 -					   GNTMAP_contains_pte, handle->user);
  34.440 -		op++;
  34.441 -            
  34.442 -		BLKTAP_INVALIDATE_HANDLE(handle);
  34.443 -	}
  34.444 -
  34.445 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, op);
  34.446 -	BUG_ON(ret);
  34.447 -
  34.448 -	if (blktap_vma != NULL)
  34.449 -		zap_page_range(blktap_vma, 
  34.450 -			       MMAP_VADDR(user_vstart, idx, 0), 
  34.451 -			       nr_pages << PAGE_SHIFT, NULL);
  34.452 -}
  34.453 -
  34.454 -/******************************************************************
  34.455 - * BLOCK-DEVICE SCHEDULER LIST MAINTENANCE
  34.456 - */
  34.457 -
  34.458 -static struct list_head blkio_schedule_list;
  34.459 -static spinlock_t blkio_schedule_list_lock;
  34.460 -
  34.461 -static int __on_blkdev_list(blkif_t *blkif)
  34.462 -{
  34.463 -	return blkif->blkdev_list.next != NULL;
  34.464 -}
  34.465 -
  34.466 -static void remove_from_blkdev_list(blkif_t *blkif)
  34.467 -{
  34.468 -	unsigned long flags;
  34.469 -
  34.470 -	if (!__on_blkdev_list(blkif))
  34.471 -		return;
  34.472 -
  34.473 -	spin_lock_irqsave(&blkio_schedule_list_lock, flags);
  34.474 -	if (__on_blkdev_list(blkif)) {
  34.475 -		list_del(&blkif->blkdev_list);
  34.476 -		blkif->blkdev_list.next = NULL;
  34.477 -		blkif_put(blkif);
  34.478 -	}
  34.479 -	spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
  34.480 -}
  34.481 -
  34.482 -static void add_to_blkdev_list_tail(blkif_t *blkif)
  34.483 -{
  34.484 -	unsigned long flags;
  34.485 -
  34.486 -	if (__on_blkdev_list(blkif))
  34.487 -		return;
  34.488 -
  34.489 -	spin_lock_irqsave(&blkio_schedule_list_lock, flags);
  34.490 -	if (!__on_blkdev_list(blkif) && (blkif->status == CONNECTED)) {
  34.491 -		list_add_tail(&blkif->blkdev_list, &blkio_schedule_list);
  34.492 -		blkif_get(blkif);
  34.493 -	}
  34.494 -	spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
  34.495 -}
  34.496 -
  34.497 -
  34.498 -/******************************************************************
  34.499 - * SCHEDULER FUNCTIONS
  34.500 - */
  34.501 -
  34.502 -static DECLARE_WAIT_QUEUE_HEAD(blkio_schedule_wait);
  34.503 -
  34.504 -static int blkio_schedule(void *arg)
  34.505 -{
  34.506 -	DECLARE_WAITQUEUE(wq, current);
  34.507 -
  34.508 -	blkif_t          *blkif;
  34.509 -	struct list_head *ent;
  34.510 -
  34.511 -	daemonize("xenblkd");
  34.512 -
  34.513 -	for (;;) {
  34.514 -		/* Wait for work to do. */
  34.515 -		add_wait_queue(&blkio_schedule_wait, &wq);
  34.516 -		set_current_state(TASK_INTERRUPTIBLE);
  34.517 -		if ((NR_PENDING_REQS == MAX_PENDING_REQS) || 
  34.518 -		    list_empty(&blkio_schedule_list))
  34.519 -			schedule();
  34.520 -		__set_current_state(TASK_RUNNING);
  34.521 -		remove_wait_queue(&blkio_schedule_wait, &wq);
  34.522 -
  34.523 -		/* Queue up a batch of requests. */
  34.524 -		while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
  34.525 -		       !list_empty(&blkio_schedule_list)) {
  34.526 -			ent = blkio_schedule_list.next;
  34.527 -			blkif = list_entry(ent, blkif_t, blkdev_list);
  34.528 -			blkif_get(blkif);
  34.529 -			remove_from_blkdev_list(blkif);
  34.530 -			if (do_block_io_op(blkif, BATCH_PER_DOMAIN))
  34.531 -				add_to_blkdev_list_tail(blkif);
  34.532 -			blkif_put(blkif);
  34.533 -		}
  34.534 -	}
  34.535 -}
  34.536 -
  34.537 -static void maybe_trigger_blkio_schedule(void)
  34.538 -{
  34.539 -	/*
  34.540 -	 * Needed so that two processes, who together make the following
  34.541 -	 * predicate true, don't both read stale values and evaluate the
  34.542 -	 * predicate incorrectly. Incredibly unlikely to stall the scheduler
  34.543 -	 * on the x86, but...
  34.544 -	 */
  34.545 -	smp_mb();
  34.546 -
  34.547 -	if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
  34.548 -	    !list_empty(&blkio_schedule_list))
  34.549 -		wake_up(&blkio_schedule_wait);
  34.550 -}
  34.551 -
  34.552 -
  34.553 -
  34.554 -/******************************************************************
  34.555 - * COMPLETION CALLBACK -- Called as bh->b_end_io()
  34.556 - */
  34.557 -
  34.558 -
  34.559 -static int blktap_read_ufe_ring(void)
  34.560 -{
  34.561 -	/* This is called to read responses from the UFE ring. */
  34.562 -
  34.563 -	RING_IDX i, j, rp;
  34.564 -	blkif_response_t *resp;
  34.565 -	blkif_t *blkif;
  34.566 -	int pending_idx;
  34.567 -	pending_req_t *pending_req;
  34.568 -	unsigned long     flags;
  34.569 -
  34.570 -	/* if we are forwarding from UFERring to FERing */
  34.571 -	if (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) {
  34.572 -
  34.573 -		/* for each outstanding message on the UFEring  */
  34.574 -		rp = blktap_ufe_ring.sring->rsp_prod;
  34.575 -		rmb();
  34.576 -        
  34.577 -		for (i = blktap_ufe_ring.rsp_cons; i != rp; i++) {
  34.578 -			resp = RING_GET_RESPONSE(&blktap_ufe_ring, i);
  34.579 -			pending_idx = MASK_PEND_IDX(ID_TO_IDX(resp->id));
  34.580 -			pending_req = &pending_reqs[pending_idx];
  34.581 -            
  34.582 -			blkif = pending_req->blkif;
  34.583 -			for (j = 0; j < pending_req->nr_pages; j++) {
  34.584 -				unsigned long vaddr;
  34.585 -				struct page **map = blktap_vma->vm_private_data;
  34.586 -				int offset; 
  34.587 -
  34.588 -				vaddr  = MMAP_VADDR(user_vstart, pending_idx, j);
  34.589 -				offset = (vaddr - blktap_vma->vm_start) >> PAGE_SHIFT;
  34.590 -
  34.591 -				//ClearPageReserved(virt_to_page(vaddr));
  34.592 -				ClearPageReserved((struct page *)map[offset]);
  34.593 -				map[offset] = NULL;
  34.594 -			}
  34.595 -
  34.596 -			fast_flush_area(pending_idx, pending_req->nr_pages);
  34.597 -			make_response(blkif, pending_req->id, resp->operation, 
  34.598 -				      resp->status);
  34.599 -			blkif_put(pending_req->blkif);
  34.600 -			spin_lock_irqsave(&pend_prod_lock, flags);
  34.601 -			pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
  34.602 -			spin_unlock_irqrestore(&pend_prod_lock, flags);
  34.603 -		}
  34.604 -		blktap_ufe_ring.rsp_cons = i;
  34.605 -		maybe_trigger_blkio_schedule();
  34.606 -	}
  34.607 -	return 0;
  34.608 -}
  34.609 -
  34.610 -
  34.611 -/******************************************************************************
  34.612 - * NOTIFICATION FROM GUEST OS.
  34.613 - */
  34.614 -
  34.615 -irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
  34.616 -{
  34.617 -	blkif_t *blkif = dev_id;
  34.618 -	add_to_blkdev_list_tail(blkif);
  34.619 -	maybe_trigger_blkio_schedule();
  34.620 -	return IRQ_HANDLED;
  34.621 -}
  34.622 -
  34.623 -
  34.624 -
  34.625 -/******************************************************************
  34.626 - * DOWNWARD CALLS -- These interface with the block-device layer proper.
  34.627 - */
  34.628 -
  34.629 -static int do_block_io_op(blkif_t *blkif, int max_to_do)
  34.630 -{
  34.631 -	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
  34.632 -	blkif_request_t *req;
  34.633 -	RING_IDX i, rp;
  34.634 -	int more_to_do = 0;
  34.635 -    
  34.636 -	rp = blk_ring->sring->req_prod;
  34.637 -	rmb(); /* Ensure we see queued requests up to 'rp'. */
  34.638 -
  34.639 -	for (i = blk_ring->req_cons; 
  34.640 -	     (i != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, i);
  34.641 -	     i++ ) {
  34.642 -		if ((max_to_do-- == 0) ||
  34.643 -		    (NR_PENDING_REQS == MAX_PENDING_REQS)) {
  34.644 -			more_to_do = 1;
  34.645 -			break;
  34.646 -		}
  34.647 -        
  34.648 -		req = RING_GET_REQUEST(blk_ring, i);
  34.649 -		switch (req->operation) {
  34.650 -		case BLKIF_OP_READ:
  34.651 -		case BLKIF_OP_WRITE:
  34.652 -			dispatch_rw_block_io(blkif, req);
  34.653 -			break;
  34.654 -
  34.655 -		default:
  34.656 -			DPRINTK("error: unknown block io operation [%d]\n",
  34.657 -				req->operation);
  34.658 -			make_response(blkif, req->id, req->operation,
  34.659 -				      BLKIF_RSP_ERROR);
  34.660 -			break;
  34.661 -		}
  34.662 -	}
  34.663 -
  34.664 -	blk_ring->req_cons = i;
  34.665 -	blktap_kick_user();
  34.666 -
  34.667 -	return more_to_do;
  34.668 -}
  34.669 -
  34.670 -static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req)
  34.671 -{
  34.672 -	blkif_request_t *target;
  34.673 -	int i, pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
  34.674 -	pending_req_t *pending_req;
  34.675 -	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
  34.676 -	int op, ret;
  34.677 -	unsigned int nseg;
  34.678 -	int retval;
  34.679 -
  34.680 -	/* Check that number of segments is sane. */
  34.681 -	nseg = req->nr_segments;
  34.682 -	if (unlikely(nseg == 0) || 
  34.683 -	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
  34.684 -		DPRINTK("Bad number of segments in request (%d)\n", nseg);
  34.685 -		goto bad_descriptor;
  34.686 -	}
  34.687 -
  34.688 -	/* Make sure userspace is ready. */
  34.689 -	if (!blktap_ring_ok) {
  34.690 -		DPRINTK("blktap: ring not ready for requests!\n");
  34.691 -		goto bad_descriptor;
  34.692 -	}
  34.693 -    
  34.694 -
  34.695 -	if (RING_FULL(&blktap_ufe_ring)) {
  34.696 -		WPRINTK("blktap: fe_ring is full, can't add "
  34.697 -			"(very broken!).\n");
  34.698 -		goto bad_descriptor;
  34.699 -	}
  34.700 -
  34.701 -	flush_cache_all(); /* a noop on intel... */
  34.702 -
  34.703 -	/* Map the foreign pages directly in to the application */    
  34.704 -	op = 0;
  34.705 -	for (i = 0; i < req->nr_segments; i++) {
  34.706 -
  34.707 -		unsigned long uvaddr;
  34.708 -		unsigned long kvaddr;
  34.709 -		uint64_t ptep;
  34.710 -		uint32_t flags;
  34.711 -
  34.712 -		uvaddr = MMAP_VADDR(user_vstart, pending_idx, i);
  34.713 -		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i);
  34.714 -
  34.715 -		flags = GNTMAP_host_map;
  34.716 -		/* This needs a bit more thought in terms of interposition: 
  34.717 -		 * If we want to be able to modify pages during write using 
  34.718 -		 * grant table mappings, the guest will either need to allow 
  34.719 -		 * it, or we'll need to incur a copy. Bit of an fbufs moment. ;) */
  34.720 -		if (req->operation == BLKIF_OP_WRITE)
  34.721 -			flags |= GNTMAP_readonly;
  34.722 -		/* Map the remote page to kernel. */
  34.723 -		gnttab_set_map_op(&map[op], kvaddr, flags, req->seg[i].gref,
  34.724 -				  blkif->domid);
  34.725 -		op++;
  34.726 -
  34.727 -		/* Now map it to user. */
  34.728 -		ret = create_lookup_pte_addr(blktap_vma->vm_mm, uvaddr, &ptep);
  34.729 -		if (ret) {
  34.730 -			DPRINTK("Couldn't get a pte addr!\n");
  34.731 -			fast_flush_area(pending_idx, req->nr_segments);
  34.732 -			goto bad_descriptor;
  34.733 -		}
  34.734 -
  34.735 -		flags = GNTMAP_host_map | GNTMAP_application_map
  34.736 -			| GNTMAP_contains_pte;
  34.737 -		/* Above interposition comment applies here as well. */
  34.738 -		if (req->operation == BLKIF_OP_WRITE)
  34.739 -			flags |= GNTMAP_readonly;
  34.740 -		gnttab_set_map_op(&map[op], ptep, flags, req->seg[i].gref,
  34.741 -				  blkif->domid);
  34.742 -		op++;
  34.743 -	}
  34.744 -
  34.745 -	retval = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op);
  34.746 -	BUG_ON(retval);
  34.747 -
  34.748 -	op = 0;
  34.749 -	for (i = 0; i < (req->nr_segments*2); i += 2) {
  34.750 -		unsigned long uvaddr;
  34.751 -		unsigned long kvaddr;
  34.752 -		unsigned long offset;
  34.753 -		int cancel = 0;
  34.754 -
  34.755 -		uvaddr = MMAP_VADDR(user_vstart, pending_idx, i/2);
  34.756 -		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i/2);
  34.757 -
  34.758 -		if (unlikely(map[i].status)) {
  34.759 -			DPRINTK("Error on kernel grant mapping (%d)\n",
  34.760 -				map[i].status);
  34.761 -			ret = map[i].status;
  34.762 -			cancel = 1;
  34.763 -		}
  34.764 -
  34.765 -		if (unlikely(map[i+1].status)) {
  34.766 -			DPRINTK("Error on user grant mapping (%d)\n",
  34.767 -				map[i+1].status);
  34.768 -			ret = map[i+1].status;
  34.769 -			cancel = 1;
  34.770 -		}
  34.771 -
  34.772 -		if (cancel) {
  34.773 -			fast_flush_area(pending_idx, req->nr_segments);
  34.774 -			goto bad_descriptor;
  34.775 -		}
  34.776 -
  34.777 -		/* Set the necessary mappings in p2m and in the VM_FOREIGN 
  34.778 -		 * vm_area_struct to allow user vaddr -> struct page lookups
  34.779 -		 * to work.  This is needed for direct IO to foreign pages. */
  34.780 -		set_phys_to_machine(__pa(kvaddr) >> PAGE_SHIFT,
  34.781 -				FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
  34.782 -
  34.783 -		offset = (uvaddr - blktap_vma->vm_start) >> PAGE_SHIFT;
  34.784 -		((struct page **)blktap_vma->vm_private_data)[offset] =
  34.785 -			pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT);
  34.786 -
  34.787 -		/* Save handles for unmapping later. */
  34.788 -		pending_handle(pending_idx, i/2).kernel = map[i].handle;
  34.789 -		pending_handle(pending_idx, i/2).user   = map[i+1].handle;
  34.790 -	}
  34.791 -
  34.792 -	/* Mark mapped pages as reserved: */
  34.793 -	for (i = 0; i < req->nr_segments; i++) {
  34.794 -		unsigned long kvaddr;
  34.795 -		kvaddr = MMAP_VADDR(mmap_vstart, pending_idx, i);
  34.796 -		SetPageReserved(pfn_to_page(__pa(kvaddr) >> PAGE_SHIFT));
  34.797 -	}
  34.798 -
  34.799 -	pending_req = &pending_reqs[pending_idx];
  34.800 -	pending_req->blkif     = blkif;
  34.801 -	pending_req->id        = req->id;
  34.802 -	pending_req->operation = req->operation;
  34.803 -	pending_req->status    = BLKIF_RSP_OKAY;
  34.804 -	pending_req->nr_pages  = nseg;
  34.805 -	req->id = MAKE_ID(blkif->domid, pending_idx);
  34.806 -	//atomic_set(&pending_req->pendcnt, nbio);
  34.807 -	pending_cons++;
  34.808 -	blkif_get(blkif);
  34.809 -
  34.810 -	/* Finally, write the request message to the user ring. */
  34.811 -	target = RING_GET_REQUEST(&blktap_ufe_ring,
  34.812 -				  blktap_ufe_ring.req_prod_pvt);
  34.813 -	memcpy(target, req, sizeof(*req));
  34.814 -	blktap_ufe_ring.req_prod_pvt++;
  34.815 -	return;
  34.816 -
  34.817 - bad_descriptor:
  34.818 -	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
  34.819 -} 
  34.820 -
  34.821 -
  34.822 -
  34.823 -/******************************************************************
  34.824 - * MISCELLANEOUS SETUP / TEARDOWN / DEBUGGING
  34.825 - */
  34.826 -
  34.827 -
  34.828 -static void make_response(blkif_t *blkif, unsigned long id, 
  34.829 -                          unsigned short op, int st)
  34.830 -{
  34.831 -	blkif_response_t *resp;
  34.832 -	unsigned long     flags;
  34.833 -	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
  34.834 -
  34.835 -	/* Place on the response ring for the relevant domain. */ 
  34.836 -	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
  34.837 -	resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
  34.838 -	resp->id        = id;
  34.839 -	resp->operation = op;
  34.840 -	resp->status    = st;
  34.841 -	wmb(); /* Ensure other side can see the response fields. */
  34.842 -	blk_ring->rsp_prod_pvt++;
  34.843 -	RING_PUSH_RESPONSES(blk_ring);
  34.844 -	spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
  34.845 -
  34.846 -	/* Kick the relevant domain. */
  34.847 -	notify_remote_via_irq(blkif->irq);
  34.848 -}
  34.849 -
  34.850 -static struct miscdevice blktap_miscdev = {
  34.851 -	.minor        = BLKTAP_MINOR,
  34.852 -	.name         = "blktap",
  34.853 -	.fops         = &blktap_fops,
  34.854 -	.devfs_name   = "misc/blktap",
  34.855 -};
  34.856 -
  34.857 -void blkif_deschedule(blkif_t *blkif)
  34.858 -{
  34.859 -	remove_from_blkdev_list(blkif);
  34.860 -}
  34.861 -
  34.862 -static int __init blkif_init(void)
  34.863 -{
  34.864 -	int i, j, err;
  34.865 -	struct page *page;
  34.866 -
  34.867 -	blkif_interface_init();
  34.868 -
  34.869 -	page = balloon_alloc_empty_page_range(MMAP_PAGES);
  34.870 -	BUG_ON(page == NULL);
  34.871 -	mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
  34.872 -
  34.873 -	pending_cons = 0;
  34.874 -	pending_prod = MAX_PENDING_REQS;
  34.875 -	memset(pending_reqs, 0, sizeof(pending_reqs));
  34.876 -	for ( i = 0; i < MAX_PENDING_REQS; i++ )
  34.877 -		pending_ring[i] = i;
  34.878 -    
  34.879 -	spin_lock_init(&blkio_schedule_list_lock);
  34.880 -	INIT_LIST_HEAD(&blkio_schedule_list);
  34.881 -
  34.882 -	i = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES);
  34.883 -	BUG_ON(i<0);
  34.884 -
  34.885 -	blkif_xenbus_init();
  34.886 -
  34.887 -	for (i = 0; i < MAX_PENDING_REQS ; i++)
  34.888 -		for (j = 0; j < BLKIF_MAX_SEGMENTS_PER_REQUEST; j++)
  34.889 -			BLKTAP_INVALIDATE_HANDLE(&pending_handle(i, j));
  34.890 -
  34.891 -	err = misc_register(&blktap_miscdev);
  34.892 -	if (err != 0) {
  34.893 -		printk(KERN_ALERT "Couldn't register /dev/misc/blktap (%d)\n",
  34.894 -		       err);
  34.895 -		return err;
  34.896 -	}
  34.897 -
  34.898 -	init_waitqueue_head(&blktap_wait);
  34.899 -
  34.900 -	return 0;
  34.901 -}
  34.902 -
  34.903 -__initcall(blkif_init);
    35.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Tue Jun 13 09:00:32 2006 -0600
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,100 +0,0 @@
    35.4 -
    35.5 -#ifndef __BLKIF__BACKEND__COMMON_H__
    35.6 -#define __BLKIF__BACKEND__COMMON_H__
    35.7 -
    35.8 -#include <linux/config.h>
    35.9 -#include <linux/version.h>
   35.10 -#include <linux/module.h>
   35.11 -#include <linux/interrupt.h>
   35.12 -#include <linux/slab.h>
   35.13 -#include <linux/blkdev.h>
   35.14 -#include <linux/vmalloc.h>
   35.15 -#include <asm/io.h>
   35.16 -#include <asm/setup.h>
   35.17 -#include <asm/pgalloc.h>
   35.18 -#include <xen/evtchn.h>
   35.19 -#include <asm/hypervisor.h>
   35.20 -#include <xen/interface/io/blkif.h>
   35.21 -#include <xen/interface/io/ring.h>
   35.22 -#include <xen/gnttab.h>
   35.23 -#include <xen/driver_util.h>
   35.24 -
   35.25 -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
   35.26 -                                    __FILE__ , __LINE__ , ## _a )
   35.27 -
   35.28 -#define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
   35.29 -
   35.30 -struct vbd {
   35.31 -	blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
   35.32 -	unsigned char  readonly;    /* Non-zero -> read-only */
   35.33 -	unsigned char  type;        /* VDISK_xxx */
   35.34 -	u32            pdevice;     /* phys device that this vbd maps to */
   35.35 -	struct block_device *bdev;
   35.36 -}; 
   35.37 -
   35.38 -typedef struct blkif_st {
   35.39 -	/* Unique identifier for this interface. */
   35.40 -	domid_t           domid;
   35.41 -	unsigned int      handle;
   35.42 -	/* Physical parameters of the comms window. */
   35.43 -	unsigned int      evtchn;
   35.44 -	unsigned int      irq;
   35.45 -	/* Comms information. */
   35.46 -	blkif_back_ring_t blk_ring;
   35.47 -	struct vm_struct *blk_ring_area;
   35.48 -	/* VBDs attached to this interface. */
   35.49 -	struct vbd        vbd;
   35.50 -	/* Private fields. */
   35.51 -	enum { DISCONNECTED, CONNECTED } status;
   35.52 -#ifdef CONFIG_XEN_BLKDEV_TAP_BE
   35.53 -	/* Is this a blktap frontend */
   35.54 -	unsigned int     is_blktap;
   35.55 -#endif
   35.56 -	struct list_head blkdev_list;
   35.57 -	spinlock_t       blk_ring_lock;
   35.58 -	atomic_t         refcnt;
   35.59 -
   35.60 -	struct work_struct free_work;
   35.61 -
   35.62 -	grant_handle_t   shmem_handle;
   35.63 -	grant_ref_t      shmem_ref;
   35.64 -} blkif_t;
   35.65 -
   35.66 -blkif_t *alloc_blkif(domid_t domid);
   35.67 -void free_blkif_callback(blkif_t *blkif);
   35.68 -int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
   35.69 -
   35.70 -#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
   35.71 -#define blkif_put(_b)                             \
   35.72 -    do {                                          \
   35.73 -        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
   35.74 -            free_blkif_callback(_b);		  \
   35.75 -    } while (0)
   35.76 -
   35.77 -/* Create a vbd. */
   35.78 -int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, u32 pdevice,
   35.79 -	       int readonly);
   35.80 -void vbd_free(struct vbd *vbd);
   35.81 -
   35.82 -unsigned long vbd_size(struct vbd *vbd);
   35.83 -unsigned int vbd_info(struct vbd *vbd);
   35.84 -unsigned long vbd_secsize(struct vbd *vbd);
   35.85 -
   35.86 -struct phys_req {
   35.87 -	unsigned short       dev;
   35.88 -	unsigned short       nr_sects;
   35.89 -	struct block_device *bdev;
   35.90 -	blkif_sector_t       sector_number;
   35.91 -};
   35.92 -
   35.93 -int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation); 
   35.94 -
   35.95 -void blkif_interface_init(void);
   35.96 -
   35.97 -void blkif_deschedule(blkif_t *blkif);
   35.98 -
   35.99 -void blkif_xenbus_init(void);
  35.100 -
  35.101 -irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
  35.102 -
  35.103 -#endif /* __BLKIF__BACKEND__COMMON_H__ */
    36.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Tue Jun 13 09:00:32 2006 -0600
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,134 +0,0 @@
    36.4 -/******************************************************************************
    36.5 - * arch/xen/drivers/blkif/backend/interface.c
    36.6 - * 
    36.7 - * Block-device interface management.
    36.8 - * 
    36.9 - * Copyright (c) 2004, Keir Fraser
   36.10 - */
   36.11 -
   36.12 -#include "common.h"
   36.13 -#include <xen/evtchn.h>
   36.14 -
   36.15 -static kmem_cache_t *blkif_cachep;
   36.16 -
   36.17 -blkif_t *alloc_blkif(domid_t domid)
   36.18 -{
   36.19 -	blkif_t *blkif;
   36.20 -
   36.21 -	blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
   36.22 -	if (!blkif)
   36.23 -		return ERR_PTR(-ENOMEM);
   36.24 -
   36.25 -	memset(blkif, 0, sizeof(*blkif));
   36.26 -	blkif->domid = domid;
   36.27 -	blkif->status = DISCONNECTED;
   36.28 -	spin_lock_init(&blkif->blk_ring_lock);
   36.29 -	atomic_set(&blkif->refcnt, 1);
   36.30 -
   36.31 -	return blkif;
   36.32 -}
   36.33 -
   36.34 -static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
   36.35 -{
   36.36 -	struct gnttab_map_grant_ref op;
   36.37 -	int ret;
   36.38 -
   36.39 -	gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   36.40 -			  GNTMAP_host_map, shared_page, blkif->domid);
   36.41 -
   36.42 -	lock_vm_area(blkif->blk_ring_area);
   36.43 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
   36.44 -	unlock_vm_area(blkif->blk_ring_area);
   36.45 -	BUG_ON(ret);
   36.46 -
   36.47 -	if (op.status) {
   36.48 -		DPRINTK(" Grant table operation failure !\n");
   36.49 -		return op.status;
   36.50 -	}
   36.51 -
   36.52 -	blkif->shmem_ref    = shared_page;
   36.53 -	blkif->shmem_handle = op.handle;
   36.54 -
   36.55 -	return 0;
   36.56 -}
   36.57 -
   36.58 -static void unmap_frontend_page(blkif_t *blkif)
   36.59 -{
   36.60 -	struct gnttab_unmap_grant_ref op;
   36.61 -	int ret;
   36.62 -
   36.63 -	gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
   36.64 -			    GNTMAP_host_map, blkif->shmem_handle);
   36.65 -
   36.66 -	lock_vm_area(blkif->blk_ring_area);
   36.67 -	ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1);
   36.68 -	unlock_vm_area(blkif->blk_ring_area);
   36.69 -	BUG_ON(ret);
   36.70 -}
   36.71 -
   36.72 -int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
   36.73 -{
   36.74 -	blkif_sring_t *sring;
   36.75 -	int err;
   36.76 -	struct evtchn_bind_interdomain bind_interdomain;
   36.77 -
   36.78 -	if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
   36.79 -		return -ENOMEM;
   36.80 -
   36.81 -	err = map_frontend_page(blkif, shared_page);
   36.82 -	if (err) {
   36.83 -		free_vm_area(blkif->blk_ring_area);
   36.84 -		return err;
   36.85 -	}
   36.86 -
   36.87 -	bind_interdomain.remote_dom  = blkif->domid;
   36.88 -	bind_interdomain.remote_port = evtchn;
   36.89 -
   36.90 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   36.91 -					  &bind_interdomain);
   36.92 -	if (err) {
   36.93 -		unmap_frontend_page(blkif);
   36.94 -		free_vm_area(blkif->blk_ring_area);
   36.95 -		return err;
   36.96 -	}
   36.97 -
   36.98 -	blkif->evtchn = bind_interdomain.local_port;
   36.99 -
  36.100 -	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
  36.101 -	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
  36.102 -
  36.103 -	blkif->irq = bind_evtchn_to_irqhandler(
  36.104 -		blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
  36.105 -
  36.106 -	blkif->status = CONNECTED;
  36.107 -
  36.108 -	return 0;
  36.109 -}
  36.110 -
  36.111 -static void free_blkif(void *arg)
  36.112 -{
  36.113 -	blkif_t *blkif = (blkif_t *)arg;
  36.114 -
  36.115 -	if (blkif->irq)
  36.116 -		unbind_from_irqhandler(blkif->irq, blkif);
  36.117 -
  36.118 -	if (blkif->blk_ring.sring) {
  36.119 -		unmap_frontend_page(blkif);
  36.120 -		free_vm_area(blkif->blk_ring_area);
  36.121 -		blkif->blk_ring.sring = NULL;
  36.122 -	}
  36.123 -
  36.124 -	kmem_cache_free(blkif_cachep, blkif);
  36.125 -}
  36.126 -
  36.127 -void free_blkif_callback(blkif_t *blkif)
  36.128 -{
  36.129 -	INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
  36.130 -	schedule_work(&blkif->free_work);
  36.131 -}
  36.132 -
  36.133 -void __init blkif_interface_init(void)
  36.134 -{
  36.135 -	blkif_cachep = kmem_cache_create(
  36.136 -		"blkif_cache", sizeof(blkif_t), 0, 0, NULL, NULL);
  36.137 -}
    37.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Tue Jun 13 09:00:32 2006 -0600
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,223 +0,0 @@
    37.4 -/*  Xenbus code for blkif tap
    37.5 -
    37.6 -    A Warfield.
    37.7 -
    37.8 -    Hastily modified from the oroginal backend code:
    37.9 -
   37.10 -    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
   37.11 -
   37.12 -    This program is free software; you can redistribute it and/or modify
   37.13 -    it under the terms of the GNU General Public License as published by
   37.14 -    the Free Software Foundation; either version 2 of the License, or
   37.15 -    (at your option) any later version.
   37.16 -
   37.17 -    This program is distributed in the hope that it will be useful,
   37.18 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.19 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.20 -    GNU General Public License for more details.
   37.21 -
   37.22 -    You should have received a copy of the GNU General Public License
   37.23 -    along with this program; if not, write to the Free Software
   37.24 -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   37.25 -*/
   37.26 -
   37.27 -#include <stdarg.h>
   37.28 -#include <linux/module.h>
   37.29 -#include <xen/xenbus.h>
   37.30 -#include "common.h"
   37.31 -
   37.32 -struct backend_info
   37.33 -{
   37.34 -	struct xenbus_device *dev;
   37.35 -
   37.36 -	/* our communications channel */
   37.37 -	blkif_t *blkif;
   37.38 -
   37.39 -	long int frontend_id;
   37.40 -
   37.41 -	/* watch back end for changes */
   37.42 -	struct xenbus_watch backend_watch;
   37.43 -
   37.44 -	/* watch front end for changes */
   37.45 -	struct xenbus_watch watch;
   37.46 -	char *frontpath;
   37.47 -};
   37.48 -
   37.49 -static int blkback_remove(struct xenbus_device *dev)
   37.50 -{
   37.51 -	struct backend_info *be = dev->data;
   37.52 -
   37.53 -	if (be->watch.node)
   37.54 -		unregister_xenbus_watch(&be->watch);
   37.55 -	unregister_xenbus_watch(&be->backend_watch);
   37.56 -	if (be->blkif)
   37.57 -		blkif_put(be->blkif);
   37.58 -	kfree(be->frontpath);
   37.59 -	kfree(be);
   37.60 -	return 0;
   37.61 -}
   37.62 -
   37.63 -/* Front end tells us frame. */
   37.64 -static void frontend_changed(struct xenbus_watch *watch,
   37.65 -			     const char **vec, unsigned int len)
   37.66 -{
   37.67 -	unsigned long ring_ref;
   37.68 -	unsigned int evtchn;
   37.69 -	int err;
   37.70 -	struct backend_info *be
   37.71 -		= container_of(watch, struct backend_info, watch);
   37.72 -
   37.73 -	/* If other end is gone, delete ourself. */
   37.74 -	if (vec && !xenbus_exists(be->frontpath, "")) {
   37.75 -		xenbus_rm(be->dev->nodename, "");
   37.76 -		device_unregister(&be->dev->dev);
   37.77 -		return;
   37.78 -	}
   37.79 -	if (be->blkif == NULL || be->blkif->status == CONNECTED)
   37.80 -		return;
   37.81 -
   37.82 -	err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref,
   37.83 -			    "event-channel", "%u", &evtchn, NULL);
   37.84 -	if (err) {
   37.85 -		xenbus_dev_error(be->dev, err,
   37.86 -				 "reading %s/ring-ref and event-channel",
   37.87 -				 be->frontpath);
   37.88 -		return;
   37.89 -	}
   37.90 -
   37.91 -	/* Map the shared frame, irq etc. */
   37.92 -	err = blkif_map(be->blkif, ring_ref, evtchn);
   37.93 -	if (err) {
   37.94 -		xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u",
   37.95 -				 ring_ref, evtchn);
   37.96 -		goto abort;
   37.97 -	}
   37.98 -
   37.99 -	xenbus_dev_ok(be->dev);
  37.100 -
  37.101 -	return;
  37.102 -
  37.103 -abort:
  37.104 -	xenbus_transaction_end(1);
  37.105 -}
  37.106 -
  37.107 -/* 
  37.108 -   Setup supplies physical device.  
  37.109 -   We provide event channel and device details to front end.
  37.110 -   Frontend supplies shared frame and event channel.
  37.111 - */
  37.112 -static void backend_changed(struct xenbus_watch *watch,
  37.113 -			    const char **vec, unsigned int len)
  37.114 -{
  37.115 -	int err;
  37.116 -	char *p;
  37.117 -	long int handle;
  37.118 -	struct backend_info *be
  37.119 -		= container_of(watch, struct backend_info, backend_watch);
  37.120 -	struct xenbus_device *dev = be->dev;
  37.121 -
  37.122 -	if (be->blkif == NULL) {
  37.123 -		/* Front end dir is a number, which is used as the handle. */
  37.124 -		p = strrchr(be->frontpath, '/') + 1;
  37.125 -		handle = simple_strtoul(p, NULL, 0);
  37.126 -
  37.127 -		be->blkif = alloc_blkif(be->frontend_id);
  37.128 -		if (IS_ERR(be->blkif)) {
  37.129 -			err = PTR_ERR(be->blkif);
  37.130 -			be->blkif = NULL;
  37.131 -			xenbus_dev_error(dev, err, "creating block interface");
  37.132 -			return;
  37.133 -		}
  37.134 -
  37.135 -		/* Pass in NULL node to skip exist test. */
  37.136 -		frontend_changed(&be->watch, NULL, 0);
  37.137 -	}
  37.138 -}
  37.139 -
  37.140 -static int blkback_probe(struct xenbus_device *dev,
  37.141 -			 const struct xenbus_device_id *id)
  37.142 -{
  37.143 -	struct backend_info *be;
  37.144 -	char *frontend;
  37.145 -	int err;
  37.146 -
  37.147 -	be = kzalloc(sizeof(*be), GFP_KERNEL);
  37.148 -	if (!be) {
  37.149 -		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
  37.150 -		return -ENOMEM;
  37.151 -	}
  37.152 -
  37.153 -	frontend = NULL;
  37.154 -	err = xenbus_gather(dev->nodename,
  37.155 -			    "frontend-id", "%li", &be->frontend_id,
  37.156 -			    "frontend", NULL, &frontend,
  37.157 -			    NULL);
  37.158 -	if (XENBUS_EXIST_ERR(err))
  37.159 -		goto free_be;
  37.160 -	if (err < 0) {
  37.161 -		xenbus_dev_error(dev, err,
  37.162 -				 "reading %s/frontend or frontend-id",
  37.163 -				 dev->nodename);
  37.164 -		goto free_be;
  37.165 -	}
  37.166 -	if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) {
  37.167 -		/* If we can't get a frontend path and a frontend-id,
  37.168 -		 * then our bus-id is no longer valid and we need to
  37.169 -		 * destroy the backend device.
  37.170 -		 */
  37.171 -		err = -ENOENT;
  37.172 -		goto free_be;
  37.173 -	}
  37.174 -
  37.175 -	be->dev = dev;
  37.176 -	be->backend_watch.node = dev->nodename;
  37.177 -	be->backend_watch.callback = backend_changed;
  37.178 -	/* Registration implicitly fires backend_changed once */
  37.179 -	err = register_xenbus_watch(&be->backend_watch);
  37.180 -	if (err) {
  37.181 -		be->backend_watch.node = NULL;
  37.182 -		xenbus_dev_error(dev, err, "adding backend watch on %s",
  37.183 -				 dev->nodename);
  37.184 -		goto free_be;
  37.185 -	}
  37.186 -
  37.187 -	be->frontpath = frontend;
  37.188 -	be->watch.node = be->frontpath;
  37.189 -	be->watch.callback = frontend_changed;
  37.190 -	err = register_xenbus_watch(&be->watch);
  37.191 -	if (err) {
  37.192 -		be->watch.node = NULL;
  37.193 -		xenbus_dev_error(dev, err,
  37.194 -				 "adding frontend watch on %s",
  37.195 -				 be->frontpath);
  37.196 -		goto free_be;
  37.197 -	}
  37.198 -
  37.199 -	dev->data = be;
  37.200 -	return 0;
  37.201 -
  37.202 - free_be:
  37.203 -	if (be->backend_watch.node)
  37.204 -		unregister_xenbus_watch(&be->backend_watch);
  37.205 -	kfree(frontend);
  37.206 -	kfree(be);
  37.207 -	return err;
  37.208 -}
  37.209 -
  37.210 -static struct xenbus_device_id blkback_ids[] = {
  37.211 -	{ "vbd" },
  37.212 -	{ "" }
  37.213 -};
  37.214 -
  37.215 -static struct xenbus_driver blkback = {
  37.216 -	.name = "vbd",
  37.217 -	.owner = THIS_MODULE,
  37.218 -	.ids = blkback_ids,
  37.219 -	.probe = blkback_probe,
  37.220 -	.remove = blkback_remove,
  37.221 -};
  37.222 -
  37.223 -void blkif_xenbus_init(void)
  37.224 -{
  37.225 -	xenbus_register_backend(&blkback);
  37.226 -}
    38.1 --- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Tue Jun 13 09:00:32 2006 -0600
    38.2 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Tue Jun 13 12:12:24 2006 -0600
    38.3 @@ -30,10 +30,10 @@
    38.4  
    38.5  static inline int uncached_access(struct file *file)
    38.6  {
    38.7 -        if (file->f_flags & O_SYNC)
    38.8 -                return 1;
    38.9 -        /* Xen sets correct MTRR type on non-RAM for us. */
   38.10 -        return 0;
   38.11 +	if (file->f_flags & O_SYNC)
   38.12 +		return 1;
   38.13 +	/* Xen sets correct MTRR type on non-RAM for us. */
   38.14 +	return 0;
   38.15  }
   38.16  
   38.17  /*
    39.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c	Tue Jun 13 09:00:32 2006 -0600
    39.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c	Tue Jun 13 12:12:24 2006 -0600
    39.3 @@ -364,7 +364,7 @@ void xencons_tx(void)
    39.4  
    39.5  /* Privileged receive callback and transmit kicker. */
    39.6  static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
    39.7 -                                          struct pt_regs *regs)
    39.8 +					  struct pt_regs *regs)
    39.9  {
   39.10  	static char rbuf[16];
   39.11  	int         l;
    40.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile	Tue Jun 13 09:00:32 2006 -0600
    40.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile	Tue Jun 13 12:12:24 2006 -0600
    40.3 @@ -2,11 +2,13 @@
    40.4  # Makefile for the linux kernel.
    40.5  #
    40.6  
    40.7 -obj-y   := evtchn.o reboot.o gnttab.o features.o
    40.8 +obj-y := evtchn.o gnttab.o features.o
    40.9  
   40.10 -obj-$(CONFIG_PROC_FS)     += xen_proc.o
   40.11 -obj-$(CONFIG_NET)         += skbuff.o
   40.12 -obj-$(CONFIG_SMP)         += smpboot.o
   40.13 -obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
   40.14 -obj-$(CONFIG_SYSFS)       += hypervisor_sysfs.o
   40.15 -obj-$(CONFIG_XEN_SYSFS)   += xen_sysfs.o
   40.16 +obj-$(CONFIG_PROC_FS)		+= xen_proc.o
   40.17 +obj-$(CONFIG_SYSFS)		+= hypervisor_sysfs.o
   40.18 +obj-$(CONFIG_HOTPLUG_CPU)	+= cpu_hotplug.o
   40.19 +obj-$(CONFIG_XEN_SYSFS)		+= xen_sysfs.o
   40.20 +obj-$(CONFIG_IA64)		+= xenia64_init.o
   40.21 +obj-$(CONFIG_XEN_SKBUFF)	+= skbuff.o
   40.22 +obj-$(CONFIG_XEN_REBOOT)	+= reboot.o
   40.23 +obj-$(CONFIG_XEN_SMPBOOT)	+= smpboot.o
    41.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c	Tue Jun 13 09:00:32 2006 -0600
    41.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/cpu_hotplug.c	Tue Jun 13 12:12:24 2006 -0600
    41.3 @@ -34,7 +34,7 @@ static void vcpu_hotplug(unsigned int cp
    41.4  		return;
    41.5  
    41.6  	sprintf(dir, "cpu/%d", cpu);
    41.7 -	err = xenbus_scanf(XBT_NULL, dir, "availability", "%s", state);
    41.8 +	err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state);
    41.9  	if (err != 1) {
   41.10  		printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
   41.11  		return;
    42.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Tue Jun 13 09:00:32 2006 -0600
    42.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Tue Jun 13 12:12:24 2006 -0600
    42.3 @@ -54,7 +54,8 @@
    42.4  static DEFINE_SPINLOCK(irq_mapping_update_lock);
    42.5  
    42.6  /* IRQ <-> event-channel mappings. */
    42.7 -static int evtchn_to_irq[NR_EVENT_CHANNELS] = {[0 ...  NR_EVENT_CHANNELS-1] = -1};
    42.8 +static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
    42.9 +	[0 ...  NR_EVENT_CHANNELS-1] = -1 };
   42.10  
   42.11  /* Packed IRQ information: binding type, sub-type index, and event channel. */
   42.12  static u32 irq_info[NR_IRQS];
   42.13 @@ -120,6 +121,11 @@ static inline unsigned long active_evtch
   42.14  
   42.15  static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
   42.16  {
   42.17 +	int irq = evtchn_to_irq[chn];
   42.18 +
   42.19 +	BUG_ON(irq == -1);
   42.20 +	set_native_irq_info(irq, cpumask_of_cpu(cpu));
   42.21 +
   42.22  	clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
   42.23  	set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
   42.24  	cpu_evtchn[chn] = cpu;
   42.25 @@ -127,7 +133,12 @@ static void bind_evtchn_to_cpu(unsigned 
   42.26  
   42.27  static void init_evtchn_cpu_bindings(void)
   42.28  {
   42.29 +	int i;
   42.30 +
   42.31  	/* By default all event channels notify CPU#0. */
   42.32 +	for (i = 0; i < NR_IRQS; i++)
   42.33 +		set_native_irq_info(i, cpumask_of_cpu(0));
   42.34 +
   42.35  	memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
   42.36  	memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
   42.37  }
   42.38 @@ -430,25 +441,14 @@ void unbind_from_irqhandler(unsigned int
   42.39  }
   42.40  EXPORT_SYMBOL_GPL(unbind_from_irqhandler);
   42.41  
   42.42 -#ifdef CONFIG_SMP
   42.43 -static void do_nothing_function(void *ign)
   42.44 -{
   42.45 -}
   42.46 -#endif
   42.47 -
   42.48  /* Rebind an evtchn so that it gets delivered to a specific cpu */
   42.49  static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
   42.50  {
   42.51  	struct evtchn_bind_vcpu bind_vcpu;
   42.52 -	int evtchn;
   42.53 -
   42.54 -	spin_lock(&irq_mapping_update_lock);
   42.55 +	int evtchn = evtchn_from_irq(irq);
   42.56  
   42.57 -	evtchn = evtchn_from_irq(irq);
   42.58 -	if (!VALID_EVTCHN(evtchn)) {
   42.59 -		spin_unlock(&irq_mapping_update_lock);
   42.60 +	if (!VALID_EVTCHN(evtchn))
   42.61  		return;
   42.62 -	}
   42.63  
   42.64  	/* Send future instances of this interrupt to other vcpu. */
   42.65  	bind_vcpu.port = evtchn;
   42.66 @@ -461,21 +461,6 @@ static void rebind_irq_to_cpu(unsigned i
   42.67  	 */
   42.68  	if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
   42.69  		bind_evtchn_to_cpu(evtchn, tcpu);
   42.70 -
   42.71 -	spin_unlock(&irq_mapping_update_lock);
   42.72 -
   42.73 -	/*
   42.74 -	 * Now send the new target processor a NOP IPI. When this returns, it
   42.75 -	 * will check for any pending interrupts, and so service any that got 
   42.76 -	 * delivered to the wrong processor by mistake.
   42.77 -	 * 
   42.78 -	 * XXX: The only time this is called with interrupts disabled is from
   42.79 -	 * the hotplug/hotunplug path. In that case, all cpus are stopped with 
   42.80 -	 * interrupts disabled, and the missed interrupts will be picked up
   42.81 -	 * when they start again. This is kind of a hack.
   42.82 -	 */
   42.83 -	if (!irqs_disabled())
   42.84 -		smp_call_function(do_nothing_function, NULL, 0, 0);
   42.85  }
   42.86  
   42.87  
   42.88 @@ -597,8 +582,8 @@ static unsigned int startup_pirq(unsigne
   42.89  
   42.90  	pirq_query_unmask(irq_to_pirq(irq));
   42.91  
   42.92 +	evtchn_to_irq[evtchn] = irq;
   42.93  	bind_evtchn_to_cpu(evtchn, 0);
   42.94 -	evtchn_to_irq[evtchn] = irq;
   42.95  	irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);
   42.96  
   42.97   out:
   42.98 @@ -678,7 +663,14 @@ static struct hw_interrupt_type pirq_typ
   42.99  	set_affinity_irq
  42.100  };
  42.101  
  42.102 -void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
  42.103 +int irq_ignore_unhandled(unsigned int irq)
  42.104 +{
  42.105 +	struct physdev_irq_status_query irq_status = { .irq = irq };
  42.106 +	(void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
  42.107 +	return !!(irq_status.flags & XENIRQSTAT_shared);
  42.108 +}
  42.109 +
  42.110 +void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i)
  42.111  {
  42.112  	int evtchn = evtchn_from_irq(i);
  42.113  	shared_info_t *s = HYPERVISOR_shared_info;
  42.114 @@ -710,6 +702,8 @@ void unmask_evtchn(int port)
  42.115  	unsigned int cpu = smp_processor_id();
  42.116  	vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
  42.117  
  42.118 +	BUG_ON(!irqs_disabled());
  42.119 +
  42.120  	/* Slow path (hypercall) if this is a non-local port. */
  42.121  	if (unlikely(cpu != cpu_from_evtchn(port))) {
  42.122  		struct evtchn_unmask unmask = { .port = port };
  42.123 @@ -726,11 +720,8 @@ void unmask_evtchn(int port)
  42.124  	 */
  42.125  	if (synch_test_bit(port, &s->evtchn_pending[0]) &&
  42.126  	    !synch_test_and_set_bit(port / BITS_PER_LONG,
  42.127 -				    &vcpu_info->evtchn_pending_sel)) {
  42.128 +				    &vcpu_info->evtchn_pending_sel))
  42.129  		vcpu_info->evtchn_upcall_pending = 1;
  42.130 -		if (!vcpu_info->evtchn_upcall_mask)
  42.131 -			force_evtchn_callback();
  42.132 -	}
  42.133  }
  42.134  EXPORT_SYMBOL_GPL(unmask_evtchn);
  42.135  
    43.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Tue Jun 13 09:00:32 2006 -0600
    43.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Tue Jun 13 12:12:24 2006 -0600
    43.3 @@ -1,27 +1,27 @@
    43.4  /******************************************************************************
    43.5   * gnttab.c
    43.6 - * 
    43.7 + *
    43.8   * Granting foreign access to our memory reservation.
    43.9 - * 
   43.10 + *
   43.11   * Copyright (c) 2005, Christopher Clark
   43.12   * Copyright (c) 2004-2005, K A Fraser
   43.13 - * 
   43.14 + *
   43.15   * This program is free software; you can redistribute it and/or
   43.16   * modify it under the terms of the GNU General Public License version 2
   43.17   * as published by the Free Software Foundation; or, when distributed
   43.18   * separately from the Linux kernel or incorporated into other
   43.19   * software packages, subject to the following license:
   43.20 - * 
   43.21 + *
   43.22   * Permission is hereby granted, free of charge, to any person obtaining a copy
   43.23   * of this source file (the "Software"), to deal in the Software without
   43.24   * restriction, including without limitation the rights to use, copy, modify,
   43.25   * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   43.26   * and to permit persons to whom the Software is furnished to do so, subject to
   43.27   * the following conditions:
   43.28 - * 
   43.29 + *
   43.30   * The above copyright notice and this permission notice shall be included in
   43.31   * all copies or substantial portions of the Software.
   43.32 - * 
   43.33 + *
   43.34   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   43.35   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   43.36   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   43.37 @@ -36,45 +36,17 @@
   43.38  #include <linux/sched.h>
   43.39  #include <linux/mm.h>
   43.40  #include <linux/vmalloc.h>
   43.41 +#include <xen/interface/xen.h>
   43.42 +#include <xen/gnttab.h>
   43.43  #include <asm/pgtable.h>
   43.44 -#include <xen/interface/xen.h>
   43.45  #include <asm/uaccess.h>
   43.46 -#include <xen/gnttab.h>
   43.47  #include <asm/synch_bitops.h>
   43.48  
   43.49 -#if 1
   43.50 -#define ASSERT(_p)							      \
   43.51 -	if (!(_p)) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n",   \
   43.52 -	#_p , __LINE__, __FILE__); *(int*)0=0; }
   43.53 -#else
   43.54 -#define ASSERT(_p) ((void)0)
   43.55 -#endif
   43.56 -
   43.57 -#define WPRINTK(fmt, args...)				\
   43.58 -	printk(KERN_WARNING "xen_grant: " fmt, ##args)
   43.59 -
   43.60 -
   43.61 -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
   43.62 -EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
   43.63 -EXPORT_SYMBOL_GPL(gnttab_end_foreign_access);
   43.64 -EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
   43.65 -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer);
   43.66 -EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref);
   43.67 -EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer);
   43.68 -EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references);
   43.69 -EXPORT_SYMBOL_GPL(gnttab_free_grant_references);
   43.70 -EXPORT_SYMBOL_GPL(gnttab_free_grant_reference);
   43.71 -EXPORT_SYMBOL_GPL(gnttab_empty_grant_references);
   43.72 -EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
   43.73 -EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
   43.74 -EXPORT_SYMBOL_GPL(gnttab_request_free_callback);
   43.75 -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
   43.76 -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref);
   43.77 -
   43.78  /* External tools reserve first few grant table entries. */
   43.79  #define NR_RESERVED_ENTRIES 8
   43.80  
   43.81 -#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
   43.82 +#define NR_GRANT_ENTRIES \
   43.83 +	(NR_GRANT_FRAMES * PAGE_SIZE / sizeof(struct grant_entry))
   43.84  #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
   43.85  
   43.86  static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
   43.87 @@ -82,12 +54,11 @@ static int gnttab_free_count;
   43.88  static grant_ref_t gnttab_free_head;
   43.89  static DEFINE_SPINLOCK(gnttab_list_lock);
   43.90  
   43.91 -static grant_entry_t *shared = NULL;
   43.92 +static struct grant_entry *shared;
   43.93  
   43.94 -static struct gnttab_free_callback *gnttab_free_callback_list = NULL;
   43.95 +static struct gnttab_free_callback *gnttab_free_callback_list;
   43.96  
   43.97 -static int
   43.98 -get_free_entries(int count)
   43.99 +static int get_free_entries(int count)
  43.100  {
  43.101  	unsigned long flags;
  43.102  	int ref;
  43.103 @@ -109,8 +80,7 @@ get_free_entries(int count)
  43.104  
  43.105  #define get_free_entry() get_free_entries(1)
  43.106  
  43.107 -static void
  43.108 -do_free_callbacks(void)
  43.109 +static void do_free_callbacks(void)
  43.110  {
  43.111  	struct gnttab_free_callback *callback, *next;
  43.112  
  43.113 @@ -130,15 +100,13 @@ do_free_callbacks(void)
  43.114  	}
  43.115  }
  43.116  
  43.117 -static inline void
  43.118 -check_free_callbacks(void)
  43.119 +static inline void check_free_callbacks(void)
  43.120  {
  43.121  	if (unlikely(gnttab_free_callback_list))
  43.122  		do_free_callbacks();
  43.123  }
  43.124  
  43.125 -static void
  43.126 -put_free_entry(grant_ref_t ref)
  43.127 +static void put_free_entry(grant_ref_t ref)
  43.128  {
  43.129  	unsigned long flags;
  43.130  	spin_lock_irqsave(&gnttab_list_lock, flags);
  43.131 @@ -153,8 +121,8 @@ put_free_entry(grant_ref_t ref)
  43.132   * Public grant-issuing interface functions
  43.133   */
  43.134  
  43.135 -int
  43.136 -gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
  43.137 +int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
  43.138 +				int readonly)
  43.139  {
  43.140  	int ref;
  43.141  
  43.142 @@ -168,20 +136,20 @@ gnttab_grant_foreign_access(domid_t domi
  43.143  
  43.144  	return ref;
  43.145  }
  43.146 +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
  43.147  
  43.148 -void
  43.149 -gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
  43.150 -				unsigned long frame, int readonly)
  43.151 +void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
  43.152 +				     unsigned long frame, int readonly)
  43.153  {
  43.154  	shared[ref].frame = frame;
  43.155  	shared[ref].domid = domid;
  43.156  	wmb();
  43.157  	shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
  43.158  }
  43.159 +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
  43.160  
  43.161  
  43.162 -int
  43.163 -gnttab_query_foreign_access(grant_ref_t ref)
  43.164 +int gnttab_query_foreign_access(grant_ref_t ref)
  43.165  {
  43.166  	u16 nflags;
  43.167  
  43.168 @@ -189,9 +157,9 @@ gnttab_query_foreign_access(grant_ref_t 
  43.169  
  43.170  	return (nflags & (GTF_reading|GTF_writing));
  43.171  }
  43.172 +EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
  43.173  
  43.174 -int
  43.175 -gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
  43.176 +int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
  43.177  {
  43.178  	u16 flags, nflags;
  43.179  
  43.180 @@ -206,15 +174,15 @@ gnttab_end_foreign_access_ref(grant_ref_
  43.181  
  43.182  	return 1;
  43.183  }
  43.184 +EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
  43.185  
  43.186 -void
  43.187 -gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page)
  43.188 +void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
  43.189 +			       unsigned long page)
  43.190  {
  43.191  	if (gnttab_end_foreign_access_ref(ref, readonly)) {
  43.192  		put_free_entry(ref);
  43.193 -		if (page != 0) {
  43.194 +		if (page != 0)
  43.195  			free_page(page);
  43.196 -		}
  43.197  	} else {
  43.198  		/* XXX This needs to be fixed so that the ref and page are
  43.199  		   placed on a list to be freed up later. */
  43.200 @@ -222,9 +190,9 @@ gnttab_end_foreign_access(grant_ref_t re
  43.201  		       "WARNING: leaking g.e. and page still in use!\n");
  43.202  	}
  43.203  }
  43.204 +EXPORT_SYMBOL_GPL(gnttab_end_foreign_access);
  43.205  
  43.206 -int
  43.207 -gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
  43.208 +int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
  43.209  {
  43.210  	int ref;
  43.211  
  43.212 @@ -234,27 +202,27 @@ gnttab_grant_foreign_transfer(domid_t do
  43.213  
  43.214  	return ref;
  43.215  }
  43.216 +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer);
  43.217  
  43.218 -void
  43.219 -gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
  43.220 -				  unsigned long pfn)
  43.221 +void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
  43.222 +				       unsigned long pfn)
  43.223  {
  43.224  	shared[ref].frame = pfn;
  43.225  	shared[ref].domid = domid;
  43.226  	wmb();
  43.227  	shared[ref].flags = GTF_accept_transfer;
  43.228  }
  43.229 +EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref);
  43.230  
  43.231 -unsigned long
  43.232 -gnttab_end_foreign_transfer_ref(grant_ref_t ref)
  43.233 +unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref)
  43.234  {
  43.235  	unsigned long frame;
  43.236  	u16           flags;
  43.237  
  43.238  	/*
  43.239 -         * If a transfer is not even yet started, try to reclaim the grant
  43.240 -         * reference and return failure (== 0).
  43.241 -         */
  43.242 +	 * If a transfer is not even yet started, try to reclaim the grant
  43.243 +	 * reference and return failure (== 0).
  43.244 +	 */
  43.245  	while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
  43.246  		if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
  43.247  			return 0;
  43.248 @@ -274,24 +242,23 @@ gnttab_end_foreign_transfer_ref(grant_re
  43.249  
  43.250  	return frame;
  43.251  }
  43.252 +EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref);
  43.253  
  43.254 -unsigned long
  43.255 -gnttab_end_foreign_transfer(grant_ref_t ref)
  43.256 +unsigned long gnttab_end_foreign_transfer(grant_ref_t ref)
  43.257  {
  43.258  	unsigned long frame = gnttab_end_foreign_transfer_ref(ref);
  43.259  	put_free_entry(ref);
  43.260  	return frame;
  43.261  }
  43.262 +EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer);
  43.263  
  43.264 -void
  43.265 -gnttab_free_grant_reference(grant_ref_t ref)
  43.266 +void gnttab_free_grant_reference(grant_ref_t ref)
  43.267  {
  43.268 -
  43.269  	put_free_entry(ref);
  43.270  }
  43.271 +EXPORT_SYMBOL_GPL(gnttab_free_grant_reference);
  43.272  
  43.273 -void
  43.274 -gnttab_free_grant_references(grant_ref_t head)
  43.275 +void gnttab_free_grant_references(grant_ref_t head)
  43.276  {
  43.277  	grant_ref_t ref;
  43.278  	unsigned long flags;
  43.279 @@ -310,9 +277,9 @@ gnttab_free_grant_references(grant_ref_t
  43.280  	check_free_callbacks();
  43.281  	spin_unlock_irqrestore(&gnttab_list_lock, flags);
  43.282  }
  43.283 +EXPORT_SYMBOL_GPL(gnttab_free_grant_references);
  43.284  
  43.285 -int
  43.286 -gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
  43.287 +int gnttab_alloc_grant_references(u16 count, grant_ref_t *head)
  43.288  {
  43.289  	int h = get_free_entries(count);
  43.290  
  43.291 @@ -323,15 +290,15 @@ gnttab_alloc_grant_references(u16 count,
  43.292  
  43.293  	return 0;
  43.294  }
  43.295 +EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references);
  43.296  
  43.297 -int
  43.298 -gnttab_empty_grant_references(const grant_ref_t *private_head)
  43.299 +int gnttab_empty_grant_references(const grant_ref_t *private_head)
  43.300  {
  43.301  	return (*private_head == GNTTAB_LIST_END);
  43.302  }
  43.303 +EXPORT_SYMBOL_GPL(gnttab_empty_grant_references);
  43.304  
  43.305 -int
  43.306 -gnttab_claim_grant_reference(grant_ref_t *private_head)
  43.307 +int gnttab_claim_grant_reference(grant_ref_t *private_head)
  43.308  {
  43.309  	grant_ref_t g = *private_head;
  43.310  	if (unlikely(g == GNTTAB_LIST_END))
  43.311 @@ -339,17 +306,18 @@ gnttab_claim_grant_reference(grant_ref_t
  43.312  	*private_head = gnttab_list[g];
  43.313  	return g;
  43.314  }
  43.315 +EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference);
  43.316  
  43.317 -void
  43.318 -gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t  release)
  43.319 +void gnttab_release_grant_reference(grant_ref_t *private_head,
  43.320 +				    grant_ref_t release)
  43.321  {
  43.322  	gnttab_list[release] = *private_head;
  43.323  	*private_head = release;
  43.324  }
  43.325 +EXPORT_SYMBOL_GPL(gnttab_release_grant_reference);
  43.326  
  43.327 -void
  43.328 -gnttab_request_free_callback(struct gnttab_free_callback *callback,
  43.329 -			     void (*fn)(void *), void *arg, u16 count)
  43.330 +void gnttab_request_free_callback(struct gnttab_free_callback *callback,
  43.331 +				  void (*fn)(void *), void *arg, u16 count)
  43.332  {
  43.333  	unsigned long flags;
  43.334  	spin_lock_irqsave(&gnttab_list_lock, flags);
  43.335 @@ -361,9 +329,10 @@ gnttab_request_free_callback(struct gntt
  43.336  	callback->next = gnttab_free_callback_list;
  43.337  	gnttab_free_callback_list = callback;
  43.338  	check_free_callbacks();
  43.339 - out:
  43.340 +out:
  43.341  	spin_unlock_irqrestore(&gnttab_list_lock, flags);
  43.342  }
  43.343 +EXPORT_SYMBOL_GPL(gnttab_request_free_callback);
  43.344  
  43.345  #ifndef __ia64__
  43.346  static int map_pte_fn(pte_t *pte, struct page *pmd_page,
  43.347 @@ -377,7 +346,7 @@ static int map_pte_fn(pte_t *pte, struct
  43.348  }
  43.349  
  43.350  static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
  43.351 -		      unsigned long addr, void *data)
  43.352 +			unsigned long addr, void *data)
  43.353  {
  43.354  
  43.355  	set_pte_at(&init_mm, addr, pte, __pte(0));
  43.356 @@ -385,10 +354,9 @@ static int unmap_pte_fn(pte_t *pte, stru
  43.357  }
  43.358  #endif
  43.359  
  43.360 -int
  43.361 -gnttab_resume(void)
  43.362 +int gnttab_resume(void)
  43.363  {
  43.364 -	gnttab_setup_table_t setup;
  43.365 +	struct gnttab_setup_table setup;
  43.366  	unsigned long frames[NR_GRANT_FRAMES];
  43.367  	int rc;
  43.368  #ifndef __ia64__
  43.369 @@ -424,8 +392,7 @@ gnttab_resume(void)
  43.370  	return 0;
  43.371  }
  43.372  
  43.373 -int
  43.374 -gnttab_suspend(void)
  43.375 +int gnttab_suspend(void)
  43.376  {
  43.377  
  43.378  #ifndef __ia64__
  43.379 @@ -437,8 +404,7 @@ gnttab_suspend(void)
  43.380  	return 0;
  43.381  }
  43.382  
  43.383 -static int __init
  43.384 -gnttab_init(void)
  43.385 +static int __init gnttab_init(void)
  43.386  {
  43.387  	int i;
  43.388  
    44.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Tue Jun 13 09:00:32 2006 -0600
    44.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c	Tue Jun 13 12:12:24 2006 -0600
    44.3 @@ -250,7 +250,7 @@ static void shutdown_handler(struct xenb
    44.4  			     const char **vec, unsigned int len)
    44.5  {
    44.6  	char *str;
    44.7 -	xenbus_transaction_t xbt;
    44.8 +	struct xenbus_transaction xbt;
    44.9  	int err;
   44.10  
   44.11  	if (shutting_down != SHUTDOWN_INVALID)
   44.12 @@ -298,7 +298,7 @@ static void sysrq_handler(struct xenbus_
   44.13  			  unsigned int len)
   44.14  {
   44.15  	char sysrq_key = '\0';
   44.16 -	xenbus_transaction_t xbt;
   44.17 +	struct xenbus_transaction xbt;
   44.18  	int err;
   44.19  
   44.20   again:
   44.21 @@ -336,8 +336,8 @@ static struct xenbus_watch sysrq_watch =
   44.22  };
   44.23  
   44.24  static int setup_shutdown_watcher(struct notifier_block *notifier,
   44.25 -                                  unsigned long event,
   44.26 -                                  void *data)
   44.27 +				  unsigned long event,
   44.28 +				  void *data)
   44.29  {
   44.30  	int err;
   44.31  
    45.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Tue Jun 13 09:00:32 2006 -0600
    45.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c	Tue Jun 13 12:12:24 2006 -0600
    45.3 @@ -89,9 +89,8 @@ void __init prefill_possible_map(void)
    45.4  
    45.5  	for (i = 0; i < NR_CPUS; i++) {
    45.6  		rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
    45.7 -		if (rc == -ENOENT)
    45.8 -			break;
    45.9 -		cpu_set(i, cpu_possible_map);
   45.10 +		if (rc >= 0)
   45.11 +			cpu_set(i, cpu_possible_map);
   45.12  	}
   45.13  }
   45.14  
   45.15 @@ -209,7 +208,7 @@ void cpu_initialize_context(unsigned int
   45.16  	ctxt.failsafe_callback_cs  = __KERNEL_CS;
   45.17  	ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
   45.18  
   45.19 -	ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT;
   45.20 +	ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
   45.21  #else /* __x86_64__ */
   45.22  	ctxt.user_regs.cs = __KERNEL_CS;
   45.23  	ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
   45.24 @@ -221,7 +220,7 @@ void cpu_initialize_context(unsigned int
   45.25  	ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
   45.26  	ctxt.syscall_callback_eip  = (unsigned long)system_call;
   45.27  
   45.28 -	ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT;
   45.29 +	ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
   45.30  
   45.31  	ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
   45.32  #endif
    46.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Tue Jun 13 09:00:32 2006 -0600
    46.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Tue Jun 13 12:12:24 2006 -0600
    46.3 @@ -93,7 +93,7 @@ void evtchn_device_upcall(int port)
    46.4  }
    46.5  
    46.6  static ssize_t evtchn_read(struct file *file, char __user *buf,
    46.7 -                           size_t count, loff_t *ppos)
    46.8 +			   size_t count, loff_t *ppos)
    46.9  {
   46.10  	int rc;
   46.11  	unsigned int c, p, bytes1 = 0, bytes2 = 0;
   46.12 @@ -153,7 +153,7 @@ static ssize_t evtchn_read(struct file *
   46.13  }
   46.14  
   46.15  static ssize_t evtchn_write(struct file *file, const char __user *buf,
   46.16 -                            size_t count, loff_t *ppos)
   46.17 +			    size_t count, loff_t *ppos)
   46.18  {
   46.19  	int  rc, i;
   46.20  	evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
   46.21 @@ -201,7 +201,7 @@ static void evtchn_bind_to_user(struct p
   46.22  }
   46.23  
   46.24  static int evtchn_ioctl(struct inode *inode, struct file *file,
   46.25 -                        unsigned int cmd, unsigned long arg)
   46.26 +			unsigned int cmd, unsigned long arg)
   46.27  {
   46.28  	int rc;
   46.29  	struct per_user_data *u = file->private_data;
    47.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Tue Jun 13 09:00:32 2006 -0600
    47.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Tue Jun 13 12:12:24 2006 -0600
    47.3 @@ -47,12 +47,13 @@
    47.4  #include <xen/gnttab.h>
    47.5  #include <xen/driver_util.h>
    47.6  
    47.7 -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
    47.8 -                                    __FILE__ , __LINE__ , ## _a )
    47.9 -#define IPRINTK(fmt, args...) \
   47.10 -    printk(KERN_INFO "xen_net: " fmt, ##args)
   47.11 -#define WPRINTK(fmt, args...) \
   47.12 -    printk(KERN_WARNING "xen_net: " fmt, ##args)
   47.13 +#define DPRINTK(_f, _a...)			\
   47.14 +	pr_debug("(file=%s, line=%d) " _f,	\
   47.15 +		 __FILE__ , __LINE__ , ## _a )
   47.16 +#define IPRINTK(fmt, args...)				\
   47.17 +	printk(KERN_INFO "xen_net: " fmt, ##args)
   47.18 +#define WPRINTK(fmt, args...)				\
   47.19 +	printk(KERN_WARNING "xen_net: " fmt, ##args)
   47.20  
   47.21  typedef struct netif_st {
   47.22  	/* Unique identifier for this interface. */
    48.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Tue Jun 13 09:00:32 2006 -0600
    48.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Tue Jun 13 12:12:24 2006 -0600
    48.3 @@ -124,7 +124,7 @@ netif_t *netif_alloc(domid_t domid, unsi
    48.4  		 * Initialise a dummy MAC address. We choose the numerically
    48.5  		 * largest non-broadcast address to prevent the address getting
    48.6  		 * stolen by an Ethernet bridge for STP purposes.
    48.7 -                 * (FE:FF:FF:FF:FF:FF) 
    48.8 +		 * (FE:FF:FF:FF:FF:FF)
    48.9  		 */ 
   48.10  		memset(dev->dev_addr, 0xFF, ETH_ALEN);
   48.11  		dev->dev_addr[0] &= ~0x01;
    49.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Tue Jun 13 09:00:32 2006 -0600
    49.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Tue Jun 13 12:12:24 2006 -0600
    49.3 @@ -146,11 +146,13 @@ static void loopback_construct(struct ne
    49.4  	dev->hard_start_xmit = loopback_start_xmit;
    49.5  	dev->get_stats       = loopback_get_stats;
    49.6  	dev->set_multicast_list = loopback_set_multicast_list;
    49.7 +	dev->change_mtu	     = NULL; /* allow arbitrary mtu */
    49.8  
    49.9  	dev->tx_queue_len    = 0;
   49.10  
   49.11  	dev->features        = (NETIF_F_HIGHDMA |
   49.12  				NETIF_F_LLTX |
   49.13 +				NETIF_F_SG |
   49.14  				NETIF_F_IP_CSUM);
   49.15  
   49.16  	SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
    50.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Jun 13 09:00:32 2006 -0600
    50.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Tue Jun 13 12:12:24 2006 -0600
    50.3 @@ -43,14 +43,14 @@
    50.4  static void netif_idx_release(u16 pending_idx);
    50.5  static void netif_page_release(struct page *page);
    50.6  static void make_tx_response(netif_t *netif, 
    50.7 -                             u16      id,
    50.8 -                             s8       st);
    50.9 +			     u16      id,
   50.10 +			     s8       st);
   50.11  static int  make_rx_response(netif_t *netif, 
   50.12 -                             u16      id, 
   50.13 -                             s8       st,
   50.14 -                             u16      offset,
   50.15 -                             u16      size,
   50.16 -                             u16      flags);
   50.17 +			     u16      id, 
   50.18 +			     s8       st,
   50.19 +			     u16      offset,
   50.20 +			     u16      size,
   50.21 +			     u16      flags);
   50.22  
   50.23  static void net_tx_action(unsigned long unused);
   50.24  static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
   50.25 @@ -329,9 +329,9 @@ static void net_rx_action(unsigned long 
   50.26  			DPRINTK("Bad status %d from grant transfer to DOM%u\n",
   50.27  				gop->status, netif->domid);
   50.28  			/*
   50.29 -                         * Page no longer belongs to us unless GNTST_bad_page,
   50.30 -                         * but that should be a fatal error anyway.
   50.31 -                         */
   50.32 +			 * Page no longer belongs to us unless GNTST_bad_page,
   50.33 +			 * but that should be a fatal error anyway.
   50.34 +			 */
   50.35  			BUG_ON(gop->status == GNTST_bad_page);
   50.36  			status = NETIF_RSP_ERROR; 
   50.37  		}
   50.38 @@ -458,6 +458,9 @@ inline static void net_tx_action_dealloc
   50.39  	dc = dealloc_cons;
   50.40  	dp = dealloc_prod;
   50.41  
   50.42 +	/* Ensure we see all indexes enqueued by netif_idx_release(). */
   50.43 +	smp_rmb();
   50.44 +
   50.45  	/*
   50.46  	 * Free up any grants we have finished using
   50.47  	 */
   50.48 @@ -480,13 +483,184 @@ inline static void net_tx_action_dealloc
   50.49  
   50.50  		make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
   50.51  				 NETIF_RSP_OKAY);
   50.52 -        
   50.53 +
   50.54  		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   50.55  
   50.56  		netif_put(netif);
   50.57  	}
   50.58  }
   50.59  
   50.60 +static void netbk_tx_err(netif_t *netif, RING_IDX end)
   50.61 +{
   50.62 +	RING_IDX cons = netif->tx.req_cons;
   50.63 +
   50.64 +	do {
   50.65 +		netif_tx_request_t *txp = RING_GET_REQUEST(&netif->tx, cons);
   50.66 +		make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
   50.67 +	} while (++cons < end);
   50.68 +	netif->tx.req_cons = cons;
   50.69 +	netif_schedule_work(netif);
   50.70 +	netif_put(netif);
   50.71 +}
   50.72 +
   50.73 +static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp,
   50.74 +				int work_to_do)
   50.75 +{
   50.76 +	netif_tx_request_t *first = txp;
   50.77 +	RING_IDX cons = netif->tx.req_cons;
   50.78 +	int frags = 1;
   50.79 +
   50.80 +	while (txp->flags & NETTXF_more_data) {
   50.81 +		if (frags >= work_to_do) {
   50.82 +			DPRINTK("Need more frags\n");
   50.83 +			return -frags;
   50.84 +		}
   50.85 +
   50.86 +		txp = RING_GET_REQUEST(&netif->tx, cons + frags);
   50.87 +		if (txp->size > first->size) {
   50.88 +			DPRINTK("Frags galore\n");
   50.89 +			return -frags;
   50.90 +		}
   50.91 +
   50.92 +		first->size -= txp->size;
   50.93 +		frags++;
   50.94 +
   50.95 +		if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
   50.96 +			DPRINTK("txp->offset: %x, size: %u\n",
   50.97 +				txp->offset, txp->size);
   50.98 +			return -frags;
   50.99 +		}
  50.100 +	}
  50.101 +
  50.102 +	return frags;
  50.103 +}
  50.104 +
  50.105 +static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
  50.106 +						  struct sk_buff *skb,
  50.107 +						  gnttab_map_grant_ref_t *mop)
  50.108 +{
  50.109 +	struct skb_shared_info *shinfo = skb_shinfo(skb);
  50.110 +	skb_frag_t *frags = shinfo->frags;
  50.111 +	netif_tx_request_t *txp;
  50.112 +	unsigned long pending_idx = *((u16 *)skb->data);
  50.113 +	RING_IDX cons = netif->tx.req_cons + 1;
  50.114 +	int i, start;
  50.115 +
  50.116 +	/* Skip first skb fragment if it is on same page as header fragment. */
  50.117 +	start = ((unsigned long)shinfo->frags[0].page == pending_idx);
  50.118 +
  50.119 +	for (i = start; i < shinfo->nr_frags; i++) {
  50.120 +		txp = RING_GET_REQUEST(&netif->tx, cons++);
  50.121 +		pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
  50.122 +
  50.123 +		gnttab_set_map_op(mop++, MMAP_VADDR(pending_idx),
  50.124 +				  GNTMAP_host_map | GNTMAP_readonly,
  50.125 +				  txp->gref, netif->domid);
  50.126 +
  50.127 +		memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp));
  50.128 +		netif_get(netif);
  50.129 +		pending_tx_info[pending_idx].netif = netif;
  50.130 +		frags[i].page = (void *)pending_idx;
  50.131 +	}
  50.132 +
  50.133 +	return mop;
  50.134 +}
  50.135 +
  50.136 +static int netbk_tx_check_mop(struct sk_buff *skb,
  50.137 +			       gnttab_map_grant_ref_t **mopp)
  50.138 +{
  50.139 +	gnttab_map_grant_ref_t *mop = *mopp;
  50.140 +	int pending_idx = *((u16 *)skb->data);
  50.141 +	netif_t *netif = pending_tx_info[pending_idx].netif;
  50.142 +	netif_tx_request_t *txp;
  50.143 +	struct skb_shared_info *shinfo = skb_shinfo(skb);
  50.144 +	int nr_frags = shinfo->nr_frags;
  50.145 +	int i, err, start;
  50.146 +
  50.147 +	/* Check status of header. */
  50.148 +	err = mop->status;
  50.149 +	if (unlikely(err)) {
  50.150 +		txp = &pending_tx_info[pending_idx].req;
  50.151 +		make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
  50.152 +		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
  50.153 +		netif_put(netif);
  50.154 +	} else {
  50.155 +		set_phys_to_machine(
  50.156 +			__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
  50.157 +			FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
  50.158 +		grant_tx_handle[pending_idx] = mop->handle;
  50.159 +	}
  50.160 +
  50.161 +	/* Skip first skb fragment if it is on same page as header fragment. */
  50.162 +	start = ((unsigned long)shinfo->frags[0].page == pending_idx);
  50.163 +
  50.164 +	for (i = start; i < nr_frags; i++) {
  50.165 +		int j, newerr;
  50.166 +
  50.167 +		pending_idx = (unsigned long)shinfo->frags[i].page;
  50.168 +
  50.169 +		/* Check error status: if okay then remember grant handle. */
  50.170 +		newerr = (++mop)->status;
  50.171 +		if (likely(!newerr)) {
  50.172 +			set_phys_to_machine(
  50.173 +				__pa(MMAP_VADDR(pending_idx))>>PAGE_SHIFT,
  50.174 +				FOREIGN_FRAME(mop->dev_bus_addr>>PAGE_SHIFT));
  50.175 +			grant_tx_handle[pending_idx] = mop->handle;
  50.176 +			/* Had a previous error? Invalidate this fragment. */
  50.177 +			if (unlikely(err))
  50.178 +				netif_idx_release(pending_idx);
  50.179 +			continue;
  50.180 +		}
  50.181 +
  50.182 +		/* Error on this fragment: respond to client with an error. */
  50.183 +		txp = &pending_tx_info[pending_idx].req;
  50.184 +		make_tx_response(netif, txp->id, NETIF_RSP_ERROR);
  50.185 +		pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
  50.186 +		netif_put(netif);
  50.187 +
  50.188 +		/* Not the first error? Preceding frags already invalidated. */
  50.189 +		if (err)
  50.190 +			continue;
  50.191 +
  50.192 +		/* First error: invalidate header and preceding fragments. */
  50.193 +		pending_idx = *((u16 *)skb->data);
  50.194 +		netif_idx_release(pending_idx);
  50.195 +		for (j = start; j < i; j++) {
  50.196 +			pending_idx = (unsigned long)shinfo->frags[i].page;
  50.197 +			netif_idx_release(pending_idx);
  50.198 +		}
  50.199 +
  50.200 +		/* Remember the error: invalidate all subsequent fragments. */
  50.201 +		err = newerr;
  50.202 +	}
  50.203 +
  50.204 +	*mopp = mop + 1;
  50.205 +	return err;
  50.206 +}
  50.207 +
  50.208 +static void netbk_fill_frags(struct sk_buff *skb)
  50.209 +{
  50.210 +	struct skb_shared_info *shinfo = skb_shinfo(skb);
  50.211 +	int nr_frags = shinfo->nr_frags;
  50.212 +	int i;
  50.213 +
  50.214 +	for (i = 0; i < nr_frags; i++) {
  50.215 +		skb_frag_t *frag = shinfo->frags + i;
  50.216 +		netif_tx_request_t *txp;
  50.217 +		unsigned long pending_idx;
  50.218 +
  50.219 +		pending_idx = (unsigned long)frag->page;
  50.220 +		txp = &pending_tx_info[pending_idx].req;
  50.221 +		frag->page = virt_to_page(MMAP_VADDR(pending_idx));
  50.222 +		frag->size = txp->size;
  50.223 +		frag->page_offset = txp->offset;
  50.224 +
  50.225 +		skb->len += txp->size;
  50.226 +		skb->data_len += txp->size;
  50.227 +		skb->truesize += txp->size;
  50.228 +	}
  50.229 +}
  50.230 +
  50.231  /* Called after netfront has transmitted */
  50.232  static void net_tx_action(unsigned long unused)
  50.233  {
  50.234 @@ -504,7 +678,7 @@ static void net_tx_action(unsigned long 
  50.235  		net_tx_action_dealloc();
  50.236  
  50.237  	mop = tx_map_ops;
  50.238 -	while ((NR_PENDING_REQS < MAX_PENDING_REQS) &&
  50.239 +	while (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) &&
  50.240  		!list_empty(&net_schedule_list)) {
  50.241  		/* Get a netif from the list with work to do. */
  50.242  		ent = net_schedule_list.next;
  50.243 @@ -552,38 +726,44 @@ static void net_tx_action(unsigned long 
  50.244  		}
  50.245  		netif->remaining_credit -= txreq.size;
  50.246  
  50.247 -		netif->tx.req_cons++;
  50.248 -
  50.249 -		netif_schedule_work(netif);
  50.250 +		ret = netbk_count_requests(netif, &txreq, work_to_do);
  50.251 +		if (unlikely(ret < 0)) {
  50.252 +			netbk_tx_err(netif, i - ret);
  50.253 +			continue;
  50.254 +		}
  50.255 +		i += ret;
  50.256  
  50.257 -		if (unlikely(txreq.size < ETH_HLEN) || 
  50.258 -		    unlikely(txreq.size > ETH_FRAME_LEN)) {
  50.259 +		if (unlikely(ret > MAX_SKB_FRAGS + 1)) {
  50.260 +			DPRINTK("Too many frags\n");
  50.261 +			netbk_tx_err(netif, i);
  50.262 +			continue;
  50.263 +		}
  50.264 +
  50.265 +		if (unlikely(txreq.size < ETH_HLEN)) {
  50.266  			DPRINTK("Bad packet size: %d\n", txreq.size);
  50.267 -			make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
  50.268 -			netif_put(netif);
  50.269 +			netbk_tx_err(netif, i);
  50.270  			continue; 
  50.271  		}
  50.272  
  50.273  		/* No crossing a page as the payload mustn't fragment. */
  50.274 -		if (unlikely((txreq.offset + txreq.size) >= PAGE_SIZE)) {
  50.275 +		if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
  50.276  			DPRINTK("txreq.offset: %x, size: %u, end: %lu\n", 
  50.277  				txreq.offset, txreq.size, 
  50.278  				(txreq.offset &~PAGE_MASK) + txreq.size);
  50.279 -			make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
  50.280 -			netif_put(netif);
  50.281 +			netbk_tx_err(netif, i);
  50.282  			continue;
  50.283  		}
  50.284  
  50.285  		pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
  50.286  
  50.287 -		data_len = (txreq.size > PKT_PROT_LEN) ?
  50.288 +		data_len = (txreq.size > PKT_PROT_LEN &&
  50.289 +			    ret < MAX_SKB_FRAGS + 1) ?
  50.290  			PKT_PROT_LEN : txreq.size;
  50.291  
  50.292  		skb = alloc_skb(data_len+16, GFP_ATOMIC);
  50.293  		if (unlikely(skb == NULL)) {
  50.294  			DPRINTK("Can't allocate a skb in start_xmit.\n");
  50.295 -			make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
  50.296 -			netif_put(netif);
  50.297 +			netbk_tx_err(netif, i);
  50.298  			break;
  50.299  		}
  50.300  
  50.301 @@ -600,10 +780,24 @@ static void net_tx_action(unsigned long 
  50.302  		pending_tx_info[pending_idx].netif = netif;
  50.303  		*((u16 *)skb->data) = pending_idx;
  50.304  
  50.305 +		__skb_put(skb, data_len);
  50.306 +
  50.307 +		skb_shinfo(skb)->nr_frags = ret - 1;
  50.308 +		if (data_len < txreq.size) {
  50.309 +			skb_shinfo(skb)->nr_frags++;
  50.310 +			skb_shinfo(skb)->frags[0].page =
  50.311 +				(void *)(unsigned long)pending_idx;
  50.312 +		}
  50.313 +
  50.314  		__skb_queue_tail(&tx_queue, skb);
  50.315  
  50.316  		pending_cons++;
  50.317  
  50.318 +		mop = netbk_get_requests(netif, skb, mop);
  50.319 +
  50.320 +		netif->tx.req_cons = i;
  50.321 +		netif_schedule_work(netif);
  50.322 +
  50.323  		if ((mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops))
  50.324  			break;
  50.325  	}
  50.326 @@ -617,75 +811,56 @@ static void net_tx_action(unsigned long 
  50.327  
  50.328  	mop = tx_map_ops;
  50.329  	while ((skb = __skb_dequeue(&tx_queue)) != NULL) {
  50.330 +		netif_tx_request_t *txp;
  50.331 +
  50.332  		pending_idx = *((u16 *)skb->data);
  50.333  		netif       = pending_tx_info[pending_idx].netif;
  50.334 -		memcpy(&txreq, &pending_tx_info[pending_idx].req,
  50.335 -		       sizeof(txreq));
  50.336 +		txp         = &pending_tx_info[pending_idx].req;
  50.337  
  50.338  		/* Check the remap error code. */
  50.339 -		if (unlikely(mop->status)) {
  50.340 +		if (unlikely(netbk_tx_check_mop(skb, &mop))) {
  50.341  			printk(KERN_ALERT "#### netback grant fails\n");
  50.342 -			make_tx_response(netif, txreq.id, NETIF_RSP_ERROR);
  50.343 -			netif_put(netif);
  50.344 +			skb_shinfo(skb)->nr_frags = 0;
  50.345  			kfree_skb(skb);
  50.346 -			mop++;
  50.347 -			pending_ring[MASK_PEND_IDX(pending_prod++)] =
  50.348 -				pending_idx;
  50.349  			continue;
  50.350  		}
  50.351 -		set_phys_to_machine(
  50.352 -			__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT,
  50.353 -			FOREIGN_FRAME(mop->dev_bus_addr >> PAGE_SHIFT));
  50.354 -		grant_tx_handle[pending_idx] = mop->handle;
  50.355  
  50.356 -		data_len = (txreq.size > PKT_PROT_LEN) ?
  50.357 -			PKT_PROT_LEN : txreq.size;
  50.358 -
  50.359 -		__skb_put(skb, data_len);
  50.360 +		data_len = skb->len;
  50.361  		memcpy(skb->data, 
  50.362 -		       (void *)(MMAP_VADDR(pending_idx)|txreq.offset),
  50.363 +		       (void *)(MMAP_VADDR(pending_idx)|txp->offset),
  50.364  		       data_len);
  50.365 -		if (data_len < txreq.size) {
  50.366 +		if (data_len < txp->size) {
  50.367  			/* Append the packet payload as a fragment. */
  50.368 -			skb_shinfo(skb)->frags[0].page        = 
  50.369 -				virt_to_page(MMAP_VADDR(pending_idx));
  50.370 -			skb_shinfo(skb)->frags[0].size        =
  50.371 -				txreq.size - data_len;
  50.372 -			skb_shinfo(skb)->frags[0].page_offset = 
  50.373 -				txreq.offset + data_len;
  50.374 -			skb_shinfo(skb)->nr_frags = 1;
  50.375 +			txp->offset += data_len;
  50.376 +			txp->size -= data_len;
  50.377  		} else {
  50.378  			/* Schedule a response immediately. */
  50.379  			netif_idx_release(pending_idx);
  50.380  		}
  50.381  
  50.382 -		skb->data_len  = txreq.size - data_len;
  50.383 -		skb->len      += skb->data_len;
  50.384 -		skb->truesize += skb->data_len;
  50.385 -
  50.386 -		skb->dev      = netif->dev;
  50.387 -		skb->protocol = eth_type_trans(skb, skb->dev);
  50.388 -
  50.389  		/*
  50.390  		 * Old frontends do not assert data_validated but we
  50.391  		 * can infer it from csum_blank so test both flags.
  50.392  		 */
  50.393 -		if (txreq.flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
  50.394 +		if (txp->flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
  50.395  			skb->ip_summed = CHECKSUM_UNNECESSARY;
  50.396  			skb->proto_data_valid = 1;
  50.397  		} else {
  50.398  			skb->ip_summed = CHECKSUM_NONE;
  50.399  			skb->proto_data_valid = 0;
  50.400  		}
  50.401 -		skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank);
  50.402 +		skb->proto_csum_blank = !!(txp->flags & NETTXF_csum_blank);
  50.403 +
  50.404 +		netbk_fill_frags(skb);
  50.405  
  50.406 -		netif->stats.rx_bytes += txreq.size;
  50.407 +		skb->dev      = netif->dev;
  50.408 +		skb->protocol = eth_type_trans(skb, skb->dev);
  50.409 +
  50.410 +		netif->stats.rx_bytes += skb->len;
  50.411  		netif->stats.rx_packets++;
  50.412  
  50.413  		netif_rx(skb);
  50.414  		netif->dev->last_rx = jiffies;
  50.415 -
  50.416 -		mop++;
  50.417  	}
  50.418  }
  50.419  
  50.420 @@ -695,7 +870,10 @@ static void netif_idx_release(u16 pendin
  50.421  	unsigned long flags;
  50.422  
  50.423  	spin_lock_irqsave(&_lock, flags);
  50.424 -	dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
  50.425 +	dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx;
  50.426 +	/* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */
  50.427 +	smp_wmb();
  50.428 +	dealloc_prod++;
  50.429  	spin_unlock_irqrestore(&_lock, flags);
  50.430  
  50.431  	tasklet_schedule(&net_tx_tasklet);
  50.432 @@ -720,8 +898,8 @@ irqreturn_t netif_be_int(int irq, void *
  50.433  }
  50.434  
  50.435  static void make_tx_response(netif_t *netif, 
  50.436 -                             u16      id,
  50.437 -                             s8       st)
  50.438 +			     u16      id,
  50.439 +			     s8       st)
  50.440  {
  50.441  	RING_IDX i = netif->tx.rsp_prod_pvt;
  50.442  	netif_tx_response_t *resp;
  50.443 @@ -747,11 +925,11 @@ static void make_tx_response(netif_t *ne
  50.444  }
  50.445  
  50.446  static int make_rx_response(netif_t *netif, 
  50.447 -                            u16      id, 
  50.448 -                            s8       st,
  50.449 -                            u16      offset,
  50.450 -                            u16      size,
  50.451 -                            u16      flags)
  50.452 +			    u16      id, 
  50.453 +			    s8       st,
  50.454 +			    u16      offset,
  50.455 +			    u16      size,
  50.456 +			    u16      flags)
  50.457  {
  50.458  	RING_IDX i = netif->rx.rsp_prod_pvt;
  50.459  	netif_rx_response_t *resp;
    51.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Tue Jun 13 09:00:32 2006 -0600
    51.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Tue Jun 13 12:12:24 2006 -0600
    51.3 @@ -44,7 +44,7 @@ static void backend_changed(struct xenbu
    51.4  
    51.5  static int netback_remove(struct xenbus_device *dev)
    51.6  {
    51.7 -	struct backend_info *be = dev->data;
    51.8 +	struct backend_info *be = dev->dev.driver_data;
    51.9  
   51.10  	if (be->backend_watch.node) {
   51.11  		unregister_xenbus_watch(&be->backend_watch);
   51.12 @@ -56,7 +56,7 @@ static int netback_remove(struct xenbus_
   51.13  		be->netif = NULL;
   51.14  	}
   51.15  	kfree(be);
   51.16 -	dev->data = NULL;
   51.17 +	dev->dev.driver_data = NULL;
   51.18  	return 0;
   51.19  }
   51.20  
   51.21 @@ -69,6 +69,8 @@ static int netback_remove(struct xenbus_
   51.22  static int netback_probe(struct xenbus_device *dev,
   51.23  			 const struct xenbus_device_id *id)
   51.24  {
   51.25 +	const char *message;
   51.26 +	struct xenbus_transaction xbt;
   51.27  	int err;
   51.28  	struct backend_info *be = kzalloc(sizeof(struct backend_info),
   51.29  					  GFP_KERNEL);
   51.30 @@ -79,13 +81,34 @@ static int netback_probe(struct xenbus_d
   51.31  	}
   51.32  
   51.33  	be->dev = dev;
   51.34 -	dev->data = be;
   51.35 +	dev->dev.driver_data = be;
   51.36  
   51.37  	err = xenbus_watch_path2(dev, dev->nodename, "handle",
   51.38  				 &be->backend_watch, backend_changed);
   51.39  	if (err)
   51.40  		goto fail;
   51.41  
   51.42 +	do {
   51.43 +		err = xenbus_transaction_start(&xbt);
   51.44 +		if (err) {
   51.45 +			xenbus_dev_fatal(dev, err, "starting transaction");
   51.46 +			goto fail;
   51.47 +		}
   51.48 +
   51.49 +		err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
   51.50 +		if (err) {
   51.51 +			message = "writing feature-sg";
   51.52 +			goto abort_transaction;
   51.53 +		}
   51.54 +
   51.55 +		err = xenbus_transaction_end(xbt, 0);
   51.56 +	} while (err == -EAGAIN);
   51.57 +
   51.58 +	if (err) {
   51.59 +		xenbus_dev_fatal(dev, err, "completing transaction");
   51.60 +		goto fail;
   51.61 +	}
   51.62 +
   51.63  	err = xenbus_switch_state(dev, XenbusStateInitWait);
   51.64  	if (err) {
   51.65  		goto fail;
   51.66 @@ -93,6 +116,9 @@ static int netback_probe(struct xenbus_d
   51.67  
   51.68  	return 0;
   51.69  
   51.70 +abort_transaction:
   51.71 +	xenbus_transaction_end(xbt, 1);
   51.72 +	xenbus_dev_fatal(dev, err, "%s", message);
   51.73  fail:
   51.74  	DPRINTK("failed");
   51.75  	netback_remove(dev);
   51.76 @@ -108,14 +134,14 @@ fail:
   51.77  static int netback_uevent(struct xenbus_device *xdev, char **envp,
   51.78  			  int num_envp, char *buffer, int buffer_size)
   51.79  {
   51.80 -	struct backend_info *be = xdev->data;
   51.81 +	struct backend_info *be = xdev->dev.driver_data;
   51.82  	netif_t *netif = be->netif;
   51.83  	int i = 0, length = 0;
   51.84  	char *val;
   51.85  
   51.86  	DPRINTK("netback_uevent");
   51.87  
   51.88 -	val = xenbus_read(XBT_NULL, xdev->nodename, "script", NULL);
   51.89 +	val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL);
   51.90  	if (IS_ERR(val)) {
   51.91  		int err = PTR_ERR(val);
   51.92  		xenbus_dev_fatal(xdev, err, "reading script");
   51.93 @@ -151,7 +177,7 @@ static void backend_changed(struct xenbu
   51.94  
   51.95  	DPRINTK("");
   51.96  
   51.97 -	err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%li", &handle);
   51.98 +	err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
   51.99  	if (XENBUS_EXIST_ERR(err)) {
  51.100  		/* Since this watch will fire once immediately after it is
  51.101  		   registered, we expect this.  Ignore it, and wait for the
  51.102 @@ -187,7 +213,7 @@ static void backend_changed(struct xenbu
  51.103  static void frontend_changed(struct xenbus_device *dev,
  51.104  			     enum xenbus_state frontend_state)
  51.105  {
  51.106 -	struct backend_info *be = dev->data;
  51.107 +	struct backend_info *be = dev->dev.driver_data;
  51.108  
  51.109  	DPRINTK("");
  51.110  
  51.111 @@ -242,7 +268,7 @@ static void xen_net_read_rate(struct xen
  51.112  	*bytes = ~0UL;
  51.113  	*usec = 0;
  51.114  
  51.115 -	ratestr = xenbus_read(XBT_NULL, dev->nodename, "rate", NULL);
  51.116 +	ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL);
  51.117  	if (IS_ERR(ratestr))
  51.118  		return;
  51.119  
  51.120 @@ -272,7 +298,7 @@ static int xen_net_read_mac(struct xenbu
  51.121  	char *s, *e, *macstr;
  51.122  	int i;
  51.123  
  51.124 -	macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
  51.125 +	macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
  51.126  	if (IS_ERR(macstr))
  51.127  		return PTR_ERR(macstr);
  51.128  
  51.129 @@ -321,7 +347,7 @@ static int connect_rings(struct backend_
  51.130  
  51.131  	DPRINTK("");
  51.132  
  51.133 -	err = xenbus_gather(XBT_NULL, dev->otherend,
  51.134 +	err = xenbus_gather(XBT_NIL, dev->otherend,
  51.135  			    "tx-ring-ref", "%lu", &tx_ring_ref,
  51.136  			    "rx-ring-ref", "%lu", &rx_ring_ref,
  51.137  			    "event-channel", "%u", &evtchn, NULL);
    52.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jun 13 09:00:32 2006 -0600
    52.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jun 13 12:12:24 2006 -0600
    52.3 @@ -45,6 +45,7 @@
    52.4  #include <linux/bitops.h>
    52.5  #include <linux/ethtool.h>
    52.6  #include <linux/in.h>
    52.7 +#include <linux/if_ether.h>
    52.8  #include <net/sock.h>
    52.9  #include <net/pkt_sched.h>
   52.10  #include <net/arp.h>
   52.11 @@ -137,14 +138,14 @@ static inline unsigned short get_id_from
   52.12  	return id;
   52.13  }
   52.14  
   52.15 -#define DPRINTK(fmt, args...) pr_debug("netfront (%s:%d) " fmt, \
   52.16 -                                       __FUNCTION__, __LINE__, ##args)
   52.17 +#define DPRINTK(fmt, args...)				\
   52.18 +	pr_debug("netfront (%s:%d) " fmt,		\
   52.19 +		 __FUNCTION__, __LINE__, ##args)
   52.20  #define IPRINTK(fmt, args...)				\
   52.21  	printk(KERN_INFO "netfront: " fmt, ##args)
   52.22  #define WPRINTK(fmt, args...)				\
   52.23  	printk(KERN_WARNING "netfront: " fmt, ##args)
   52.24  
   52.25 -
   52.26  static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
   52.27  static int setup_device(struct xenbus_device *, struct netfront_info *);
   52.28  static struct net_device *create_netdev(int, struct xenbus_device *);
   52.29 @@ -156,8 +157,6 @@ static void netif_disconnect_backend(str
   52.30  static void close_netdev(struct netfront_info *);
   52.31  static void netif_free(struct netfront_info *);
   52.32  
   52.33 -static void show_device(struct netfront_info *);
   52.34 -
   52.35  static void network_connect(struct net_device *);
   52.36  static void network_tx_buf_gc(struct net_device *);
   52.37  static void network_alloc_rx_buffers(struct net_device *);
   52.38 @@ -173,6 +172,11 @@ static void xennet_sysfs_delif(struct ne
   52.39  #define xennet_sysfs_delif(dev) do { } while(0)
   52.40  #endif
   52.41  
   52.42 +static inline int xennet_can_sg(struct net_device *dev)
   52.43 +{
   52.44 +	return dev->features & NETIF_F_SG;
   52.45 +}
   52.46 +
   52.47  /**
   52.48   * Entry point to this code when a new device is created.  Allocate the basic
   52.49   * structures and the ring buffers for communication with the backend, and
   52.50 @@ -187,7 +191,7 @@ static int __devinit netfront_probe(stru
   52.51  	struct netfront_info *info;
   52.52  	unsigned int handle;
   52.53  
   52.54 -	err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%u", &handle);
   52.55 +	err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
   52.56  	if (err != 1) {
   52.57  		xenbus_dev_fatal(dev, err, "reading handle");
   52.58  		return err;
   52.59 @@ -201,14 +205,14 @@ static int __devinit netfront_probe(stru
   52.60  	}
   52.61  
   52.62  	info = netdev_priv(netdev);
   52.63 -	dev->data = info;
   52.64 +	dev->dev.driver_data = info;
   52.65  
   52.66  	err = talk_to_backend(dev, info);
   52.67  	if (err) {
   52.68  		xennet_sysfs_delif(info->netdev);
   52.69  		unregister_netdev(netdev);
   52.70  		free_netdev(netdev);
   52.71 -		dev->data = NULL;
   52.72 +		dev->dev.driver_data = NULL;
   52.73  		return err;
   52.74  	}
   52.75  
   52.76 @@ -224,7 +228,7 @@ static int __devinit netfront_probe(stru
   52.77   */
   52.78  static int netfront_resume(struct xenbus_device *dev)
   52.79  {
   52.80 -	struct netfront_info *info = dev->data;
   52.81 +	struct netfront_info *info = dev->dev.driver_data;
   52.82  
   52.83  	DPRINTK("%s\n", dev->nodename);
   52.84  
   52.85 @@ -237,7 +241,7 @@ static int xen_net_read_mac(struct xenbu
   52.86  	char *s, *e, *macstr;
   52.87  	int i;
   52.88  
   52.89 -	macstr = s = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
   52.90 +	macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL);
   52.91  	if (IS_ERR(macstr))
   52.92  		return PTR_ERR(macstr);
   52.93  
   52.94 @@ -259,7 +263,7 @@ static int talk_to_backend(struct xenbus
   52.95  			   struct netfront_info *info)
   52.96  {
   52.97  	const char *message;
   52.98 -	xenbus_transaction_t xbt;
   52.99 +	struct xenbus_transaction xbt;
  52.100  	int err;
  52.101  
  52.102  	err = xen_net_read_mac(dev, info->mac);
  52.103 @@ -307,8 +311,6 @@ again:
  52.104  		goto destroy_ring;
  52.105  	}
  52.106  
  52.107 -	xenbus_switch_state(dev, XenbusStateConnected);
  52.108 -
  52.109  	return 0;
  52.110  
  52.111   abort_transaction:
  52.112 @@ -334,35 +336,36 @@ static int setup_device(struct xenbus_de
  52.113  	info->tx.sring = NULL;
  52.114  	info->irq = 0;
  52.115  
  52.116 -	txs = (struct netif_tx_sring *)__get_free_page(GFP_KERNEL);
  52.117 +	txs = (struct netif_tx_sring *)get_zeroed_page(GFP_KERNEL);
  52.118  	if (!txs) {
  52.119  		err = -ENOMEM;
  52.120  		xenbus_dev_fatal(dev, err, "allocating tx ring page");
  52.121  		goto fail;
  52.122  	}
  52.123 -	rxs = (struct netif_rx_sring *)__get_free_page(GFP_KERNEL);
  52.124 +	SHARED_RING_INIT(txs);
  52.125 +	FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
  52.126 +
  52.127 +	err = xenbus_grant_ring(dev, virt_to_mfn(txs));
  52.128 +	if (err < 0) {
  52.129 +		free_page((unsigned long)txs);
  52.130 +		goto fail;
  52.131 +	}
  52.132 +	info->tx_ring_ref = err;
  52.133 +
  52.134 +	rxs = (struct netif_rx_sring *)get_zeroed_page(GFP_KERNEL);
  52.135  	if (!rxs) {
  52.136  		err = -ENOMEM;
  52.137  		xenbus_dev_fatal(dev, err, "allocating rx ring page");
  52.138  		goto fail;
  52.139  	}
  52.140 -	memset(txs, 0, PAGE_SIZE);
  52.141 -	memset(rxs, 0, PAGE_SIZE);
  52.142 -
  52.143 -	SHARED_RING_INIT(txs);
  52.144 -	FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
  52.145 -
  52.146  	SHARED_RING_INIT(rxs);
  52.147  	FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
  52.148  
  52.149 -	err = xenbus_grant_ring(dev, virt_to_mfn(txs));
  52.150 -	if (err < 0)
  52.151 +	err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
  52.152 +	if (err < 0) {
  52.153 +		free_page((unsigned long)rxs);
  52.154  		goto fail;
  52.155 -	info->tx_ring_ref = err;
  52.156 -
  52.157 -	err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
  52.158 -	if (err < 0)
  52.159 -		goto fail;
  52.160 +	}
  52.161  	info->rx_ring_ref = err;
  52.162  
  52.163  	err = xenbus_alloc_evtchn(dev, &info->evtchn);
  52.164 @@ -370,13 +373,11 @@ static int setup_device(struct xenbus_de
  52.165  		goto fail;
  52.166  
  52.167  	memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
  52.168 -	network_connect(netdev);
  52.169 -	info->irq = bind_evtchn_to_irqhandler(
  52.170 -		info->evtchn, netif_int, SA_SAMPLE_RANDOM, netdev->name,
  52.171 -		netdev);
  52.172 -	(void)send_fake_arp(netdev);
  52.173 -	show_device(info);
  52.174 -
  52.175 +	err = bind_evtchn_to_irqhandler(info->evtchn, netif_int,
  52.176 +					SA_SAMPLE_RANDOM, netdev->name, netdev);
  52.177 +	if (err < 0)
  52.178 +		goto fail;
  52.179 +	info->irq = err;
  52.180  	return 0;
  52.181  
  52.182   fail:
  52.183 @@ -391,17 +392,25 @@ static int setup_device(struct xenbus_de
  52.184  static void backend_changed(struct xenbus_device *dev,
  52.185  			    enum xenbus_state backend_state)
  52.186  {
  52.187 +	struct netfront_info *np = dev->dev.driver_data;
  52.188 +	struct net_device *netdev = np->netdev;
  52.189 +
  52.190  	DPRINTK("\n");
  52.191  
  52.192  	switch (backend_state) {
  52.193  	case XenbusStateInitialising:
  52.194 -	case XenbusStateInitWait:
  52.195  	case XenbusStateInitialised:
  52.196  	case XenbusStateConnected:
  52.197  	case XenbusStateUnknown:
  52.198  	case XenbusStateClosed:
  52.199  		break;
  52.200  
  52.201 +	case XenbusStateInitWait:
  52.202 +		network_connect(netdev);
  52.203 +		xenbus_switch_state(dev, XenbusStateConnected);
  52.204 +		(void)send_fake_arp(netdev);
  52.205 +		break;
  52.206 +
  52.207  	case XenbusStateClosing:
  52.208  		netfront_closing(dev);
  52.209  		break;
  52.210 @@ -452,13 +461,17 @@ static int network_open(struct net_devic
  52.211  	return 0;
  52.212  }
  52.213  
  52.214 +static inline int netfront_tx_slot_available(struct netfront_info *np)
  52.215 +{
  52.216 +	return RING_FREE_REQUESTS(&np->tx) >= MAX_SKB_FRAGS + 1;
  52.217 +}
  52.218 +
  52.219  static inline void network_maybe_wake_tx(struct net_device *dev)
  52.220  {
  52.221  	struct netfront_info *np = netdev_priv(dev);
  52.222  
  52.223  	if (unlikely(netif_queue_stopped(dev)) &&
  52.224 -	    !RING_FULL(&np->tx) &&
  52.225 -	    !gnttab_empty_grant_references(&np->gref_tx_head) &&
  52.226 +	    netfront_tx_slot_available(np) &&
  52.227  	    likely(netif_running(dev)))
  52.228  		netif_wake_queue(dev);
  52.229  }
  52.230 @@ -485,7 +498,7 @@ static void network_tx_buf_gc(struct net
  52.231  				printk(KERN_ALERT "network_tx_buf_gc: warning "
  52.232  				       "-- grant still in use by backend "
  52.233  				       "domain.\n");
  52.234 -				break; /* bail immediately */
  52.235 +				BUG();
  52.236  			}
  52.237  			gnttab_end_foreign_access_ref(
  52.238  				np->grant_tx_ref[id], GNTMAP_readonly);
  52.239 @@ -589,7 +602,7 @@ static void network_alloc_rx_buffers(str
  52.240  		np->grant_rx_ref[id] = ref;
  52.241  		gnttab_grant_foreign_transfer_ref(ref,
  52.242  						  np->xbdev->otherend_id,
  52.243 -						  __pa(skb->head) >> PAGE_SHIFT);
  52.244 +						  __pa(skb->head)>>PAGE_SHIFT);
  52.245  		RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
  52.246  		np->rx_pfn_array[i] = virt_to_mfn(skb->head);
  52.247  
  52.248 @@ -638,36 +651,95 @@ static void network_alloc_rx_buffers(str
  52.249  	RING_PUSH_REQUESTS(&np->rx);
  52.250  }
  52.251  
  52.252 +static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
  52.253 +			      struct netif_tx_request *tx)
  52.254 +{
  52.255 +	struct netfront_info *np = netdev_priv(dev);
  52.256 +	char *data = skb->data;
  52.257 +	unsigned long mfn;
  52.258 +	RING_IDX prod = np->tx.req_prod_pvt;
  52.259 +	int frags = skb_shinfo(skb)->nr_frags;
  52.260 +	unsigned int offset = offset_in_page(data);
  52.261 +	unsigned int len = skb_headlen(skb);
  52.262 +	unsigned int id;
  52.263 +	grant_ref_t ref;
  52.264 +	int i;
  52.265 +
  52.266 +	while (len > PAGE_SIZE - offset) {
  52.267 +		tx->size = PAGE_SIZE - offset;
  52.268 +		tx->flags |= NETTXF_more_data;
  52.269 +		len -= tx->size;
  52.270 +		data += tx->size;
  52.271 +		offset = 0;
  52.272 +
  52.273 +		id = get_id_from_freelist(np->tx_skbs);
  52.274 +		np->tx_skbs[id] = skb_get(skb);
  52.275 +		tx = RING_GET_REQUEST(&np->tx, prod++);
  52.276 +		tx->id = id;
  52.277 +		ref = gnttab_claim_grant_reference(&np->gref_tx_head);
  52.278 +		BUG_ON((signed short)ref < 0);
  52.279 +
  52.280 +		mfn = virt_to_mfn(data);
  52.281 +		gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
  52.282 +						mfn, GNTMAP_readonly);
  52.283 +
  52.284 +		tx->gref = np->grant_tx_ref[id] = ref;
  52.285 +		tx->offset = offset;
  52.286 +		tx->size = len;
  52.287 +		tx->flags = 0;
  52.288 +	}
  52.289 +
  52.290 +	for (i = 0; i < frags; i++) {
  52.291 +		skb_frag_t *frag = skb_shinfo(skb)->frags + i;
  52.292 +
  52.293 +		tx->flags |= NETTXF_more_data;
  52.294 +
  52.295 +		id = get_id_from_freelist(np->tx_skbs);
  52.296 +		np->tx_skbs[id] = skb_get(skb);
  52.297 +		tx = RING_GET_REQUEST(&np->tx, prod++);
  52.298 +		tx->id = id;
  52.299 +		ref = gnttab_claim_grant_reference(&np->gref_tx_head);
  52.300 +		BUG_ON((signed short)ref < 0);
  52.301 +
  52.302 +		mfn = pfn_to_mfn(page_to_pfn(frag->page));
  52.303 +		gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
  52.304 +						mfn, GNTMAP_readonly);
  52.305 +
  52.306 +		tx->gref = np->grant_tx_ref[id] = ref;
  52.307 +		tx->offset = frag->page_offset;
  52.308 +		tx->size = frag->size;
  52.309 +		tx->flags = 0;
  52.310 +	}
  52.311 +
  52.312 +	np->tx.req_prod_pvt = prod;
  52.313 +}
  52.314  
  52.315  static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
  52.316  {
  52.317  	unsigned short id;
  52.318  	struct netfront_info *np = netdev_priv(dev);
  52.319  	struct netif_tx_request *tx;
  52.320 +	char *data = skb->data;
  52.321  	RING_IDX i;
  52.322  	grant_ref_t ref;
  52.323  	unsigned long mfn;
  52.324  	int notify;
  52.325 +	int frags = skb_shinfo(skb)->nr_frags;
  52.326 +	unsigned int offset = offset_in_page(data);
  52.327 +	unsigned int len = skb_headlen(skb);
  52.328  
  52.329 -	if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >=
  52.330 -		     PAGE_SIZE)) {
  52.331 -		struct sk_buff *nskb;
  52.332 -		nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN);
  52.333 -		if (unlikely(nskb == NULL))
  52.334 -			goto drop;
  52.335 -		skb_put(nskb, skb->len);
  52.336 -		memcpy(nskb->data, skb->data, skb->len);
  52.337 -		/* Copy only the header fields we use in this driver. */
  52.338 -		nskb->dev = skb->dev;
  52.339 -		nskb->ip_summed = skb->ip_summed;
  52.340 -		nskb->proto_data_valid = skb->proto_data_valid;
  52.341 -		dev_kfree_skb(skb);
  52.342 -		skb = nskb;
  52.343 +	frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
  52.344 +	if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
  52.345 +		printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
  52.346 +		       frags);
  52.347 +		dump_stack();
  52.348 +		goto drop;
  52.349  	}
  52.350  
  52.351  	spin_lock_irq(&np->tx_lock);
  52.352  
  52.353 -	if (unlikely(!netif_carrier_ok(dev))) {
  52.354 +	if (unlikely(!netif_carrier_ok(dev) ||
  52.355 +		     (frags > 1 && !xennet_can_sg(dev)))) {
  52.356  		spin_unlock_irq(&np->tx_lock);
  52.357  		goto drop;
  52.358  	}
  52.359 @@ -682,12 +754,12 @@ static int network_start_xmit(struct sk_
  52.360  	tx->id   = id;
  52.361  	ref = gnttab_claim_grant_reference(&np->gref_tx_head);
  52.362  	BUG_ON((signed short)ref < 0);
  52.363 -	mfn = virt_to_mfn(skb->data);
  52.364 +	mfn = virt_to_mfn(data);
  52.365  	gnttab_grant_foreign_access_ref(
  52.366  		ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly);
  52.367  	tx->gref = np->grant_tx_ref[id] = ref;
  52.368 -	tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
  52.369 -	tx->size = skb->len;
  52.370 +	tx->offset = offset;
  52.371 +	tx->size = len;
  52.372  
  52.373  	tx->flags = 0;
  52.374  	if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
  52.375 @@ -696,14 +768,17 @@ static int network_start_xmit(struct sk_
  52.376  		tx->flags |= NETTXF_data_validated;
  52.377  
  52.378  	np->tx.req_prod_pvt = i + 1;
  52.379 +
  52.380 +	xennet_make_frags(skb, dev, tx);
  52.381 +	tx->size = skb->len;
  52.382 +
  52.383  	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
  52.384  	if (notify)
  52.385  		notify_remote_via_irq(np->irq);
  52.386  
  52.387  	network_tx_buf_gc(dev);
  52.388  
  52.389 -	if (RING_FULL(&np->tx) ||
  52.390 -	    gnttab_empty_grant_references(&np->gref_tx_head))
  52.391 +	if (!netfront_tx_slot_available(np))
  52.392  		netif_stop_queue(dev);
  52.393  
  52.394  	spin_unlock_irq(&np->tx_lock);
  52.395 @@ -771,10 +846,10 @@ static int netif_poll(struct net_device 
  52.396  		rx = RING_GET_RESPONSE(&np->rx, i);
  52.397  
  52.398  		/*
  52.399 -                 * This definitely indicates a bug, either in this driver or
  52.400 -                 * in the backend driver. In future this should flag the bad
  52.401 -                 * situation to the system controller to reboot the backed.
  52.402 -                 */
  52.403 +		 * This definitely indicates a bug, either in this driver or in
  52.404 +		 * the backend driver. In future this should flag the bad
  52.405 +		 * situation to the system controller to reboot the backed.
  52.406 +		 */
  52.407  		if ((ref = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) {
  52.408  			WPRINTK("Bad rx response id %d.\n", rx->id);
  52.409  			work_done--;
  52.410 @@ -963,6 +1038,38 @@ static struct net_device_stats *network_
  52.411  	return &np->stats;
  52.412  }
  52.413  
  52.414 +static int xennet_change_mtu(struct net_device *dev, int mtu)
  52.415 +{
  52.416 +	int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
  52.417 +
  52.418 +	if (mtu > max)
  52.419 +		return -EINVAL;
  52.420 +	dev->mtu = mtu;
  52.421 +	return 0;
  52.422 +}
  52.423 +
  52.424 +static int xennet_set_sg(struct net_device *dev, u32 data)
  52.425 +{
  52.426 +	if (data) {
  52.427 +		struct netfront_info *np = netdev_priv(dev);
  52.428 +		int val;
  52.429 +
  52.430 +		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
  52.431 +				 "%d", &val) < 0)
  52.432 +			val = 0;
  52.433 +		if (!val)
  52.434 +			return -ENOSYS;
  52.435 +	} else if (dev->mtu > ETH_DATA_LEN)
  52.436 +		dev->mtu = ETH_DATA_LEN;
  52.437 +
  52.438 +	return ethtool_op_set_sg(dev, data);
  52.439 +}
  52.440 +
  52.441 +static void xennet_set_features(struct net_device *dev)
  52.442 +{
  52.443 +	xennet_set_sg(dev, 1);
  52.444 +}
  52.445 +
  52.446  static void network_connect(struct net_device *dev)
  52.447  {
  52.448  	struct netfront_info *np;
  52.449 @@ -970,6 +1077,8 @@ static void network_connect(struct net_d
  52.450  	struct netif_tx_request *tx;
  52.451  	struct sk_buff *skb;
  52.452  
  52.453 +	xennet_set_features(dev);
  52.454 +
  52.455  	np = netdev_priv(dev);
  52.456  	spin_lock_irq(&np->tx_lock);
  52.457  	spin_lock(&np->rx_lock);
  52.458 @@ -1054,22 +1163,6 @@ static void network_connect(struct net_d
  52.459  	spin_unlock_irq(&np->tx_lock);
  52.460  }
  52.461  
  52.462 -static void show_device(struct netfront_info *np)
  52.463 -{
  52.464 -#ifdef DEBUG
  52.465 -	if (np) {
  52.466 -		IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n",
  52.467 -			np->handle,
  52.468 -			netif_carrier_ok(np->netdev) ? "on" : "off",
  52.469 -			netif_running(np->netdev) ? "open" : "closed",
  52.470 -			np->evtchn,
  52.471 -			np->tx,
  52.472 -			np->rx);
  52.473 -	} else
  52.474 -		IPRINTK("<vif NULL>\n");
  52.475 -#endif
  52.476 -}
  52.477 -
  52.478  static void netif_uninit(struct net_device *dev)
  52.479  {
  52.480  	struct netfront_info *np = netdev_priv(dev);
  52.481 @@ -1081,6 +1174,8 @@ static struct ethtool_ops network_ethtoo
  52.482  {
  52.483  	.get_tx_csum = ethtool_op_get_tx_csum,
  52.484  	.set_tx_csum = ethtool_op_set_tx_csum,
  52.485 +	.get_sg = ethtool_op_get_sg,
  52.486 +	.set_sg = xennet_set_sg,
  52.487  };
  52.488  
  52.489  #ifdef CONFIG_SYSFS
  52.490 @@ -1285,7 +1380,6 @@ static struct net_device * __devinit cre
  52.491  	if (gnttab_alloc_grant_references(RX_MAX_TARGET,
  52.492  					  &np->gref_rx_head) < 0) {
  52.493  		printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
  52.494 -		gnttab_free_grant_references(np->gref_tx_head);
  52.495  		err = -ENOMEM;
  52.496  		goto exit_free_tx;
  52.497  	}
  52.498 @@ -1297,6 +1391,7 @@ static struct net_device * __devinit cre
  52.499  	netdev->poll            = netif_poll;
  52.500  	netdev->set_multicast_list = network_set_multicast_list;
  52.501  	netdev->uninit          = netif_uninit;
  52.502 +	netdev->change_mtu	= xennet_change_mtu;
  52.503  	netdev->weight          = 64;
  52.504  	netdev->features        = NETIF_F_IP_CSUM;
  52.505  
  52.506 @@ -1361,7 +1456,7 @@ inetdev_notify(struct notifier_block *th
  52.507   */
  52.508  static void netfront_closing(struct xenbus_device *dev)
  52.509  {
  52.510 -	struct netfront_info *info = dev->data;
  52.511 +	struct netfront_info *info = dev->dev.driver_data;
  52.512  
  52.513  	DPRINTK("netfront_closing: %s removed\n", dev->nodename);
  52.514  
  52.515 @@ -1373,7 +1468,7 @@ static void netfront_closing(struct xenb
  52.516  
  52.517  static int __devexit netfront_remove(struct xenbus_device *dev)
  52.518  {
  52.519 -	struct netfront_info *info = dev->data;
  52.520 +	struct netfront_info *info = dev->dev.driver_data;
  52.521  
  52.522  	DPRINTK("%s\n", dev->nodename);
  52.523  
    53.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c	Tue Jun 13 09:00:32 2006 -0600
    53.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c	Tue Jun 13 12:12:24 2006 -0600
    53.3 @@ -23,7 +23,7 @@ static struct pciback_device *alloc_pdev
    53.4  	dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
    53.5  
    53.6  	pdev->xdev = xdev;
    53.7 -	xdev->data = pdev;
    53.8 +	xdev->dev.driver_data = pdev;
    53.9  
   53.10  	spin_lock_init(&pdev->dev_lock);
   53.11  
   53.12 @@ -61,7 +61,7 @@ static void free_pdev(struct pciback_dev
   53.13  
   53.14  	pciback_release_devices(pdev);
   53.15  
   53.16 -	pdev->xdev->data = NULL;
   53.17 +	pdev->xdev->dev.driver_data = NULL;
   53.18  	pdev->xdev = NULL;
   53.19  
   53.20  	kfree(pdev);
   53.21 @@ -125,7 +125,7 @@ static int pciback_attach(struct pciback
   53.22  
   53.23  	dev_dbg(&pdev->xdev->dev, "Reading frontend config\n");
   53.24  
   53.25 -	err = xenbus_gather(XBT_NULL, pdev->xdev->otherend,
   53.26 +	err = xenbus_gather(XBT_NIL, pdev->xdev->otherend,
   53.27  			    "pci-op-ref", "%u", &gnt_ref,
   53.28  			    "event-channel", "%u", &remote_evtchn,
   53.29  			    "magic", NULL, &magic, NULL);
   53.30 @@ -168,7 +168,7 @@ static int pciback_attach(struct pciback
   53.31  static void pciback_frontend_changed(struct xenbus_device *xdev,
   53.32  				     enum xenbus_state fe_state)
   53.33  {
   53.34 -	struct pciback_device *pdev = xdev->data;
   53.35 +	struct pciback_device *pdev = xdev->dev.driver_data;
   53.36  
   53.37  	dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state);
   53.38  
   53.39 @@ -200,7 +200,7 @@ static int pciback_publish_pci_root(stru
   53.40  
   53.41  	dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n");
   53.42  
   53.43 -	err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename,
   53.44 +	err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
   53.45  			   "root_num", "%d", &root_num);
   53.46  	if (err == 0 || err == -ENOENT)
   53.47  		root_num = 0;
   53.48 @@ -215,7 +215,7 @@ static int pciback_publish_pci_root(stru
   53.49  			goto out;
   53.50  		}
   53.51  
   53.52 -		err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename,
   53.53 +		err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename,
   53.54  				   str, "%x:%x", &d, &b);
   53.55  		if (err < 0)
   53.56  			goto out;
   53.57 @@ -239,12 +239,12 @@ static int pciback_publish_pci_root(stru
   53.58  	dev_dbg(&pdev->xdev->dev, "writing root %d at %04x:%02x\n",
   53.59  		root_num, domain, bus);
   53.60  
   53.61 -	err = xenbus_printf(XBT_NULL, pdev->xdev->nodename, str,
   53.62 +	err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str,
   53.63  			    "%04x:%02x", domain, bus);
   53.64  	if (err)
   53.65  		goto out;
   53.66  
   53.67 -	err = xenbus_printf(XBT_NULL, pdev->xdev->nodename,
   53.68 +	err = xenbus_printf(XBT_NIL, pdev->xdev->nodename,
   53.69  			    "root_num", "%d", (root_num + 1));
   53.70  
   53.71        out:
   53.72 @@ -306,7 +306,7 @@ static int pciback_setup_backend(struct 
   53.73  
   53.74  	dev_dbg(&pdev->xdev->dev, "getting be setup\n");
   53.75  
   53.76 -	err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, "num_devs", "%d",
   53.77 +	err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d",
   53.78  			   &num_devs);
   53.79  	if (err != 1) {
   53.80  		if (err >= 0)
   53.81 @@ -326,7 +326,7 @@ static int pciback_setup_backend(struct 
   53.82  			goto out;
   53.83  		}
   53.84  
   53.85 -		err = xenbus_scanf(XBT_NULL, pdev->xdev->nodename, dev_str,
   53.86 +		err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, dev_str,
   53.87  				   "%x:%x:%x.%x", &domain, &bus, &slot, &func);
   53.88  		if (err < 0) {
   53.89  			xenbus_dev_fatal(pdev->xdev, err,
   53.90 @@ -421,7 +421,7 @@ static int pciback_xenbus_probe(struct x
   53.91  
   53.92  static int pciback_xenbus_remove(struct xenbus_device *dev)
   53.93  {
   53.94 -	struct pciback_device *pdev = dev->data;
   53.95 +	struct pciback_device *pdev = dev->dev.driver_data;
   53.96  
   53.97  	if (pdev != NULL)
   53.98  		free_pdev(pdev);
    54.1 --- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c	Tue Jun 13 09:00:32 2006 -0600
    54.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c	Tue Jun 13 12:12:24 2006 -0600
    54.3 @@ -29,7 +29,7 @@ static struct pcifront_device *alloc_pde
    54.4  	}
    54.5  	pdev->sh_info->flags = 0;
    54.6  
    54.7 -	xdev->data = pdev;
    54.8 +	xdev->dev.driver_data = pdev;
    54.9  	pdev->xdev = xdev;
   54.10  
   54.11  	INIT_LIST_HEAD(&pdev->root_buses);
   54.12 @@ -59,7 +59,7 @@ static void free_pdev(struct pcifront_de
   54.13  		gnttab_end_foreign_access(pdev->gnt_ref, 0,
   54.14  					  (unsigned long)pdev->sh_info);
   54.15  
   54.16 -	pdev->xdev->data = NULL;
   54.17 +	pdev->xdev->dev.driver_data = NULL;
   54.18  
   54.19  	kfree(pdev);
   54.20  }
   54.21 @@ -67,7 +67,7 @@ static void free_pdev(struct pcifront_de
   54.22  static int pcifront_publish_info(struct pcifront_device *pdev)
   54.23  {
   54.24  	int err = 0;
   54.25 -	xenbus_transaction_t trans;
   54.26 +	struct xenbus_transaction trans;
   54.27  
   54.28  	err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info));
   54.29  	if (err < 0)
   54.30 @@ -143,7 +143,7 @@ static int pcifront_try_connect(struct p
   54.31  		goto out;
   54.32  	}
   54.33  
   54.34 -	err = xenbus_scanf(XBT_NULL, pdev->xdev->otherend,
   54.35 +	err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend,
   54.36  			   "root_num", "%d", &num_roots);
   54.37  	if (err == -ENOENT) {
   54.38  		xenbus_dev_error(pdev->xdev, err,
   54.39 @@ -165,7 +165,7 @@ static int pcifront_try_connect(struct p
   54.40  			goto out;
   54.41  		}
   54.42  
   54.43 -		err = xenbus_scanf(XBT_NULL, pdev->xdev->otherend, str,
   54.44 +		err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str,
   54.45  				   "%x:%x", &domain, &bus);
   54.46  		if (err != 2) {
   54.47  			if (err >= 0)
   54.48 @@ -216,7 +216,7 @@ static int pcifront_try_disconnect(struc
   54.49  static void pcifront_backend_changed(struct xenbus_device *xdev,
   54.50  				     enum xenbus_state be_state)
   54.51  {
   54.52 -	struct pcifront_device *pdev = xdev->data;
   54.53 +	struct pcifront_device *pdev = xdev->dev.driver_data;
   54.54  
   54.55  	switch (be_state) {
   54.56  	case XenbusStateClosing:
   54.57 @@ -261,8 +261,8 @@ static int pcifront_xenbus_probe(struct 
   54.58  
   54.59  static int pcifront_xenbus_remove(struct xenbus_device *xdev)
   54.60  {
   54.61 -	if (xdev->data)
   54.62 -		free_pdev(xdev->data);
   54.63 +	if (xdev->dev.driver_data)
   54.64 +		free_pdev(xdev->dev.driver_data);
   54.65  
   54.66  	return 0;
   54.67  }
    55.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Tue Jun 13 09:00:32 2006 -0600
    55.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Tue Jun 13 12:12:24 2006 -0600
    55.3 @@ -39,7 +39,7 @@ static struct proc_dir_entry *capabiliti
    55.4  static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
    55.5  
    55.6  static int privcmd_ioctl(struct inode *inode, struct file *file,
    55.7 -                         unsigned int cmd, unsigned long data)
    55.8 +			 unsigned int cmd, unsigned long data)
    55.9  {
   55.10  	int ret = -ENOSYS;
   55.11  	void __user *udata = (void __user *) data;
   55.12 @@ -61,11 +61,11 @@ static int privcmd_ioctl(struct inode *i
   55.13  		__asm__ __volatile__ (
   55.14  			"pushl %%ebx; pushl %%ecx; pushl %%edx; "
   55.15  			"pushl %%esi; pushl %%edi; "
   55.16 -			"movl  4(%%eax),%%ebx ;"
   55.17 -			"movl  8(%%eax),%%ecx ;"
   55.18 -			"movl 12(%%eax),%%edx ;"
   55.19 -			"movl 16(%%eax),%%esi ;"
   55.20 -			"movl 20(%%eax),%%edi ;"
   55.21 +			"movl  8(%%eax),%%ebx ;"
   55.22 +			"movl 16(%%eax),%%ecx ;"
   55.23 +			"movl 24(%%eax),%%edx ;"
   55.24 +			"movl 32(%%eax),%%esi ;"
   55.25 +			"movl 40(%%eax),%%edi ;"
   55.26  			"movl   (%%eax),%%eax ;"
   55.27  			"shll $5,%%eax ;"
   55.28  			"addl $hypercall_page,%%eax ;"
   55.29 @@ -161,7 +161,7 @@ static int privcmd_ioctl(struct inode *i
   55.30  	case IOCTL_PRIVCMD_MMAPBATCH: {
   55.31  		privcmd_mmapbatch_t m;
   55.32  		struct vm_area_struct *vma = NULL;
   55.33 -		unsigned long __user *p;
   55.34 +		xen_pfn_t __user *p;
   55.35  		unsigned long addr, mfn; 
   55.36  		int i;
   55.37  
   55.38 @@ -210,7 +210,7 @@ static int privcmd_ioctl(struct inode *i
   55.39  	batch_err:
   55.40  		printk("batch_err ret=%d vma=%p addr=%lx "
   55.41  		       "num=%d arr=%p %lx-%lx\n", 
   55.42 -		       ret, vma, m.addr, m.num, m.arr,
   55.43 +		       ret, vma, (unsigned long)m.addr, m.num, m.arr,
   55.44  		       vma ? vma->vm_start : 0, vma ? vma->vm_end : 0);
   55.45  		break;
   55.46  	}
   55.47 @@ -241,7 +241,7 @@ static struct file_operations privcmd_fi
   55.48  };
   55.49  
   55.50  static int capabilities_read(char *page, char **start, off_t off,
   55.51 -                        int count, int *eof, void *data)
   55.52 +			     int count, int *eof, void *data)
   55.53  {
   55.54  	int len = 0;
   55.55  	*page = 0;
    56.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Tue Jun 13 09:00:32 2006 -0600
    56.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Tue Jun 13 12:12:24 2006 -0600
    56.3 @@ -17,8 +17,9 @@
    56.4  #include <asm/io.h>
    56.5  #include <asm/pgalloc.h>
    56.6  
    56.7 -#define DPRINTK(_f, _a...) pr_debug("(file=%s, line=%d) " _f, \
    56.8 -                                    __FILE__ , __LINE__ , ## _a )
    56.9 +#define DPRINTK(_f, _a...)			\
   56.10 +	pr_debug("(file=%s, line=%d) " _f,	\
   56.11 +		 __FILE__ , __LINE__ , ## _a )
   56.12  
   56.13  typedef struct tpmif_st {
   56.14  	struct list_head tpmif_list;
   56.15 @@ -68,12 +69,11 @@ int tpmif_vtpm_close(u32 instance);
   56.16  int vtpm_release_packets(tpmif_t * tpmif, int send_msgs);
   56.17  
   56.18  #define tpmif_get(_b) (atomic_inc(&(_b)->refcnt))
   56.19 -#define tpmif_put(_b)                             \
   56.20 -    do {                                          \
   56.21 -        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
   56.22 -            tpmif_disconnect_complete(_b);        \
   56.23 -    } while (0)
   56.24 -
   56.25 +#define tpmif_put(_b)					\
   56.26 +	do {						\
   56.27 +		if (atomic_dec_and_test(&(_b)->refcnt))	\
   56.28 +			tpmif_disconnect_complete(_b);	\
   56.29 +	} while (0)
   56.30  
   56.31  extern int num_frontends;
   56.32  
    57.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Tue Jun 13 09:00:32 2006 -0600
    57.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Tue Jun 13 12:12:24 2006 -0600
    57.3 @@ -41,13 +41,13 @@ static void maybe_connect(struct backend
    57.4  static void connect(struct backend_info *be);
    57.5  static int connect_ring(struct backend_info *be);
    57.6  static void backend_changed(struct xenbus_watch *watch,
    57.7 -                            const char **vec, unsigned int len);
    57.8 +			    const char **vec, unsigned int len);
    57.9  static void frontend_changed(struct xenbus_device *dev,
   57.10 -                             enum xenbus_state frontend_state);
   57.11 +			     enum xenbus_state frontend_state);
   57.12  
   57.13  static int tpmback_remove(struct xenbus_device *dev)
   57.14  {
   57.15 -	struct backend_info *be = dev->data;
   57.16 +	struct backend_info *be = dev->dev.driver_data;
   57.17  
   57.18  	if (!be) return 0;
   57.19  
   57.20 @@ -62,30 +62,30 @@ static int tpmback_remove(struct xenbus_
   57.21  		be->tpmif = NULL;
   57.22  	}
   57.23  	kfree(be);
   57.24 -	dev->data = NULL;
   57.25 +	dev->dev.driver_data = NULL;
   57.26  	return 0;
   57.27  }
   57.28  
   57.29  static int tpmback_probe(struct xenbus_device *dev,
   57.30 -                         const struct xenbus_device_id *id)
   57.31 +			 const struct xenbus_device_id *id)
   57.32  {
   57.33  	int err;
   57.34  	struct backend_info *be = kzalloc(sizeof(struct backend_info),
   57.35 -	                                  GFP_KERNEL);
   57.36 +					  GFP_KERNEL);
   57.37  
   57.38  	if (!be) {
   57.39  		xenbus_dev_fatal(dev, -ENOMEM,
   57.40 -		                 "allocating backend structure");
   57.41 +				 "allocating backend structure");
   57.42  		return -ENOMEM;
   57.43  	}
   57.44  
   57.45  	be->is_instance_set = 0;
   57.46  	be->dev = dev;
   57.47 -	dev->data = be;
   57.48 +	dev->dev.driver_data = be;
   57.49  
   57.50  	err = xenbus_watch_path2(dev, dev->nodename,
   57.51 -	                        "instance", &be->backend_watch,
   57.52 -	                        backend_changed);
   57.53 +				 "instance", &be->backend_watch,
   57.54 +				 backend_changed);
   57.55  	if (err) {
   57.56  		goto fail;
   57.57  	}
   57.58 @@ -102,7 +102,7 @@ fail:
   57.59  
   57.60  
   57.61  static void backend_changed(struct xenbus_watch *watch,
   57.62 -                            const char **vec, unsigned int len)
   57.63 +			    const char **vec, unsigned int len)
   57.64  {
   57.65  	int err;
   57.66  	long instance;
   57.67 @@ -110,8 +110,8 @@ static void backend_changed(struct xenbu
   57.68  		= container_of(watch, struct backend_info, backend_watch);
   57.69  	struct xenbus_device *dev = be->dev;
   57.70  
   57.71 -	err = xenbus_scanf(XBT_NULL, dev->nodename,
   57.72 -	                   "instance","%li", &instance);
   57.73 +	err = xenbus_scanf(XBT_NIL, dev->nodename,
   57.74 +			   "instance","%li", &instance);
   57.75  	if (XENBUS_EXIST_ERR(err)) {
   57.76  		return;
   57.77  	}
   57.78 @@ -129,9 +129,9 @@ static void backend_changed(struct xenbu
   57.79  
   57.80  
   57.81  static void frontend_changed(struct xenbus_device *dev,
   57.82 -                             enum xenbus_state frontend_state)
   57.83 +			     enum xenbus_state frontend_state)
   57.84  {
   57.85 -	struct backend_info *be = dev->data;
   57.86 +	struct backend_info *be = dev->dev.driver_data;
   57.87  	int err;
   57.88  
   57.89  	be->frontend_state = frontend_state;
   57.90 @@ -167,8 +167,8 @@ static void frontend_changed(struct xenb
   57.91  	case XenbusStateInitWait:
   57.92  	default:
   57.93  		xenbus_dev_fatal(dev, -EINVAL,
   57.94 -		                 "saw state %d at frontend",
   57.95 -		                 frontend_state);
   57.96 +				 "saw state %d at frontend",
   57.97 +				 frontend_state);
   57.98  		break;
   57.99  	}
  57.100  }
  57.101 @@ -188,11 +188,11 @@ static void maybe_connect(struct backend
  57.102  	 * Notify the vTPM manager about a new front-end.
  57.103  	 */
  57.104  	err = tpmif_vtpm_open(be->tpmif,
  57.105 -	                      be->frontend_id,
  57.106 -	                      be->instance);
  57.107 +			      be->frontend_id,
  57.108 +			      be->instance);
  57.109  	if (err) {
  57.110  		xenbus_dev_error(be->dev, err,
  57.111 -		                 "queueing vtpm open packet");
  57.112 +				 "queueing vtpm open packet");
  57.113  		/*
  57.114  		 * Should close down this device and notify FE
  57.115  		 * about closure.
  57.116 @@ -204,7 +204,7 @@ static void maybe_connect(struct backend
  57.117  
  57.118  static void connect(struct backend_info *be)
  57.119  {
  57.120 -	xenbus_transaction_t xbt;
  57.121 +	struct xenbus_transaction xbt;
  57.122  	int err;
  57.123  	struct xenbus_device *dev = be->dev;
  57.124  	unsigned long ready = 1;
  57.125 @@ -217,7 +217,7 @@ again:
  57.126  	}
  57.127  
  57.128  	err = xenbus_printf(xbt, be->dev->nodename,
  57.129 -	                    "ready", "%lu", ready);
  57.130 +			    "ready", "%lu", ready);
  57.131  	if (err) {
  57.132  		xenbus_dev_fatal(be->dev, err, "writing 'ready'");
  57.133  		goto abort;
  57.134 @@ -245,8 +245,8 @@ static int connect_ring(struct backend_i
  57.135  	unsigned int evtchn;
  57.136  	int err;
  57.137  
  57.138 -	err = xenbus_gather(XBT_NULL, dev->otherend,
  57.139 -	                    "ring-ref", "%lu", &ring_ref,
  57.140 +	err = xenbus_gather(XBT_NIL, dev->otherend,
  57.141 +			    "ring-ref", "%lu", &ring_ref,
  57.142  			    "event-channel", "%u", &evtchn, NULL);
  57.143  	if (err) {
  57.144  		xenbus_dev_error(dev, err,
  57.145 @@ -257,7 +257,7 @@ static int connect_ring(struct backend_i
  57.146  
  57.147  	if (!be->tpmif) {
  57.148  		be->tpmif = tpmif_find(dev->otherend_id,
  57.149 -		                       be->instance);
  57.150 +				       be->instance);
  57.151  		if (IS_ERR(be->tpmif)) {
  57.152  			err = PTR_ERR(be->tpmif);
  57.153  			be->tpmif = NULL;
  57.154 @@ -270,8 +270,8 @@ static int connect_ring(struct backend_i
  57.155  		err = tpmif_map(be->tpmif, ring_ref, evtchn);
  57.156  		if (err) {
  57.157  			xenbus_dev_error(dev, err,
  57.158 -			    	         "mapping shared-frame %lu port %u",
  57.159 -				         ring_ref, evtchn);
  57.160 +					 "mapping shared-frame %lu port %u",
  57.161 +					 ring_ref, evtchn);
  57.162  			return err;
  57.163  		}
  57.164  	}
    58.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Tue Jun 13 09:00:32 2006 -0600
    58.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Tue Jun 13 12:12:24 2006 -0600
    58.3 @@ -106,12 +106,12 @@ int xenbus_switch_state(struct xenbus_de
    58.4  	if (state == dev->state)
    58.5  		return 0;
    58.6  
    58.7 -	err = xenbus_scanf(XBT_NULL, dev->nodename, "state", "%d",
    58.8 +	err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
    58.9  			   &current_state);
   58.10  	if (err != 1)
   58.11  		return 0;
   58.12  
   58.13 -	err = xenbus_printf(XBT_NULL, dev->nodename, "state", "%d", state);
   58.14 +	err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
   58.15  	if (err) {
   58.16  		if (state != XenbusStateClosing) /* Avoid looping */
   58.17  			xenbus_dev_fatal(dev, err, "writing new state");
   58.18 @@ -162,7 +162,7 @@ void _dev_error(struct xenbus_device *de
   58.19  		goto fail;
   58.20  	}
   58.21  
   58.22 -	if (xenbus_write(XBT_NULL, path_buffer, "error", printf_buffer) != 0) {
   58.23 +	if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) {
   58.24  		printk("xenbus: failed to write error node for %s (%s)\n",
   58.25  		       dev->nodename, printf_buffer);
   58.26  		goto fail;
   58.27 @@ -272,7 +272,7 @@ int xenbus_free_evtchn(struct xenbus_dev
   58.28  enum xenbus_state xenbus_read_driver_state(const char *path)
   58.29  {
   58.30  	enum xenbus_state result;
   58.31 -	int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL);
   58.32 +	int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL);
   58.33  	if (err)
   58.34  		result = XenbusStateClosed;
   58.35  
    59.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Tue Jun 13 09:00:32 2006 -0600
    59.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Tue Jun 13 12:12:24 2006 -0600
    59.3 @@ -51,7 +51,7 @@
    59.4  
    59.5  struct xenbus_dev_transaction {
    59.6  	struct list_head list;
    59.7 -	xenbus_transaction_t handle;
    59.8 +	struct xenbus_transaction handle;
    59.9  };
   59.10  
   59.11  struct xenbus_dev_data {
   59.12 @@ -154,11 +154,11 @@ static ssize_t xenbus_dev_write(struct f
   59.13  		}
   59.14  
   59.15  		if (msg_type == XS_TRANSACTION_START) {
   59.16 -			trans->handle = simple_strtoul(reply, NULL, 0);
   59.17 +			trans->handle.id = simple_strtoul(reply, NULL, 0);
   59.18  			list_add(&trans->list, &u->transactions);
   59.19  		} else if (msg_type == XS_TRANSACTION_END) {
   59.20  			list_for_each_entry(trans, &u->transactions, list)
   59.21 -				if (trans->handle == u->u.msg.tx_id)
   59.22 +				if (trans->handle.id == u->u.msg.tx_id)
   59.23  					break;
   59.24  			BUG_ON(&trans->list == &u->transactions);
   59.25  			list_del(&trans->list);
    60.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jun 13 09:00:32 2006 -0600
    60.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Tue Jun 13 12:12:24 2006 -0600
    60.3 @@ -30,8 +30,9 @@
    60.4   * IN THE SOFTWARE.
    60.5   */
    60.6  
    60.7 -#define DPRINTK(fmt, args...) \
    60.8 -    pr_debug("xenbus_probe (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
    60.9 +#define DPRINTK(fmt, args...)				\
   60.10 +	pr_debug("xenbus_probe (%s:%d) " fmt ".\n",	\
   60.11 +		 __FUNCTION__, __LINE__, ##args)
   60.12  
   60.13  #include <linux/kernel.h>
   60.14  #include <linux/err.h>
   60.15 @@ -128,7 +129,7 @@ static void free_otherend_watch(struct x
   60.16  static int read_otherend_details(struct xenbus_device *xendev,
   60.17  				 char *id_node, char *path_node)
   60.18  {
   60.19 -	int err = xenbus_gather(XBT_NULL, xendev->nodename,
   60.20 +	int err = xenbus_gather(XBT_NIL, xendev->nodename,
   60.21  				id_node, "%i", &xendev->otherend_id,
   60.22  				path_node, NULL, &xendev->otherend,
   60.23  				NULL);
   60.24 @@ -139,7 +140,7 @@ static int read_otherend_details(struct 
   60.25  		return err;
   60.26  	}
   60.27  	if (strlen(xendev->otherend) == 0 ||
   60.28 -	    !xenbus_exists(XBT_NULL, xendev->otherend, "")) {
   60.29 +	    !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
   60.30  		xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
   60.31  				 xendev->nodename);
   60.32  		free_otherend_details(xendev);
   60.33 @@ -195,14 +196,14 @@ static int backend_bus_id(char bus_id[BU
   60.34  
   60.35  	devid = strrchr(nodename, '/') + 1;
   60.36  
   60.37 -	err = xenbus_gather(XBT_NULL, nodename, "frontend-id", "%i", &domid,
   60.38 +	err = xenbus_gather(XBT_NIL, nodename, "frontend-id", "%i", &domid,
   60.39  			    "frontend", NULL, &frontend,
   60.40  			    NULL);
   60.41  	if (err)
   60.42  		return err;
   60.43  	if (strlen(frontend) == 0)
   60.44  		err = -ERANGE;
   60.45 -	if (!err && !xenbus_exists(XBT_NULL, frontend, ""))
   60.46 +	if (!err && !xenbus_exists(XBT_NIL, frontend, ""))
   60.47  		err = -ENOENT;
   60.48  
   60.49  	kfree(frontend);
   60.50 @@ -634,7 +635,7 @@ static int xenbus_probe_backend(const ch
   60.51  	if (!nodename)
   60.52  		return -ENOMEM;
   60.53  
   60.54 -	dir = xenbus_directory(XBT_NULL, nodename, "", &dir_n);
   60.55 +	dir = xenbus_directory(XBT_NIL, nodename, "", &dir_n);
   60.56  	if (IS_ERR(dir)) {
   60.57  		kfree(nodename);
   60.58  		return PTR_ERR(dir);
   60.59 @@ -657,7 +658,7 @@ static int xenbus_probe_device_type(stru
   60.60  	unsigned int dir_n = 0;
   60.61  	int i;
   60.62  
   60.63 -	dir = xenbus_directory(XBT_NULL, bus->root, type, &dir_n);
   60.64 +	dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n);
   60.65  	if (IS_ERR(dir))
   60.66  		return PTR_ERR(dir);
   60.67  
   60.68 @@ -676,7 +677,7 @@ static int xenbus_probe_devices(struct x
   60.69  	char **dir;
   60.70  	unsigned int i, dir_n;
   60.71  
   60.72 -	dir = xenbus_directory(XBT_NULL, bus->root, "", &dir_n);
   60.73 +	dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n);
   60.74  	if (IS_ERR(dir))
   60.75  		return PTR_ERR(dir);
   60.76  
   60.77 @@ -722,7 +723,7 @@ static void dev_changed(const char *node
   60.78  	if (char_count(node, '/') < 2)
   60.79   		return;
   60.80  
   60.81 -	exists = xenbus_exists(XBT_NULL, node, "");
   60.82 +	exists = xenbus_exists(XBT_NIL, node, "");
   60.83  	if (!exists) {
   60.84  		xenbus_cleanup_devices(node, &bus->bus);
   60.85  		return;
   60.86 @@ -806,6 +807,7 @@ static int resume_dev(struct device *dev
   60.87  
   60.88  	if (dev->driver == NULL)
   60.89  		return 0;
   60.90 +
   60.91  	drv = to_xenbus_driver(dev->driver);
   60.92  	xdev = container_of(dev, struct xenbus_device, dev);
   60.93  
   60.94 @@ -817,6 +819,18 @@ static int resume_dev(struct device *dev
   60.95  		return err;
   60.96  	}
   60.97  
   60.98 +	xdev->state = XenbusStateInitialising;
   60.99 +
  60.100 +	if (drv->resume) {
  60.101 +		err = drv->resume(xdev);
  60.102 +		if (err) { 
  60.103 +			printk(KERN_WARNING
  60.104 +			       "xenbus: resume %s failed: %i\n", 
  60.105 +			       dev->bus_id, err);
  60.106 +			return err; 
  60.107 +		}
  60.108 +	}
  60.109 +
  60.110  	err = watch_otherend(xdev);
  60.111  	if (err) {
  60.112  		printk(KERN_WARNING
  60.113 @@ -825,14 +839,7 @@ static int resume_dev(struct device *dev
  60.114  		return err;
  60.115  	}
  60.116  
  60.117 -	xdev->state = XenbusStateInitialising;
  60.118 -
  60.119 -	if (drv->resume)
  60.120 -		err = drv->resume(xdev);
  60.121 -	if (err)
  60.122 -		printk(KERN_WARNING
  60.123 -		       "xenbus: resume %s failed: %i\n", dev->bus_id, err);
  60.124 -	return err;
  60.125 +	return 0; 
  60.126  }
  60.127  
  60.128  void xenbus_suspend(void)
  60.129 @@ -939,7 +946,7 @@ static int xsd_kva_mmap(struct file *fil
  60.130  }
  60.131  
  60.132  static int xsd_kva_read(char *page, char **start, off_t off,
  60.133 -                        int count, int *eof, void *data)
  60.134 +			int count, int *eof, void *data)
  60.135  {
  60.136  	int len;
  60.137  
  60.138 @@ -1038,10 +1045,10 @@ static int __init xenbus_probe_init(void
  60.139  		free_page(page);
  60.140  
  60.141  	/*
  60.142 -         * Do not unregister the xenbus front/backend buses here. The
  60.143 -         * buses must exist because front/backend drivers will use
  60.144 -         * them when they are registered.
  60.145 -         */
  60.146 +	 * Do not unregister the xenbus front/backend buses here. The buses
  60.147 +	 * must exist because front/backend drivers will use them when they are
  60.148 +	 * registered.
  60.149 +	 */
  60.150  
  60.151  	return err;
  60.152  }
    61.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Jun 13 09:00:32 2006 -0600
    61.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Tue Jun 13 12:12:24 2006 -0600
    61.3 @@ -192,7 +192,7 @@ void *xenbus_dev_request_and_reply(struc
    61.4  }
    61.5  
    61.6  /* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
    61.7 -static void *xs_talkv(xenbus_transaction_t t,
    61.8 +static void *xs_talkv(struct xenbus_transaction t,
    61.9  		      enum xsd_sockmsg_type type,
   61.10  		      const struct kvec *iovec,
   61.11  		      unsigned int num_vecs,
   61.12 @@ -203,7 +203,7 @@ static void *xs_talkv(xenbus_transaction
   61.13  	unsigned int i;
   61.14  	int err;
   61.15  
   61.16 -	msg.tx_id = t;
   61.17 +	msg.tx_id = t.id;
   61.18  	msg.req_id = 0;
   61.19  	msg.type = type;
   61.20  	msg.len = 0;
   61.21 @@ -251,7 +251,7 @@ static void *xs_talkv(xenbus_transaction
   61.22  }
   61.23  
   61.24  /* Simplified version of xs_talkv: single message. */
   61.25 -static void *xs_single(xenbus_transaction_t t,
   61.26 +static void *xs_single(struct xenbus_transaction t,
   61.27  		       enum xsd_sockmsg_type type,
   61.28  		       const char *string,
   61.29  		       unsigned int *len)
   61.30 @@ -318,7 +318,7 @@ static char **split(char *strings, unsig
   61.31  	return ret;
   61.32  }
   61.33  
   61.34 -char **xenbus_directory(xenbus_transaction_t t,
   61.35 +char **xenbus_directory(struct xenbus_transaction t,
   61.36  			const char *dir, const char *node, unsigned int *num)
   61.37  {
   61.38  	char *strings, *path;
   61.39 @@ -338,7 +338,7 @@ char **xenbus_directory(xenbus_transacti
   61.40  EXPORT_SYMBOL_GPL(xenbus_directory);
   61.41  
   61.42  /* Check if a path exists. Return 1 if it does. */
   61.43 -int xenbus_exists(xenbus_transaction_t t,
   61.44 +int xenbus_exists(struct xenbus_transaction t,
   61.45  		  const char *dir, const char *node)
   61.46  {
   61.47  	char **d;
   61.48 @@ -356,7 +356,7 @@ EXPORT_SYMBOL_GPL(xenbus_exists);
   61.49   * Returns a kmalloced value: call free() on it after use.
   61.50   * len indicates length in bytes.
   61.51   */
   61.52 -void *xenbus_read(xenbus_transaction_t t,
   61.53 +void *xenbus_read(struct xenbus_transaction t,
   61.54  		  const char *dir, const char *node, unsigned int *len)
   61.55  {
   61.56  	char *path;
   61.57 @@ -375,7 +375,7 @@ EXPORT_SYMBOL_GPL(xenbus_read);
   61.58  /* Write the value of a single file.
   61.59   * Returns -err on failure.
   61.60   */
   61.61 -int xenbus_write(xenbus_transaction_t t,
   61.62 +int xenbus_write(struct xenbus_transaction t,
   61.63  		 const char *dir, const char *node, const char *string)
   61.64  {
   61.65  	const char *path;
   61.66 @@ -398,7 +398,7 @@ int xenbus_write(xenbus_transaction_t t,
   61.67  EXPORT_SYMBOL_GPL(xenbus_write);
   61.68  
   61.69  /* Create a new directory. */
   61.70 -int xenbus_mkdir(xenbus_transaction_t t,
   61.71 +int xenbus_mkdir(struct xenbus_transaction t,
   61.72  		 const char *dir, const char *node)
   61.73  {
   61.74  	char *path;
   61.75 @@ -415,7 +415,7 @@ int xenbus_mkdir(xenbus_transaction_t t,
   61.76  EXPORT_SYMBOL_GPL(xenbus_mkdir);
   61.77  
   61.78  /* Destroy a file or directory (directories must be empty). */
   61.79 -int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node)
   61.80 +int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node)
   61.81  {
   61.82  	char *path;
   61.83  	int ret;
   61.84 @@ -433,19 +433,19 @@ EXPORT_SYMBOL_GPL(xenbus_rm);
   61.85  /* Start a transaction: changes by others will not be seen during this
   61.86   * transaction, and changes will not be visible to others until end.
   61.87   */
   61.88 -int xenbus_transaction_start(xenbus_transaction_t *t)
   61.89 +int xenbus_transaction_start(struct xenbus_transaction *t)
   61.90  {
   61.91  	char *id_str;
   61.92  
   61.93  	down_read(&xs_state.suspend_mutex);
   61.94  
   61.95 -	id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL);
   61.96 +	id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL);
   61.97  	if (IS_ERR(id_str)) {
   61.98  		up_read(&xs_state.suspend_mutex);
   61.99  		return PTR_ERR(id_str);
  61.100  	}
  61.101  
  61.102 -	*t = simple_strtoul(id_str, NULL, 0);
  61.103 +	t->id = simple_strtoul(id_str, NULL, 0);
  61.104  	kfree(id_str);
  61.105  	return 0;
  61.106  }
  61.107 @@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(xenbus_transaction_sta
  61.108  /* End a transaction.
  61.109   * If abandon is true, transaction is discarded instead of committed.
  61.110   */
  61.111 -int xenbus_transaction_end(xenbus_transaction_t t, int abort)
  61.112 +int xenbus_transaction_end(struct xenbus_transaction t, int abort)
  61.113  {
  61.114  	char abortstr[2];
  61.115  	int err;
  61.116 @@ -473,7 +473,7 @@ int xenbus_transaction_end(xenbus_transa
  61.117  EXPORT_SYMBOL_GPL(xenbus_transaction_end);
  61.118  
  61.119  /* Single read and scanf: returns -errno or num scanned. */
  61.120 -int xenbus_scanf(xenbus_transaction_t t,
  61.121 +int xenbus_scanf(struct xenbus_transaction t,
  61.122  		 const char *dir, const char *node, const char *fmt, ...)
  61.123  {
  61.124  	va_list ap;
  61.125 @@ -496,7 +496,7 @@ int xenbus_scanf(xenbus_transaction_t t,
  61.126  EXPORT_SYMBOL_GPL(xenbus_scanf);
  61.127  
  61.128  /* Single printf and write: returns -errno or 0. */
  61.129 -int xenbus_printf(xenbus_transaction_t t,
  61.130 +int xenbus_printf(struct xenbus_transaction t,
  61.131  		  const char *dir, const char *node, const char *fmt, ...)
  61.132  {
  61.133  	va_list ap;
  61.134 @@ -522,7 +522,7 @@ int xenbus_printf(xenbus_transaction_t t
  61.135  EXPORT_SYMBOL_GPL(xenbus_printf);
  61.136  
  61.137  /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
  61.138 -int xenbus_gather(xenbus_transaction_t t, const char *dir, ...)
  61.139 +int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
  61.140  {
  61.141  	va_list ap;
  61.142  	const char *name;
  61.143 @@ -560,7 +560,7 @@ static int xs_watch(const char *path, co
  61.144  	iov[1].iov_base = (void *)token;
  61.145  	iov[1].iov_len = strlen(token) + 1;
  61.146  
  61.147 -	return xs_error(xs_talkv(XBT_NULL, XS_WATCH, iov,
  61.148 +	return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov,
  61.149  				 ARRAY_SIZE(iov), NULL));
  61.150  }
  61.151  
  61.152 @@ -573,7 +573,7 @@ static int xs_unwatch(const char *path, 
  61.153  	iov[1].iov_base = (char *)token;
  61.154  	iov[1].iov_len = strlen(token) + 1;
  61.155  
  61.156 -	return xs_error(xs_talkv(XBT_NULL, XS_UNWATCH, iov,
  61.157 +	return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov,
  61.158  				 ARRAY_SIZE(iov), NULL));
  61.159  }
  61.160  
    62.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h	Tue Jun 13 09:00:32 2006 -0600
    62.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hw_irq.h	Tue Jun 13 12:12:24 2006 -0600
    62.3 @@ -68,6 +68,10 @@ extern atomic_t irq_mis_count;
    62.4  
    62.5  #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
    62.6  
    62.7 -extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
    62.8 +extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i);
    62.9 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
   62.10 +{
   62.11 +	resend_irq_on_evtchn(h, i);
   62.12 +}
   62.13  
   62.14  #endif /* _ASM_HW_IRQ_H */
    63.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Tue Jun 13 09:00:32 2006 -0600
    63.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h	Tue Jun 13 12:12:24 2006 -0600
    63.3 @@ -255,6 +255,7 @@ HYPERVISOR_event_channel_op(
    63.4  		op.cmd = cmd;
    63.5  		memcpy(&op.u, arg, sizeof(op.u));
    63.6  		rc = _hypercall1(int, event_channel_op_compat, &op);
    63.7 +		memcpy(arg, &op.u, sizeof(op.u));
    63.8  	}
    63.9  	return rc;
   63.10  }
   63.11 @@ -290,6 +291,7 @@ HYPERVISOR_physdev_op(
   63.12  		op.cmd = cmd;
   63.13  		memcpy(&op.u, arg, sizeof(op.u));
   63.14  		rc = _hypercall1(int, physdev_op_compat, &op);
   63.15 +		memcpy(arg, &op.u, sizeof(op.u));
   63.16  	}
   63.17  	return rc;
   63.18  }
    64.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h	Tue Jun 13 09:00:32 2006 -0600
    64.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/system.h	Tue Jun 13 12:12:24 2006 -0600
    64.3 @@ -116,10 +116,12 @@ extern struct task_struct * FASTCALL(__s
    64.4  	__asm__ ( \
    64.5  		"movl %%cr3,%0\n\t" \
    64.6  		:"=r" (__dummy)); \
    64.7 -	machine_to_phys(__dummy); \
    64.8 +	__dummy = xen_cr3_to_pfn(__dummy); \
    64.9 +	mfn_to_pfn(__dummy) << PAGE_SHIFT; \
   64.10  })
   64.11  #define write_cr3(x) ({						\
   64.12 -	maddr_t __dummy = phys_to_machine(x);			\
   64.13 +	unsigned int __dummy = pfn_to_mfn((x) >> PAGE_SHIFT);	\
   64.14 +	__dummy = xen_pfn_to_cr3(__dummy);			\
   64.15  	__asm__ __volatile__("movl %0,%%cr3": :"r" (__dummy));	\
   64.16  })
   64.17  
    65.1 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Tue Jun 13 09:00:32 2006 -0600
    65.2 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h	Tue Jun 13 12:12:24 2006 -0600
    65.3 @@ -61,13 +61,6 @@ static void __init machine_specific_arch
    65.4  		.address = { __KERNEL_CS, (unsigned long)nmi },
    65.5  	};
    65.6  
    65.7 -	if (xen_feature(XENFEAT_auto_translated_physmap) &&
    65.8 -	    xen_start_info->shared_info < xen_start_info->nr_pages) {
    65.9 -		HYPERVISOR_shared_info =
   65.10 -			(shared_info_t *)__va(xen_start_info->shared_info);
   65.11 -		memset(empty_zero_page, 0, sizeof(empty_zero_page));
   65.12 -	}
   65.13 -
   65.14  	ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
   65.15  	if (ret == 0)
   65.16  		ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
    66.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h	Tue Jun 13 09:00:32 2006 -0600
    66.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hw_irq.h	Tue Jun 13 12:12:24 2006 -0600
    66.3 @@ -90,15 +90,18 @@ extern void free_irq_vector (int vector)
    66.4  extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
    66.5  extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
    66.6  
    66.7 -#ifndef CONFIG_XEN
    66.8  static inline void
    66.9  hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
   66.10  {
   66.11 +#ifdef CONFIG_XEN
   66.12 +	extern void resend_irq_on_evtchn(struct hw_interrupt_type *h,
   66.13 +					 unsigned int i);
   66.14 +	if (is_running_on_xen())
   66.15 +		resend_irq_on_evtchn(h, vector);
   66.16 +	else
   66.17 +#endif /* CONFIG_XEN */
   66.18  	platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
   66.19  }
   66.20 -#else
   66.21 -extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
   66.22 -#endif /* CONFIG_XEN */
   66.23  
   66.24  /*
   66.25   * Default implementations for the irq-descriptor API:
    67.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/page.h	Tue Jun 13 09:00:32 2006 -0600
    67.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h	Tue Jun 13 12:12:24 2006 -0600
    67.3 @@ -327,6 +327,16 @@ machine_to_phys_for_dma(unsigned long ma
    67.4  #define virt_to_mfn(virt)		(__pa(virt) >> PAGE_SHIFT)
    67.5  #define virt_to_machine(virt)		__pa(virt) // for tpmfront.c
    67.6  
    67.7 +static inline unsigned long
    67.8 +mfn_to_local_pfn(unsigned long mfn)
    67.9 +{
   67.10 +	extern unsigned long max_mapnr;
   67.11 +	unsigned long pfn = mfn_to_pfn(mfn);
   67.12 +	if (!pfn_valid(pfn))
   67.13 +		return INVALID_P2M_ENTRY;
   67.14 +	return pfn;
   67.15 +}
   67.16 +
   67.17  #endif /* CONFIG_XEN_IA64_DOM0_VP */
   67.18  #endif /* CONFIG_XEN */
   67.19  #endif /* __ASSEMBLY__ */
    68.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h	Tue Jun 13 09:00:32 2006 -0600
    68.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hw_irq.h	Tue Jun 13 12:12:24 2006 -0600
    68.3 @@ -132,7 +132,11 @@ asmlinkage void IRQ_NAME(nr); \
    68.4  	"push $" #nr "-256 ; " \
    68.5  	"jmp common_interrupt");
    68.6  
    68.7 -extern void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i);
    68.8 +extern void resend_irq_on_evtchn(struct hw_interrupt_type *h, unsigned int i);
    68.9 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
   68.10 +{
   68.11 +	resend_irq_on_evtchn(h, i);
   68.12 +}
   68.13  
   68.14  #define platform_legacy_irq(irq)	((irq) < 16)
   68.15  
    69.1 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Tue Jun 13 09:00:32 2006 -0600
    69.2 +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h	Tue Jun 13 12:12:24 2006 -0600
    69.3 @@ -253,6 +253,7 @@ HYPERVISOR_event_channel_op(
    69.4  		op.cmd = cmd;
    69.5  		memcpy(&op.u, arg, sizeof(op.u));
    69.6  		rc = _hypercall1(int, event_channel_op_compat, &op);
    69.7 +		memcpy(arg, &op.u, sizeof(op.u));
    69.8  	}
    69.9  	return rc;
   69.10  }
   69.11 @@ -288,6 +289,7 @@ HYPERVISOR_physdev_op(
   69.12  		op.cmd = cmd;
   69.13  		memcpy(&op.u, arg, sizeof(op.u));
   69.14  		rc = _hypercall1(int, physdev_op_compat, &op);
   69.15 +		memcpy(arg, &op.u, sizeof(op.u));
   69.16  	}
   69.17  	return rc;
   69.18  }
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/linux-2.6-xen-sparse/include/linux/interrupt.h	Tue Jun 13 12:12:24 2006 -0600
    70.3 @@ -0,0 +1,301 @@
    70.4 +/* interrupt.h */
    70.5 +#ifndef _LINUX_INTERRUPT_H
    70.6 +#define _LINUX_INTERRUPT_H
    70.7 +
    70.8 +#include <linux/config.h>
    70.9 +#include <linux/kernel.h>
   70.10 +#include <linux/linkage.h>
   70.11 +#include <linux/bitops.h>
   70.12 +#include <linux/preempt.h>
   70.13 +#include <linux/cpumask.h>
   70.14 +#include <linux/hardirq.h>
   70.15 +#include <linux/sched.h>
   70.16 +#include <asm/atomic.h>
   70.17 +#include <asm/ptrace.h>
   70.18 +#include <asm/system.h>
   70.19 +
   70.20 +/*
   70.21 + * For 2.4.x compatibility, 2.4.x can use
   70.22 + *
   70.23 + *	typedef void irqreturn_t;
   70.24 + *	#define IRQ_NONE
   70.25 + *	#define IRQ_HANDLED
   70.26 + *	#define IRQ_RETVAL(x)
   70.27 + *
   70.28 + * To mix old-style and new-style irq handler returns.
   70.29 + *
   70.30 + * IRQ_NONE means we didn't handle it.
   70.31 + * IRQ_HANDLED means that we did have a valid interrupt and handled it.
   70.32 + * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)
   70.33 + */
   70.34 +typedef int irqreturn_t;
   70.35 +
   70.36 +#define IRQ_NONE	(0)
   70.37 +#define IRQ_HANDLED	(1)
   70.38 +#define IRQ_RETVAL(x)	((x) != 0)
   70.39 +
   70.40 +struct irqaction {
   70.41 +	irqreturn_t (*handler)(int, void *, struct pt_regs *);
   70.42 +	unsigned long flags;
   70.43 +	cpumask_t mask;
   70.44 +	const char *name;
   70.45 +	void *dev_id;
   70.46 +	struct irqaction *next;
   70.47 +	int irq;
   70.48 +	struct proc_dir_entry *dir;
   70.49 +};
   70.50 +
   70.51 +extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
   70.52 +extern int request_irq(unsigned int,
   70.53 +		       irqreturn_t (*handler)(int, void *, struct pt_regs *),
   70.54 +		       unsigned long, const char *, void *);
   70.55 +extern void free_irq(unsigned int, void *);
   70.56 +
   70.57 +
   70.58 +#ifdef CONFIG_GENERIC_HARDIRQS
   70.59 +extern void disable_irq_nosync(unsigned int irq);
   70.60 +extern void disable_irq(unsigned int irq);
   70.61 +extern void enable_irq(unsigned int irq);
   70.62 +#endif
   70.63 +
   70.64 +#ifdef CONFIG_HAVE_IRQ_IGNORE_UNHANDLED
   70.65 +int irq_ignore_unhandled(unsigned int irq);
   70.66 +#else
   70.67 +#define irq_ignore_unhandled(irq) 0
   70.68 +#endif
   70.69 +
   70.70 +#ifndef __ARCH_SET_SOFTIRQ_PENDING
   70.71 +#define set_softirq_pending(x) (local_softirq_pending() = (x))
   70.72 +#define or_softirq_pending(x)  (local_softirq_pending() |= (x))
   70.73 +#endif
   70.74 +
   70.75 +/*
   70.76 + * Temporary defines for UP kernels, until all code gets fixed.
   70.77 + */
   70.78 +#ifndef CONFIG_SMP
   70.79 +static inline void __deprecated cli(void)
   70.80 +{
   70.81 +	local_irq_disable();
   70.82 +}
   70.83 +static inline void __deprecated sti(void)
   70.84 +{
   70.85 +	local_irq_enable();
   70.86 +}
   70.87 +static inline void __deprecated save_flags(unsigned long *x)
   70.88 +{
   70.89 +	local_save_flags(*x);
   70.90 +}
   70.91 +#define save_flags(x) save_flags(&x)
   70.92 +static inline void __deprecated restore_flags(unsigned long x)
   70.93 +{
   70.94 +	local_irq_restore(x);
   70.95 +}
   70.96 +
   70.97 +static inline void __deprecated save_and_cli(unsigned long *x)
   70.98 +{
   70.99 +	local_irq_save(*x);
  70.100 +}
  70.101 +#define save_and_cli(x)	save_and_cli(&x)
  70.102 +#endif /* CONFIG_SMP */
  70.103 +
  70.104 +/* SoftIRQ primitives.  */
  70.105 +#define local_bh_disable() \
  70.106 +		do { add_preempt_count(SOFTIRQ_OFFSET); barrier(); } while (0)
  70.107 +#define __local_bh_enable() \
  70.108 +		do { barrier(); sub_preempt_count(SOFTIRQ_OFFSET); } while (0)
  70.109 +
  70.110 +extern void local_bh_enable(void);
  70.111 +
  70.112 +/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
  70.113 +   frequency threaded job scheduling. For almost all the purposes
  70.114 +   tasklets are more than enough. F.e. all serial device BHs et
  70.115 +   al. should be converted to tasklets, not to softirqs.
  70.116 + */
  70.117 +
  70.118 +enum
  70.119 +{
  70.120 +	HI_SOFTIRQ=0,
  70.121 +	TIMER_SOFTIRQ,
  70.122 +	NET_TX_SOFTIRQ,
  70.123 +	NET_RX_SOFTIRQ,
  70.124 +	BLOCK_SOFTIRQ,
  70.125 +	TASKLET_SOFTIRQ
  70.126 +};
  70.127 +
  70.128 +/* softirq mask and active fields moved to irq_cpustat_t in
  70.129 + * asm/hardirq.h to get better cache usage.  KAO
  70.130 + */
  70.131 +
  70.132 +struct softirq_action
  70.133 +{
  70.134 +	void	(*action)(struct softirq_action *);
  70.135 +	void	*data;
  70.136 +};
  70.137 +
  70.138 +asmlinkage void do_softirq(void);
  70.139 +extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
  70.140 +extern void softirq_init(void);
  70.141 +#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
  70.142 +extern void FASTCALL(raise_softirq_irqoff(unsigned int nr));
  70.143 +extern void FASTCALL(raise_softirq(unsigned int nr));
  70.144 +
  70.145 +
  70.146 +/* Tasklets --- multithreaded analogue of BHs.
  70.147 +
  70.148 +   Main feature differing them of generic softirqs: tasklet
  70.149 +   is running only on one CPU simultaneously.
  70.150 +
  70.151 +   Main feature differing them of BHs: different tasklets
  70.152 +   may be run simultaneously on different CPUs.
  70.153 +
  70.154 +   Properties:
  70.155 +   * If tasklet_schedule() is called, then tasklet is guaranteed
  70.156 +     to be executed on some cpu at least once after this.
  70.157 +   * If the tasklet is already scheduled, but its excecution is still not
  70.158 +     started, it will be executed only once.
  70.159 +   * If this tasklet is already running on another CPU (or schedule is called
  70.160 +     from tasklet itself), it is rescheduled for later.
  70.161 +   * Tasklet is strictly serialized wrt itself, but not
  70.162 +     wrt another tasklets. If client needs some intertask synchronization,
  70.163 +     he makes it with spinlocks.
  70.164 + */
  70.165 +
  70.166 +struct tasklet_struct
  70.167 +{
  70.168 +	struct tasklet_struct *next;
  70.169 +	unsigned long state;
  70.170 +	atomic_t count;
  70.171 +	void (*func)(unsigned long);
  70.172 +	unsigned long data;
  70.173 +};
  70.174 +
  70.175 +#define DECLARE_TASKLET(name, func, data) \
  70.176 +struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
  70.177 +
  70.178 +#define DECLARE_TASKLET_DISABLED(name, func, data) \
  70.179 +struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }
  70.180 +
  70.181 +
  70.182 +enum
  70.183 +{
  70.184 +	TASKLET_STATE_SCHED,	/* Tasklet is scheduled for execution */
  70.185 +	TASKLET_STATE_RUN	/* Tasklet is running (SMP only) */
  70.186 +};
  70.187 +
  70.188 +#ifdef CONFIG_SMP
  70.189 +static inline int tasklet_trylock(struct tasklet_struct *t)
  70.190 +{
  70.191 +	return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state);
  70.192 +}
  70.193 +
  70.194 +static inline void tasklet_unlock(struct tasklet_struct *t)
  70.195 +{
  70.196 +	smp_mb__before_clear_bit(); 
  70.197 +	clear_bit(TASKLET_STATE_RUN, &(t)->state);
  70.198 +}
  70.199 +
  70.200 +static inline void tasklet_unlock_wait(struct tasklet_struct *t)
  70.201 +{
  70.202 +	while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); }
  70.203 +}
  70.204 +#else
  70.205 +#define tasklet_trylock(t) 1
  70.206 +#define tasklet_unlock_wait(t) do { } while (0)
  70.207 +#define tasklet_unlock(t) do { } while (0)
  70.208 +#endif
  70.209 +
  70.210 +extern void FASTCALL(__tasklet_schedule(struct tasklet_struct *t));
  70.211 +
  70.212 +static inline void tasklet_schedule(struct tasklet_struct *t)
  70.213 +{
  70.214 +	if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
  70.215 +		__tasklet_schedule(t);
  70.216 +}
  70.217 +
  70.218 +extern void FASTCALL(__tasklet_hi_schedule(struct tasklet_struct *t));
  70.219 +
  70.220 +static inline void tasklet_hi_schedule(struct tasklet_struct *t)
  70.221 +{
  70.222 +	if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
  70.223 +		__tasklet_hi_schedule(t);
  70.224 +}
  70.225 +
  70.226 +
  70.227 +static inline void tasklet_disable_nosync(struct tasklet_struct *t)
  70.228 +{
  70.229 +	atomic_inc(&t->count);
  70.230 +	smp_mb__after_atomic_inc();
  70.231 +}
  70.232 +
  70.233 +static inline void tasklet_disable(struct tasklet_struct *t)
  70.234 +{
  70.235 +	tasklet_disable_nosync(t);
  70.236 +	tasklet_unlock_wait(t);
  70.237 +	smp_mb();
  70.238 +}
  70.239 +
  70.240 +static inline void tasklet_enable(struct tasklet_struct *t)
  70.241 +{
  70.242 +	smp_mb__before_atomic_dec();
  70.243 +	atomic_dec(&t->count);
  70.244 +}
  70.245 +
  70.246 +static inline void tasklet_hi_enable(struct tasklet_struct *t)
  70.247 +{
  70.248 +	smp_mb__before_atomic_dec();
  70.249 +	atomic_dec(&t->count);
  70.250 +}
  70.251 +
  70.252 +extern void tasklet_kill(struct tasklet_struct *t);
  70.253 +extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu);
  70.254 +extern void tasklet_init(struct tasklet_struct *t,
  70.255 +			 void (*func)(unsigned long), unsigned long data);
  70.256 +
  70.257 +/*
  70.258 + * Autoprobing for irqs:
  70.259 + *
  70.260 + * probe_irq_on() and probe_irq_off() provide robust primitives
  70.261 + * for accurate IRQ probing during kernel initialization.  They are
  70.262 + * reasonably simple to use, are not "fooled" by spurious interrupts,
  70.263 + * and, unlike other attempts at IRQ probing, they do not get hung on
  70.264 + * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards).
  70.265 + *
  70.266 + * For reasonably foolproof probing, use them as follows:
  70.267 + *
  70.268 + * 1. clear and/or mask the device's internal interrupt.
  70.269 + * 2. sti();
  70.270 + * 3. irqs = probe_irq_on();      // "take over" all unassigned idle IRQs
  70.271 + * 4. enable the device and cause it to trigger an interrupt.
  70.272 + * 5. wait for the device to interrupt, using non-intrusive polling or a delay.
  70.273 + * 6. irq = probe_irq_off(irqs);  // get IRQ number, 0=none, negative=multiple
  70.274 + * 7. service the device to clear its pending interrupt.
  70.275 + * 8. loop again if paranoia is required.
  70.276 + *
  70.277 + * probe_irq_on() returns a mask of allocated irq's.
  70.278 + *
  70.279 + * probe_irq_off() takes the mask as a parameter,
  70.280 + * and returns the irq number which occurred,
  70.281 + * or zero if none occurred, or a negative irq number
  70.282 + * if more than one irq occurred.
  70.283 + */
  70.284 +
  70.285 +#if defined(CONFIG_GENERIC_HARDIRQS) && !defined(CONFIG_GENERIC_IRQ_PROBE) 
  70.286 +static inline unsigned long probe_irq_on(void)
  70.287 +{
  70.288 +	return 0;
  70.289 +}
  70.290 +static inline int probe_irq_off(unsigned long val)
  70.291 +{
  70.292 +	return 0;
  70.293 +}
  70.294 +static inline unsigned int probe_irq_mask(unsigned long val)
  70.295 +{
  70.296 +	return 0;
  70.297 +}
  70.298 +#else
  70.299 +extern unsigned long probe_irq_on(void);	/* returns 0 on failure */
  70.300 +extern int probe_irq_off(unsigned long);	/* returns 0 or negative on failure */
  70.301 +extern unsigned int probe_irq_mask(unsigned long);	/* returns mask of ISA interrupts */
  70.302 +#endif
  70.303 +
  70.304 +#endif
    71.1 --- a/linux-2.6-xen-sparse/include/xen/public/privcmd.h	Tue Jun 13 09:00:32 2006 -0600
    71.2 +++ b/linux-2.6-xen-sparse/include/xen/public/privcmd.h	Tue Jun 13 12:12:24 2006 -0600
    71.3 @@ -33,20 +33,22 @@
    71.4  #ifndef __LINUX_PUBLIC_PRIVCMD_H__
    71.5  #define __LINUX_PUBLIC_PRIVCMD_H__
    71.6  
    71.7 +#include <linux/types.h>
    71.8 +
    71.9  #ifndef __user
   71.10  #define __user
   71.11  #endif
   71.12  
   71.13  typedef struct privcmd_hypercall
   71.14  {
   71.15 -	unsigned long op;
   71.16 -	unsigned long arg[5];
   71.17 +	__u64 op;
   71.18 +	__u64 arg[5];
   71.19  } privcmd_hypercall_t;
   71.20  
   71.21  typedef struct privcmd_mmap_entry {
   71.22 -	unsigned long va;
   71.23 -	unsigned long mfn;
   71.24 -	unsigned long npages;
   71.25 +	__u64 va;
   71.26 +	__u64 mfn;
   71.27 +	__u64 npages;
   71.28  } privcmd_mmap_entry_t; 
   71.29  
   71.30  typedef struct privcmd_mmap {
   71.31 @@ -58,8 +60,8 @@ typedef struct privcmd_mmap {
   71.32  typedef struct privcmd_mmapbatch {
   71.33  	int num;     /* number of pages to populate */
   71.34  	domid_t dom; /* target domain */
   71.35 -	unsigned long addr;  /* virtual address */
   71.36 -	unsigned long __user *arr; /* array of mfns - top nibble set on err */
   71.37 +	__u64 addr;  /* virtual address */
   71.38 +	xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
   71.39  } privcmd_mmapbatch_t; 
   71.40  
   71.41  /*
    72.1 --- a/linux-2.6-xen-sparse/include/xen/xenbus.h	Tue Jun 13 09:00:32 2006 -0600
    72.2 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h	Tue Jun 13 12:12:24 2006 -0600
    72.3 @@ -42,8 +42,6 @@
    72.4  #include <xen/interface/io/xenbus.h>
    72.5  #include <xen/interface/io/xs_wire.h>
    72.6  
    72.7 -#define XBT_NULL 0
    72.8 -
    72.9  /* Register callback to watch this node. */
   72.10  struct xenbus_watch
   72.11  {
   72.12 @@ -76,7 +74,6 @@ struct xenbus_device {
   72.13  	struct xenbus_watch otherend_watch;
   72.14  	struct device dev;
   72.15  	enum xenbus_state state;
   72.16 -	void *data;
   72.17  };
   72.18  
   72.19  static inline struct xenbus_device *to_xenbus_device(struct device *dev)
   72.20 @@ -116,35 +113,41 @@ int xenbus_register_frontend(struct xenb
   72.21  int xenbus_register_backend(struct xenbus_driver *drv);
   72.22  void xenbus_unregister_driver(struct xenbus_driver *drv);
   72.23  
   72.24 -typedef u32 xenbus_transaction_t;
   72.25 +struct xenbus_transaction
   72.26 +{
   72.27 +	u32 id;
   72.28 +};
   72.29  
   72.30 -char **xenbus_directory(xenbus_transaction_t t,
   72.31 +/* Nil transaction ID. */
   72.32 +#define XBT_NIL ((struct xenbus_transaction) { 0 })
   72.33 +
   72.34 +char **xenbus_directory(struct xenbus_transaction t,
   72.35  			const char *dir, const char *node, unsigned int *num);
   72.36 -void *xenbus_read(xenbus_transaction_t t,
   72.37 +void *xenbus_read(struct xenbus_transaction t,
   72.38  		  const char *dir, const char *node, unsigned int *len);
   72.39 -int xenbus_write(xenbus_transaction_t t,
   72.40 +int xenbus_write(struct xenbus_transaction t,
   72.41  		 const char *dir, const char *node, const char *string);
   72.42 -int xenbus_mkdir(xenbus_transaction_t t,
   72.43 +int xenbus_mkdir(struct xenbus_transaction t,
   72.44  		 const char *dir, const char *node);
   72.45 -int xenbus_exists(xenbus_transaction_t t,
   72.46 +int xenbus_exists(struct xenbus_transaction t,
   72.47  		  const char *dir, const char *node);
   72.48 -int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node);
   72.49 -int xenbus_transaction_start(xenbus_transaction_t *t);
   72.50 -int xenbus_transaction_end(xenbus_transaction_t t, int abort);
   72.51 +int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
   72.52 +int xenbus_transaction_start(struct xenbus_transaction *t);
   72.53 +int xenbus_transaction_end(struct xenbus_transaction t, int abort);
   72.54  
   72.55  /* Single read and scanf: returns -errno or num scanned if > 0. */
   72.56 -int xenbus_scanf(xenbus_transaction_t t,
   72.57 +int xenbus_scanf(struct xenbus_transaction t,
   72.58  		 const char *dir, const char *node, const char *fmt, ...)
   72.59  	__attribute__((format(scanf, 4, 5)));
   72.60  
   72.61  /* Single printf and write: returns -errno or 0. */
   72.62 -int xenbus_printf(xenbus_transaction_t t,
   72.63 +int xenbus_printf(struct xenbus_transaction t,
   72.64  		  const char *dir, const char *node, const char *fmt, ...)
   72.65  	__attribute__((format(printf, 4, 5)));
   72.66  
   72.67  /* Generic read function: NULL-terminated triples of name,
   72.68   * sprintf-style type string, and pointer. Returns 0 or errno.*/
   72.69 -int xenbus_gather(xenbus_transaction_t t, const char *dir, ...);
   72.70 +int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
   72.71  
   72.72  /* notifer routines for when the xenstore comes up */
   72.73  int register_xenstore_notifier(struct notifier_block *nb);
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/linux-2.6-xen-sparse/kernel/irq/spurious.c	Tue Jun 13 12:12:24 2006 -0600
    73.3 @@ -0,0 +1,206 @@
    73.4 +/*
    73.5 + * linux/kernel/irq/spurious.c
    73.6 + *
    73.7 + * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
    73.8 + *
    73.9 + * This file contains spurious interrupt handling.
   73.10 + */
   73.11 +
   73.12 +#include <linux/irq.h>
   73.13 +#include <linux/module.h>
   73.14 +#include <linux/kallsyms.h>
   73.15 +#include <linux/interrupt.h>
   73.16 +
   73.17 +static int irqfixup;
   73.18 +
   73.19 +/*
   73.20 + * Recovery handler for misrouted interrupts.
   73.21 + */
   73.22 +
   73.23 +static int misrouted_irq(int irq, struct pt_regs *regs)
   73.24 +{
   73.25 +	int i;
   73.26 +	irq_desc_t *desc;
   73.27 +	int ok = 0;
   73.28 +	int work = 0;	/* Did we do work for a real IRQ */
   73.29 +
   73.30 +	for(i = 1; i < NR_IRQS; i++) {
   73.31 +		struct irqaction *action;
   73.32 +
   73.33 +		if (i == irq)	/* Already tried */
   73.34 +			continue;
   73.35 +		desc = &irq_desc[i];
   73.36 +		spin_lock(&desc->lock);
   73.37 +		action = desc->action;
   73.38 +		/* Already running on another processor */
   73.39 +		if (desc->status & IRQ_INPROGRESS) {
   73.40 +			/*
   73.41 +			 * Already running: If it is shared get the other
   73.42 +			 * CPU to go looking for our mystery interrupt too
   73.43 +			 */
   73.44 +			if (desc->action && (desc->action->flags & SA_SHIRQ))
   73.45 +				desc->status |= IRQ_PENDING;
   73.46 +			spin_unlock(&desc->lock);
   73.47 +			continue;
   73.48 +		}
   73.49 +		/* Honour the normal IRQ locking */
   73.50 +		desc->status |= IRQ_INPROGRESS;
   73.51 +		spin_unlock(&desc->lock);
   73.52 +		while (action) {
   73.53 +			/* Only shared IRQ handlers are safe to call */
   73.54 +			if (action->flags & SA_SHIRQ) {
   73.55 +				if (action->handler(i, action->dev_id, regs) ==
   73.56 +						IRQ_HANDLED)
   73.57 +					ok = 1;
   73.58 +			}
   73.59 +			action = action->next;
   73.60 +		}
   73.61 +		local_irq_disable();
   73.62 +		/* Now clean up the flags */
   73.63 +		spin_lock(&desc->lock);
   73.64 +		action = desc->action;
   73.65 +
   73.66 +		/*
   73.67 +		 * While we were looking for a fixup someone queued a real
   73.68 +		 * IRQ clashing with our walk
   73.69 +		 */
   73.70 +
   73.71 +		while ((desc->status & IRQ_PENDING) && action) {
   73.72 +			/*
   73.73 +			 * Perform real IRQ processing for the IRQ we deferred
   73.74 +			 */
   73.75 +			work = 1;
   73.76 +			spin_unlock(&desc->lock);
   73.77 +			handle_IRQ_event(i, regs, action);
   73.78 +			spin_lock(&desc->lock);
   73.79 +			desc->status &= ~IRQ_PENDING;
   73.80 +		}
   73.81 +		desc->status &= ~IRQ_INPROGRESS;
   73.82 +		/*
   73.83 +		 * If we did actual work for the real IRQ line we must let the
   73.84 +		 * IRQ controller clean up too
   73.85 +		 */
   73.86 +		if(work)
   73.87 +			desc->handler->end(i);
   73.88 +		spin_unlock(&desc->lock);
   73.89 +	}
   73.90 +	/* So the caller can adjust the irq error counts */
   73.91 +	return ok;
   73.92 +}
   73.93 +
   73.94 +/*
   73.95 + * If 99,900 of the previous 100,000 interrupts have not been handled
   73.96 + * then assume that the IRQ is stuck in some manner. Drop a diagnostic
   73.97 + * and try to turn the IRQ off.
   73.98 + *
   73.99 + * (The other 100-of-100,000 interrupts may have been a correctly
  73.100 + *  functioning device sharing an IRQ with the failing one)
  73.101 + *
  73.102 + * Called under desc->lock
  73.103 + */
  73.104 +
  73.105 +static void
  73.106 +__report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
  73.107 +{
  73.108 +	struct irqaction *action;
  73.109 +
  73.110 +	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
  73.111 +		printk(KERN_ERR "irq event %d: bogus return value %x\n",
  73.112 +				irq, action_ret);
  73.113 +	} else {
  73.114 +		printk(KERN_ERR "irq %d: nobody cared (try booting with "
  73.115 +				"the \"irqpoll\" option)\n", irq);
  73.116 +	}
  73.117 +	dump_stack();
  73.118 +	printk(KERN_ERR "handlers:\n");
  73.119 +	action = desc->action;
  73.120 +	while (action) {
  73.121 +		printk(KERN_ERR "[<%p>]", action->handler);
  73.122 +		print_symbol(" (%s)",
  73.123 +			(unsigned long)action->handler);
  73.124 +		printk("\n");
  73.125 +		action = action->next;
  73.126 +	}
  73.127 +}
  73.128 +
  73.129 +static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
  73.130 +{
  73.131 +	static int count = 100;
  73.132 +
  73.133 +	if (count > 0) {
  73.134 +		count--;
  73.135 +		__report_bad_irq(irq, desc, action_ret);
  73.136 +	}
  73.137 +}
  73.138 +
  73.139 +void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
  73.140 +			struct pt_regs *regs)
  73.141 +{
  73.142 +	if (action_ret != IRQ_HANDLED) {
  73.143 +		if (!irq_ignore_unhandled(irq))
  73.144 +			desc->irqs_unhandled++;
  73.145 +		if (action_ret != IRQ_NONE)
  73.146 +			report_bad_irq(irq, desc, action_ret);
  73.147 +	}
  73.148 +
  73.149 +	if (unlikely(irqfixup)) {
  73.150 +		/* Don't punish working computers */
  73.151 +		if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
  73.152 +			int ok = misrouted_irq(irq, regs);
  73.153 +			if (action_ret == IRQ_NONE)
  73.154 +				desc->irqs_unhandled -= ok;
  73.155 +		}
  73.156 +	}
  73.157 +
  73.158 +	desc->irq_count++;
  73.159 +	if (desc->irq_count < 100000)
  73.160 +		return;
  73.161 +
  73.162 +	desc->irq_count = 0;
  73.163 +	if (desc->irqs_unhandled > 99900) {
  73.164 +		/*
  73.165 +		 * The interrupt is stuck
  73.166 +		 */
  73.167 +		__report_bad_irq(irq, desc, action_ret);
  73.168 +		/*
  73.169 +		 * Now kill the IRQ
  73.170 +		 */
  73.171 +		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
  73.172 +		desc->status |= IRQ_DISABLED;
  73.173 +		desc->handler->disable(irq);
  73.174 +	}
  73.175 +	desc->irqs_unhandled = 0;
  73.176 +}
  73.177 +
  73.178 +int noirqdebug;
  73.179 +
  73.180 +int __init noirqdebug_setup(char *str)
  73.181 +{
  73.182 +	noirqdebug = 1;
  73.183 +	printk(KERN_INFO "IRQ lockup detection disabled\n");
  73.184 +	return 1;
  73.185 +}
  73.186 +
  73.187 +__setup("noirqdebug", noirqdebug_setup);
  73.188 +
  73.189 +static int __init irqfixup_setup(char *str)
  73.190 +{
  73.191 +	irqfixup = 1;
  73.192 +	printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
  73.193 +	printk(KERN_WARNING "This may impact system performance.\n");
  73.194 +	return 1;
  73.195 +}
  73.196 +
  73.197 +__setup("irqfixup", irqfixup_setup);
  73.198 +
  73.199 +static int __init irqpoll_setup(char *str)
  73.200 +{
  73.201 +	irqfixup = 2;
  73.202 +	printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
  73.203 +				"enabled\n");
  73.204 +	printk(KERN_WARNING "This may significantly impact system "
  73.205 +				"performance\n");
  73.206 +	return 1;
  73.207 +}
  73.208 +
  73.209 +__setup("irqpoll", irqpoll_setup);
    74.1 --- a/linux-2.6-xen-sparse/mm/memory.c	Tue Jun 13 09:00:32 2006 -0600
    74.2 +++ b/linux-2.6-xen-sparse/mm/memory.c	Tue Jun 13 12:12:24 2006 -0600
    74.3 @@ -968,7 +968,6 @@ int get_user_pages(struct task_struct *t
    74.4  {
    74.5  	int i;
    74.6  	unsigned int vm_flags;
    74.7 -	int xenpage = 0;
    74.8  
    74.9  	/* 
   74.10  	 * Require read or write permissions.
   74.11 @@ -1026,7 +1025,6 @@ int get_user_pages(struct task_struct *t
   74.12  		if (vma && (vma->vm_flags & VM_FOREIGN)) {
   74.13  			struct page **map = vma->vm_private_data;
   74.14  			int offset = (start - vma->vm_start) >> PAGE_SHIFT;
   74.15 -			xenpage =1;
   74.16  			if (map[offset] != NULL) {
   74.17  			        if (pages) {
   74.18  			                struct page *page = map[offset];
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/patches/linux-2.6.16.13/rcu_needs_cpu.patch	Tue Jun 13 12:12:24 2006 -0600
    75.3 @@ -0,0 +1,33 @@
    75.4 +--- ../pristine-linux-2.6.16.13/kernel/rcupdate.c	2006-05-02 22:38:44.000000000 +0100
    75.5 ++++ ./kernel/rcupdate.c	2006-06-09 20:27:45.000000000 +0100
    75.6 +@@ -485,6 +485,20 @@ int rcu_pending(int cpu)
    75.7 + 		__rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
    75.8 + }
    75.9 + 
   75.10 ++/*
   75.11 ++ * Check to see if any future RCU-related work will need to be done
   75.12 ++ * by the current CPU, even if none need be done immediately, returning
   75.13 ++ * 1 if so.  This function is part of the RCU implementation; it is -not-
   75.14 ++ * an exported member of the RCU API.
   75.15 ++ */
   75.16 ++int rcu_needs_cpu(int cpu)
   75.17 ++{
   75.18 ++	struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
   75.19 ++	struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu);
   75.20 ++
   75.21 ++	return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu));
   75.22 ++}
   75.23 ++
   75.24 + void rcu_check_callbacks(int cpu, int user)
   75.25 + {
   75.26 + 	if (user || 
   75.27 +--- ../pristine-linux-2.6.16.13/include/linux/rcupdate.h	2006-05-02 22:38:44.000000000 +0100
   75.28 ++++ ./include/linux/rcupdate.h	2006-06-09 20:28:57.000000000 +0100
   75.29 +@@ -134,6 +134,7 @@ static inline void rcu_bh_qsctr_inc(int 
   75.30 + }
   75.31 + 
   75.32 + extern int rcu_pending(int cpu);
   75.33 ++extern int rcu_needs_cpu(int cpu);
   75.34 + 
   75.35 + /**
   75.36 +  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
    76.1 --- a/tools/debugger/libxendebug/xendebug.c	Tue Jun 13 09:00:32 2006 -0600
    76.2 +++ b/tools/debugger/libxendebug/xendebug.c	Tue Jun 13 12:12:24 2006 -0600
    76.3 @@ -57,7 +57,7 @@ typedef struct domain_context           
    76.4      vcpu_guest_context_t context[MAX_VIRT_CPUS];
    76.5  
    76.6      long            total_pages;
    76.7 -    unsigned long  *page_array;
    76.8 +    xen_pfn_t      *page_array;
    76.9  
   76.10      unsigned long   cr3_phys[MAX_VIRT_CPUS];
   76.11      unsigned long  *cr3_virt[MAX_VIRT_CPUS];
   76.12 @@ -346,8 +346,9 @@ xendebug_memory_page (domain_context_p c
   76.13          ctxt->cr3_phys[vcpu] = vcpu_ctxt->ctrlreg[3];
   76.14          if ( ctxt->cr3_virt[vcpu] )
   76.15              munmap(ctxt->cr3_virt[vcpu], PAGE_SIZE);
   76.16 -        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid,
   76.17 -                    PAGE_SIZE, PROT_READ, ctxt->cr3_phys[vcpu] >> PAGE_SHIFT);
   76.18 +        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(
   76.19 +            xc_handle, ctxt->domid, PAGE_SIZE, PROT_READ,
   76.20 +            xen_cr3_to_pfn(ctxt->cr3_phys[vcpu]));
   76.21          if ( ctxt->cr3_virt[vcpu] == NULL )
   76.22              return 0;
   76.23      } 
    77.1 --- a/tools/examples/network-bridge	Tue Jun 13 09:00:32 2006 -0600
    77.2 +++ b/tools/examples/network-bridge	Tue Jun 13 12:12:24 2006 -0600
    77.3 @@ -60,6 +60,7 @@ findCommand "$@"
    77.4  evalVariables "$@"
    77.5  
    77.6  vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 's/^[^0-9]*//')}
    77.7 +vifnum=${vifnum:-0}
    77.8  bridge=${bridge:-xenbr${vifnum}}
    77.9  netdev=${netdev:-eth${vifnum}}
   77.10  antispoof=${antispoof:-no}
    78.1 --- a/tools/firmware/hvmloader/Makefile	Tue Jun 13 09:00:32 2006 -0600
    78.2 +++ b/tools/firmware/hvmloader/Makefile	Tue Jun 13 12:12:24 2006 -0600
    78.3 @@ -51,8 +51,8 @@ hvmloader: roms.h hvmloader.c acpi_madt.
    78.4  	$(OBJCOPY) hvmloader.tmp hvmloader
    78.5  	rm -f hvmloader.tmp
    78.6  
    78.7 -roms.h:	../rombios/BIOS-bochs-8-processors ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
    78.8 -	sh ./mkhex rombios ../rombios/BIOS-bochs-8-processors > roms.h
    78.9 +roms.h:	../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin
   78.10 +	sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
   78.11  	sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
   78.12  	sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h
   78.13  	sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
    79.1 --- a/tools/firmware/rombios/Makefile	Tue Jun 13 09:00:32 2006 -0600
    79.2 +++ b/tools/firmware/rombios/Makefile	Tue Jun 13 12:12:24 2006 -0600
    79.3 @@ -1,7 +1,7 @@
    79.4 -#BIOS_BUILDS = BIOS-bochs-latest
    79.5 +BIOS_BUILDS = BIOS-bochs-latest
    79.6  #BIOS_BUILDS += BIOS-bochs-2-processors
    79.7  #BIOS_BUILDS += BIOS-bochs-4-processors
    79.8 -BIOS_BUILDS += BIOS-bochs-8-processors
    79.9 +#BIOS_BUILDS += BIOS-bochs-8-processors
   79.10  
   79.11  .PHONY: all
   79.12  all: bios
    80.1 --- a/tools/firmware/vgabios/clext.c	Tue Jun 13 09:00:32 2006 -0600
    80.2 +++ b/tools/firmware/vgabios/clext.c	Tue Jun 13 12:12:24 2006 -0600
    80.3 @@ -525,6 +525,13 @@ cirrus_debug_dump:
    80.4  cirrus_set_video_mode_extended:
    80.5    call cirrus_switch_mode
    80.6    pop ax ;; mode
    80.7 +  test al, #0x80
    80.8 +  jnz cirrus_set_video_mode_extended_1
    80.9 +  push ax
   80.10 +  mov ax, #0xffff ; set to 0xff to keep win 2K happy
   80.11 +  call cirrus_clear_vram
   80.12 +  pop ax
   80.13 +cirrus_set_video_mode_extended_1:
   80.14    and al, #0x7f
   80.15  
   80.16    push ds
   80.17 @@ -992,6 +999,13 @@ cirrus_vesa_02h_1:
   80.18    jnz cirrus_vesa_02h_3
   80.19    call cirrus_enable_16k_granularity
   80.20  cirrus_vesa_02h_3:
   80.21 +  test bx, #0x8000 ;; no clear
   80.22 +  jnz cirrus_vesa_02h_4
   80.23 +  push ax
   80.24 +  xor ax,ax
   80.25 +  call cirrus_clear_vram
   80.26 +  pop ax
   80.27 +cirrus_vesa_02h_4:
   80.28    pop ax
   80.29    push ds
   80.30  #ifdef CIRRUS_VESA3_PMINFO
   80.31 @@ -1460,6 +1474,38 @@ cirrus_get_start_addr:
   80.32    pop  bx
   80.33    ret
   80.34  
   80.35 +cirrus_clear_vram:
   80.36 +  pusha
   80.37 +  push es
   80.38 +  mov si, ax
   80.39 +
   80.40 +  call cirrus_enable_16k_granularity
   80.41 +  call cirrus_extbios_85h
   80.42 +  shl al, #2
   80.43 +  mov bl, al
   80.44 +  xor ah,ah
   80.45 +cirrus_clear_vram_1:
   80.46 +  mov al, #0x09
   80.47 +  mov dx, #0x3ce
   80.48 +  out dx, ax
   80.49 +  push ax
   80.50 +  mov cx, #0xa000
   80.51 +  mov es, cx
   80.52 +  xor di, di
   80.53 +  mov ax, si
   80.54 +  mov cx, #8192
   80.55 +  cld
   80.56 +  rep
   80.57 +      stosw
   80.58 +  pop ax
   80.59 +  inc ah
   80.60 +  cmp ah, bl
   80.61 +  jne cirrus_clear_vram_1
   80.62 +
   80.63 +  pop es
   80.64 +  popa
   80.65 +  ret
   80.66 +
   80.67  cirrus_extbios_handlers:
   80.68    ;; 80h
   80.69    dw cirrus_extbios_80h
    81.1 --- a/tools/firmware/vmxassist/vm86.c	Tue Jun 13 09:00:32 2006 -0600
    81.2 +++ b/tools/firmware/vmxassist/vm86.c	Tue Jun 13 12:12:24 2006 -0600
    81.3 @@ -37,6 +37,8 @@
    81.4  static unsigned prev_eip = 0;
    81.5  enum vm86_mode mode = 0;
    81.6  
    81.7 +static struct regs saved_rm_regs;
    81.8 +
    81.9  #ifdef DEBUG
   81.10  int traceset = 0;
   81.11  
   81.12 @@ -795,6 +797,8 @@ protected_mode(struct regs *regs)
   81.13  	oldctx.esp = regs->uesp;
   81.14  	oldctx.eflags = regs->eflags;
   81.15  
   81.16 +	memset(&saved_rm_regs, 0, sizeof(struct regs));
   81.17 +
   81.18  	/* reload all segment registers */
   81.19  	if (!load_seg(regs->cs, &oldctx.cs_base,
   81.20  				&oldctx.cs_limit, &oldctx.cs_arbytes))
   81.21 @@ -808,6 +812,7 @@ protected_mode(struct regs *regs)
   81.22  		load_seg(0, &oldctx.es_base,
   81.23  			    &oldctx.es_limit, &oldctx.es_arbytes);
   81.24  		oldctx.es_sel = 0;
   81.25 +		saved_rm_regs.ves = regs->ves;
   81.26  	}
   81.27  
   81.28  	if (load_seg(regs->uss, &oldctx.ss_base,
   81.29 @@ -817,6 +822,7 @@ protected_mode(struct regs *regs)
   81.30  		load_seg(0, &oldctx.ss_base,
   81.31  			    &oldctx.ss_limit, &oldctx.ss_arbytes);
   81.32  		oldctx.ss_sel = 0;
   81.33 +		saved_rm_regs.uss = regs->uss;
   81.34  	}
   81.35  
   81.36  	if (load_seg(regs->vds, &oldctx.ds_base,
   81.37 @@ -826,6 +832,7 @@ protected_mode(struct regs *regs)
   81.38  		load_seg(0, &oldctx.ds_base,
   81.39  			    &oldctx.ds_limit, &oldctx.ds_arbytes);
   81.40  		oldctx.ds_sel = 0;
   81.41 +		saved_rm_regs.vds = regs->vds;
   81.42  	}
   81.43  
   81.44  	if (load_seg(regs->vfs, &oldctx.fs_base,
   81.45 @@ -835,6 +842,7 @@ protected_mode(struct regs *regs)
   81.46  		load_seg(0, &oldctx.fs_base,
   81.47  			    &oldctx.fs_limit, &oldctx.fs_arbytes);
   81.48  		oldctx.fs_sel = 0;
   81.49 +		saved_rm_regs.vfs = regs->vfs;
   81.50  	}
   81.51  
   81.52  	if (load_seg(regs->vgs, &oldctx.gs_base,
   81.53 @@ -844,6 +852,7 @@ protected_mode(struct regs *regs)
   81.54  		load_seg(0, &oldctx.gs_base,
   81.55  			    &oldctx.gs_limit, &oldctx.gs_arbytes);
   81.56  		oldctx.gs_sel = 0;
   81.57 +		saved_rm_regs.vgs = regs->vgs;
   81.58  	}
   81.59  
   81.60  	/* initialize jump environment to warp back to protected mode */
   81.61 @@ -880,16 +889,22 @@ real_mode(struct regs *regs)
   81.62  		if (regs->uss >= HIGHMEM)
   81.63  			panic("%%ss 0x%lx higher than 1MB", regs->uss);
   81.64  		regs->uss = address(regs, regs->uss, 0) >> 4;
   81.65 +	} else {
   81.66 +	  regs->uss = saved_rm_regs.uss;
   81.67  	}
   81.68  	if (regs->vds != 0) {
   81.69  		if (regs->vds >= HIGHMEM)
   81.70  			panic("%%ds 0x%lx higher than 1MB", regs->vds);
   81.71  		regs->vds = address(regs, regs->vds, 0) >> 4;
   81.72 +	} else {
   81.73 +	  regs->vds = saved_rm_regs.vds;
   81.74  	}
   81.75  	if (regs->ves != 0) {
   81.76  		if (regs->ves >= HIGHMEM)
   81.77  			panic("%%es 0x%lx higher than 1MB", regs->ves);
   81.78  		regs->ves = address(regs, regs->ves, 0) >> 4;
   81.79 +	} else {
   81.80 +	  regs->ves = saved_rm_regs.ves;
   81.81  	}
   81.82  
   81.83  	/* this should get us into 16-bit mode */
   81.84 @@ -982,6 +997,39 @@ jmpl(struct regs *regs, int prefix)
   81.85  }
   81.86  
   81.87  static void
   81.88 +jmpl_indirect(struct regs *regs, int prefix, unsigned modrm)
   81.89 +{
   81.90 +	unsigned n = regs->eip;
   81.91 +	unsigned cs, eip;
   81.92 +	unsigned addr;
   81.93 +
   81.94 +	addr  = operand(prefix, regs, modrm);
   81.95 +
   81.96 +	if (mode == VM86_REAL_TO_PROTECTED) { /* jump to protected mode */
   81.97 +		eip = (prefix & DATA32) ? read32(addr) : read16(addr);
   81.98 +		addr += (prefix & DATA32) ? 4 : 2;
   81.99 +		cs = read16(addr);
  81.100 +
  81.101 +		TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
  81.102 +
  81.103 +                regs->cs = cs;
  81.104 +                regs->eip = eip;
  81.105 +		set_mode(regs, VM86_PROTECTED);
  81.106 +	} else if (mode == VM86_PROTECTED_TO_REAL) { /* jump to real mode */
  81.107 +		eip = (prefix & DATA32) ? read32(addr) : read16(addr);
  81.108 +		addr += (prefix & DATA32) ? 4 : 2;
  81.109 +		cs = read16(addr);
  81.110 +
  81.111 +		TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
  81.112 +
  81.113 +                regs->cs = cs;
  81.114 +                regs->eip = eip;
  81.115 +		set_mode(regs, VM86_REAL);
  81.116 +	} else
  81.117 +		panic("jmpl");
  81.118 +}
  81.119 +
  81.120 +static void
  81.121  retl(struct regs *regs, int prefix)
  81.122  {
  81.123  	unsigned cs, eip;
  81.124 @@ -1306,6 +1354,23 @@ opcode(struct regs *regs)
  81.125  			}
  81.126  			goto invalid;
  81.127  
  81.128 +		case 0xFF: /* jmpl (indirect) */
  81.129 +			if ((mode == VM86_REAL_TO_PROTECTED) ||
  81.130 +			    (mode == VM86_PROTECTED_TO_REAL)) {
  81.131 +			 	unsigned modrm = fetch8(regs);
  81.132 +				
  81.133 +				switch((modrm >> 3) & 7) {
  81.134 +				case 5:
  81.135 +				  jmpl_indirect(regs, prefix, modrm);
  81.136 +				  return OPC_INVALID;
  81.137 +
  81.138 +				default:
  81.139 +				  break;
  81.140 +				}
  81.141 +
  81.142 +			}
  81.143 +			goto invalid;
  81.144 +
  81.145  		case 0xEB: /* short jump */
  81.146  			if ((mode == VM86_REAL_TO_PROTECTED) ||
  81.147  			    (mode == VM86_PROTECTED_TO_REAL)) {
    82.1 --- a/tools/ioemu/hw/cirrus_vga.c	Tue Jun 13 09:00:32 2006 -0600
    82.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Tue Jun 13 12:12:24 2006 -0600
    82.3 @@ -1191,17 +1191,6 @@ cirrus_hook_write_sr(CirrusVGAState * s,
    82.4  	s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
    82.5  	break;
    82.6      case 0x07:			// Extended Sequencer Mode
    82.7 -	/* Win2K seems to assume that the VRAM is set to 0xff
    82.8 -	 *   whenever VGA/SVGA mode changes 
    82.9 -	 */
   82.10 -	if ((s->sr[0x07] ^ reg_value) & CIRRUS_SR7_BPP_SVGA)
   82.11 -	    memset(s->vram_ptr, 0xff, s->real_vram_size);
   82.12 -	s->sr[0x07] = reg_value;
   82.13 -#ifdef DEBUG_CIRRUS 
   82.14 -	printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
   82.15 -	       reg_index, reg_value);
   82.16 -#endif
   82.17 -	break;
   82.18      case 0x08:			// EEPROM Control
   82.19      case 0x09:			// Scratch Register 0
   82.20      case 0x0a:			// Scratch Register 1
   82.21 @@ -2460,10 +2449,9 @@ static CPUWriteMemoryFunc *cirrus_linear
   82.22  };
   82.23  
   82.24  extern FILE *logfile;
   82.25 -#if defined(__i386__) || defined (__x86_64__)
   82.26  static void * set_vram_mapping(unsigned long begin, unsigned long end)
   82.27  {
   82.28 -    unsigned long * extent_start = NULL;
   82.29 +    xen_pfn_t *extent_start = NULL;
   82.30      unsigned long nr_extents;
   82.31      void *vram_pointer = NULL;
   82.32      int i;
   82.33 @@ -2474,14 +2462,14 @@ static void * set_vram_mapping(unsigned 
   82.34      end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
   82.35      nr_extents = (end - begin) >> TARGET_PAGE_BITS;
   82.36  
   82.37 -    extent_start = malloc(sizeof(unsigned long) * nr_extents );
   82.38 +    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents );
   82.39      if (extent_start == NULL)
   82.40      {
   82.41          fprintf(stderr, "Failed malloc on set_vram_mapping\n");
   82.42          return NULL;
   82.43      }
   82.44  
   82.45 -    memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
   82.46 +    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
   82.47  
   82.48      for (i = 0; i < nr_extents; i++)
   82.49      {
   82.50 @@ -2509,7 +2497,7 @@ static void * set_vram_mapping(unsigned 
   82.51  
   82.52  static int unset_vram_mapping(unsigned long begin, unsigned long end)
   82.53  {
   82.54 -    unsigned long * extent_start = NULL;
   82.55 +    xen_pfn_t *extent_start = NULL;
   82.56      unsigned long nr_extents;
   82.57      int i;
   82.58  
   82.59 @@ -2520,7 +2508,7 @@ static int unset_vram_mapping(unsigned l
   82.60      end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
   82.61      nr_extents = (end - begin) >> TARGET_PAGE_BITS;
   82.62  
   82.63 -    extent_start = malloc(sizeof(unsigned long) * nr_extents );
   82.64 +    extent_start = malloc(sizeof(xen_pfn_t) * nr_extents );
   82.65  
   82.66      if (extent_start == NULL)
   82.67      {
   82.68 @@ -2528,7 +2516,7 @@ static int unset_vram_mapping(unsigned l
   82.69          return -1;
   82.70      }
   82.71  
   82.72 -    memset(extent_start, 0, sizeof(unsigned long) * nr_extents);
   82.73 +    memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
   82.74  
   82.75      for (i = 0; i < nr_extents; i++)
   82.76          extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
   82.77 @@ -2540,10 +2528,6 @@ static int unset_vram_mapping(unsigned l
   82.78      return 0;
   82.79  }
   82.80  
   82.81 -#elif defined(__ia64__)
   82.82 -static void * set_vram_mapping(unsigned long addr, unsigned long end) {}
   82.83 -static int unset_vram_mapping(unsigned long addr, unsigned long end) {}
   82.84 -#endif
   82.85  extern int vga_accelerate;
   82.86  
   82.87  /* Compute the memory access functions */
    83.1 --- a/tools/ioemu/hw/pc.c	Tue Jun 13 09:00:32 2006 -0600
    83.2 +++ b/tools/ioemu/hw/pc.c	Tue Jun 13 12:12:24 2006 -0600
    83.3 @@ -40,6 +40,7 @@ int speaker_data_on;
    83.4  int dummy_refresh_clock;
    83.5  static fdctrl_t *floppy_controller;
    83.6  static RTCState *rtc_state;
    83.7 +static USBPort *usb_root_ports[2];
    83.8  
    83.9  static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
   83.10  {
   83.11 @@ -537,8 +538,11 @@ void pc_init(uint64_t ram_size, int vga_
   83.12      for(i = 0; i < MAX_SERIAL_PORTS; i++) {
   83.13          if (serial_hds[i]) {
   83.14              sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
   83.15 -            if (i == SUMMA_PORT)
   83.16 +            if (i == serial_summa_port) {
   83.17  		summa_init(sp, serial_hds[i]);
   83.18 +		fprintf(stderr, "Serial port %d (COM%d) initialized for Summagraphics\n",
   83.19 +			i, i+1);
   83.20 +	    }
   83.21          }
   83.22      }
   83.23  
   83.24 @@ -581,6 +585,11 @@ void pc_init(uint64_t ram_size, int vga_
   83.25      cmos_init(ram_size, boot_device, bs_table, timeoffset);
   83.26      acpi_init(0x8000);
   83.27  
   83.28 +    if (pci_enabled && usb_enabled) {
   83.29 +	usb_uhci_init(pci_bus, usb_root_ports);
   83.30 +	usb_attach(usb_root_ports[0], vm_usb_hub);
   83.31 +    }
   83.32 +
   83.33      /* must be done after all PCI devices are instanciated */
   83.34      /* XXX: should be done in the Bochs BIOS */
   83.35      if (pci_enabled) {
    84.1 --- a/tools/ioemu/hw/pckbd.c	Tue Jun 13 09:00:32 2006 -0600
    84.2 +++ b/tools/ioemu/hw/pckbd.c	Tue Jun 13 12:12:24 2006 -0600
    84.3 @@ -118,6 +118,9 @@
    84.4  #define SUMMA_MAXX	(16000 - 1)
    84.5  #define SUMMA_MAXY	(16000 - 1)
    84.6  
    84.7 +#define MAX_ABSX	0x7fff
    84.8 +#define MAX_ABSY	0x7fff
    84.9 +
   84.10  typedef struct {
   84.11      uint8_t aux[KBD_QUEUE_SIZE];
   84.12      uint8_t data[KBD_QUEUE_SIZE];
   84.13 @@ -149,8 +152,6 @@ typedef struct KBDState {
   84.14      uint8_t mouse_wrap;
   84.15      uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
   84.16      uint8_t mouse_detect_state;
   84.17 -    int mouse_x;  /* absolute coordinates (for mousepad) */
   84.18 -    int mouse_y;
   84.19      int mouse_dx; /* current values, needed for 'poll' mode */
   84.20      int mouse_dy;
   84.21      int mouse_dz;
   84.22 @@ -422,7 +423,7 @@ static void kbd_write_keyboard(KBDState 
   84.23  
   84.24  int mouse_maxx, mouse_maxy;
   84.25  
   84.26 -static int kbd_mouse_send_packet(KBDState *s)
   84.27 +static void kbd_mouse_send_packet(KBDState *s)
   84.28  {
   84.29      unsigned int b;
   84.30      int dx1, dy1, dz1;
   84.31 @@ -430,100 +431,63 @@ static int kbd_mouse_send_packet(KBDStat
   84.32      dx1 = s->mouse_dx;
   84.33      dy1 = s->mouse_dy;
   84.34      dz1 = s->mouse_dz;
   84.35 +    /* XXX: increase range to 8 bits ? */
   84.36 +    if (dx1 > 127)
   84.37 +        dx1 = 127;
   84.38 +    else if (dx1 < -127)
   84.39 +        dx1 = -127;
   84.40 +    if (dy1 > 127)
   84.41 +        dy1 = 127;
   84.42 +    else if (dy1 < -127)
   84.43 +        dy1 = -127;
   84.44 +    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
   84.45 +    kbd_queue(s, b, 1);
   84.46 +    kbd_queue(s, dx1 & 0xff, 1);
   84.47 +    kbd_queue(s, dy1 & 0xff, 1);
   84.48 +    /* extra byte for IMPS/2 or IMEX */
   84.49      switch(s->mouse_type) {
   84.50 -  
   84.51 -    case TABLET:        /* Summagraphics pen tablet */
   84.52 -	if (SummaState.report_mode == MODE_STREAM) {
   84.53 -	    dx1 = s->mouse_x;
   84.54 -	    dy1 = s->mouse_y;
   84.55 -	    if (SummaState.origin == ORIGIN_LOWER_LEFT)
   84.56 -		dy1 = mouse_maxy - dy1;
   84.57 -	    dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
   84.58 -	    dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
   84.59 -	    ser_queue(s->serial, 0x80 | (s->mouse_buttons & 7));
   84.60 -	    ser_queue(s->serial, dx1 & 0x7f);
   84.61 -	    ser_queue(s->serial, dx1 >> 7);
   84.62 -	    ser_queue(s->serial, dy1 & 0x7f);
   84.63 -	    ser_queue(s->serial, dy1 >> 7);
   84.64 -	}
   84.65 -	s->mouse_dx = 0; 
   84.66 -	s->mouse_dy = 0;
   84.67 -	s->mouse_dz = 0;
   84.68 -	return 0;
   84.69 +    default:
   84.70 +        break;
   84.71 +    case IMPS2:
   84.72 +        if (dz1 > 127)
   84.73 +            dz1 = 127;
   84.74 +        else if (dz1 < -127)
   84.75 +                dz1 = -127;
   84.76 +        kbd_queue(s, dz1 & 0xff, 1);
   84.77 +        break;
   84.78 +    case IMEX:
   84.79 +        if (dz1 > 7)
   84.80 +            dz1 = 7;
   84.81 +        else if (dz1 < -7)
   84.82 +            dz1 = -7;
   84.83 +        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
   84.84 +        kbd_queue(s, b, 1);
   84.85 +        break;
   84.86 +    }
   84.87  
   84.88 -    default:	/* PS/2 style mice */
   84.89 -	/* XXX: increase range to 8 bits ? */
   84.90 -	if (dx1 > 127)
   84.91 -	    dx1 = 127;
   84.92 -	else if (dx1 < -127)
   84.93 -	    dx1 = -127;
   84.94 -	if (dy1 > 127)
   84.95 -	    dy1 = 127;
   84.96 -	else if (dy1 < -127)
   84.97 -	    dy1 = -127;
   84.98 -	b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
   84.99 -	kbd_queue(s, b, 1);
  84.100 -	kbd_queue(s, dx1 & 0xff, 1);
  84.101 -	kbd_queue(s, dy1 & 0xff, 1);
  84.102 -	/* extra byte for IMPS/2 or IMEX */
  84.103 -	switch(s->mouse_type) {
  84.104 -
  84.105 -	default:
  84.106 -	    break;
  84.107 -
  84.108 -	case IMPS2:
  84.109 -	    if (dz1 > 127)
  84.110 -		dz1 = 127;
  84.111 -	    else if (dz1 < -127)
  84.112 -		dz1 = -127;
  84.113 -	    kbd_queue(s, dz1 & 0xff, 1);
  84.114 -	    break;
  84.115 -
  84.116 -	case IMEX:
  84.117 -	    if (dz1 > 7)
  84.118 -		dz1 = 7;
  84.119 -	    else if (dz1 < -7)
  84.120 -		dz1 = -7;
  84.121 -	    b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
  84.122 -	    kbd_queue(s, b, 1);
  84.123 -	    break;
  84.124 -	}
  84.125 -
  84.126 -	/* update deltas */
  84.127 -	s->mouse_dx -= dx1;
  84.128 -	s->mouse_dy -= dy1;
  84.129 -	s->mouse_dz -= dz1;
  84.130 -	return s->mouse_dx || s->mouse_dy || s->mouse_dz;
  84.131 -
  84.132 -    }
  84.133 +    /* update deltas */
  84.134 +    s->mouse_dx -= dx1;
  84.135 +    s->mouse_dy -= dy1;
  84.136 +    s->mouse_dz -= dz1;
  84.137  }
  84.138  
  84.139 -static void pc_kbd_mouse_event(void *opaque, 
  84.140 -                               int dx, int dy, int dz, int buttons_state,
  84.141 -			       int x, int y)
  84.142 +static void summa_mouse_event(void *opaque, int x, int y, int z, int buttons_state)
  84.143  {
  84.144      KBDState *s = opaque;
  84.145  
  84.146 -    /* check if deltas are recorded when disabled */
  84.147 -    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
  84.148 -        return;
  84.149 -
  84.150 -    s->mouse_x = x;
  84.151 -    s->mouse_y = y;
  84.152 -    s->mouse_dx += dx;
  84.153 -    s->mouse_dy -= dy;
  84.154 -    s->mouse_dz += dz;
  84.155 -    /* XXX: SDL sometimes generates nul events: we delete them */
  84.156 -    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
  84.157 -        s->mouse_buttons == buttons_state)
  84.158 -	return;
  84.159 -    s->mouse_buttons = buttons_state;
  84.160 -    
  84.161 -    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
  84.162 -        (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
  84.163 -		while (kbd_mouse_send_packet(s))
  84.164 -		    ;
  84.165 +    if (SummaState.report_mode == MODE_STREAM) {
  84.166 +	if (SummaState.origin == ORIGIN_LOWER_LEFT)
  84.167 +	    y = mouse_maxy - y;
  84.168 +	x = ((x * SUMMA_MAXX) / MAX_ABSX) + SUMMA_BORDER;
  84.169 +	y = ((y * SUMMA_MAXY) / MAX_ABSY) + SUMMA_BORDER;
  84.170 +fprintf(stderr, "summa_mouse_event: x, y - %d, %d\n", x, y);
  84.171 +	ser_queue(s->serial, 0x80 | (buttons_state & 7));
  84.172 +	ser_queue(s->serial, x & 0x7f);
  84.173 +	ser_queue(s->serial, x >> 7);
  84.174 +	ser_queue(s->serial, y & 0x7f);
  84.175 +	ser_queue(s->serial, y >> 7);
  84.176      }
  84.177 +    return;
  84.178  }
  84.179  
  84.180  static void summa(KBDState *s, uint8_t val)
  84.181 @@ -564,6 +528,7 @@ static void summa(KBDState *s, uint8_t v
  84.182  	s->mouse_status |= MOUSE_STATUS_ENABLED;
  84.183  	SummaState.origin = ORIGIN_LOWER_LEFT;
  84.184  	SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH;
  84.185 +	qemu_add_mouse_event_handler(summa_mouse_event, s, 1);
  84.186  	break;
  84.187  
  84.188      case 'z':	/* start of 2 byte command */
  84.189 @@ -647,6 +612,36 @@ void summa_init(SerialState *serial, Cha
  84.190      return;
  84.191  }
  84.192  
  84.193 +static void pc_kbd_mouse_event(void *opaque, 
  84.194 +                               int dx, int dy, int dz, int buttons_state)
  84.195 +{
  84.196 +    KBDState *s = opaque;
  84.197 +
  84.198 +    /* check if deltas are recorded when disabled */
  84.199 +    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
  84.200 +        return;
  84.201 +
  84.202 +    s->mouse_dx += dx;
  84.203 +    s->mouse_dy -= dy;
  84.204 +    s->mouse_dz += dz;
  84.205 +    /* XXX: SDL sometimes generates nul events: we delete them */
  84.206 +    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
  84.207 +        s->mouse_buttons == buttons_state)
  84.208 +	return;
  84.209 +    s->mouse_buttons = buttons_state;
  84.210 +    
  84.211 +    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
  84.212 +        (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
  84.213 +	for(;;) {
  84.214 +	    /* if not remote, send event. Multiple events are sent if
  84.215 +	       too big deltas */
  84.216 +	    kbd_mouse_send_packet(s);
  84.217 +	    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
  84.218 +		break;
  84.219 +	}
  84.220 +    }
  84.221 +}
  84.222 +
  84.223  static void kbd_write_mouse(KBDState *s, int val)
  84.224  {
  84.225  #ifdef DEBUG_MOUSE
  84.226 @@ -890,6 +885,6 @@ void kbd_init(void)
  84.227      register_ioport_write(0x64, 1, 1, kbd_write_command, s);
  84.228  
  84.229      qemu_add_kbd_event_handler(pc_kbd_put_keycode, s);
  84.230 -    qemu_add_mouse_event_handler(pc_kbd_mouse_event, s);
  84.231 +    qemu_add_mouse_event_handler(pc_kbd_mouse_event, s, 0);
  84.232      qemu_register_reset(kbd_reset, s);
  84.233  }
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/tools/ioemu/hw/usb-hid.c	Tue Jun 13 12:12:24 2006 -0600
    85.3 @@ -0,0 +1,537 @@
    85.4 +/*
    85.5 + * QEMU USB HID devices
    85.6 + * 
    85.7 + * Copyright (c) 2005 Fabrice Bellard
    85.8 + * 
    85.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   85.10 + * of this software and associated documentation files (the "Software"), to deal
   85.11 + * in the Software without restriction, including without limitation the rights
   85.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   85.13 + * copies of the Software, and to permit persons to whom the Software is
   85.14 + * furnished to do so, subject to the following conditions:
   85.15 + *
   85.16 + * The above copyright notice and this permission notice shall be included in
   85.17 + * all copies or substantial portions of the Software.
   85.18 + *
   85.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   85.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   85.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   85.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   85.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   85.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   85.25 + * THE SOFTWARE.
   85.26 + */
   85.27 +#include "vl.h"
   85.28 +
   85.29 +/* HID interface requests */
   85.30 +#define GET_REPORT   0xa101
   85.31 +#define GET_IDLE     0xa102
   85.32 +#define GET_PROTOCOL 0xa103
   85.33 +#define SET_IDLE     0x210a
   85.34 +#define SET_PROTOCOL 0x210b
   85.35 +
   85.36 +#define USB_MOUSE  1
   85.37 +#define USB_TABLET 2
   85.38 +
   85.39 +typedef struct USBMouseState {
   85.40 +    USBDevice dev;
   85.41 +    int dx, dy, dz, buttons_state;
   85.42 +    int x, y;
   85.43 +    int kind;
   85.44 +    int mouse_grabbed;
   85.45 +} USBMouseState;
   85.46 +
   85.47 +/* mostly the same values as the Bochs USB Mouse device */
   85.48 +static const uint8_t qemu_mouse_dev_descriptor[] = {
   85.49 +	0x12,       /*  u8 bLength; */
   85.50 +	0x01,       /*  u8 bDescriptorType; Device */
   85.51 +	0x10, 0x00, /*  u16 bcdUSB; v1.0 */
   85.52 +
   85.53 +	0x00,	    /*  u8  bDeviceClass; */
   85.54 +	0x00,	    /*  u8  bDeviceSubClass; */
   85.55 +	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
   85.56 +	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
   85.57 +
   85.58 +	0x27, 0x06, /*  u16 idVendor; */
   85.59 + 	0x01, 0x00, /*  u16 idProduct; */
   85.60 +	0x00, 0x00, /*  u16 bcdDevice */
   85.61 +
   85.62 +	0x03,       /*  u8  iManufacturer; */
   85.63 +	0x02,       /*  u8  iProduct; */
   85.64 +	0x01,       /*  u8  iSerialNumber; */
   85.65 +	0x01        /*  u8  bNumConfigurations; */
   85.66 +};
   85.67 +
   85.68 +static const uint8_t qemu_mouse_config_descriptor[] = {
   85.69 +	/* one configuration */
   85.70 +	0x09,       /*  u8  bLength; */
   85.71 +	0x02,       /*  u8  bDescriptorType; Configuration */
   85.72 +	0x22, 0x00, /*  u16 wTotalLength; */
   85.73 +	0x01,       /*  u8  bNumInterfaces; (1) */
   85.74 +	0x01,       /*  u8  bConfigurationValue; */
   85.75 +	0x04,       /*  u8  iConfiguration; */
   85.76 +	0xa0,       /*  u8  bmAttributes; 
   85.77 +				 Bit 7: must be set,
   85.78 +				     6: Self-powered,
   85.79 +				     5: Remote wakeup,
   85.80 +				     4..0: resvd */
   85.81 +	50,         /*  u8  MaxPower; */
   85.82 +      
   85.83 +	/* USB 1.1:
   85.84 +	 * USB 2.0, single TT organization (mandatory):
   85.85 +	 *	one interface, protocol 0
   85.86 +	 *
   85.87 +	 * USB 2.0, multiple TT organization (optional):
   85.88 +	 *	two interfaces, protocols 1 (like single TT)
   85.89 +	 *	and 2 (multiple TT mode) ... config is
   85.90 +	 *	sometimes settable
   85.91 +	 *	NOT IMPLEMENTED
   85.92 +	 */
   85.93 +
   85.94 +	/* one interface */
   85.95 +	0x09,       /*  u8  if_bLength; */
   85.96 +	0x04,       /*  u8  if_bDescriptorType; Interface */
   85.97 +	0x00,       /*  u8  if_bInterfaceNumber; */
   85.98 +	0x00,       /*  u8  if_bAlternateSetting; */
   85.99 +	0x01,       /*  u8  if_bNumEndpoints; */
  85.100 +	0x03,       /*  u8  if_bInterfaceClass; */
  85.101 +	0x01,       /*  u8  if_bInterfaceSubClass; */
  85.102 +	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
  85.103 +	0x05,       /*  u8  if_iInterface; */
  85.104 +     
  85.105 +        /* HID descriptor */
  85.106 +        0x09,        /*  u8  bLength; */
  85.107 +        0x21,        /*  u8 bDescriptorType; */
  85.108 +        0x01, 0x00,  /*  u16 HID_class */
  85.109 +        0x00,        /*  u8 country_code */
  85.110 +        0x01,        /*  u8 num_descriptors */
  85.111 +        0x22,        /*  u8 type; Report */
  85.112 +        50, 0,       /*  u16 len */
  85.113 +
  85.114 +	/* one endpoint (status change endpoint) */
  85.115 +	0x07,       /*  u8  ep_bLength; */
  85.116 +	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
  85.117 +	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
  85.118 + 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
  85.119 + 	0x03, 0x00, /*  u16 ep_wMaxPacketSize; */
  85.120 +	0x0a,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
  85.121 +};
  85.122 +
  85.123 +static const uint8_t qemu_tablet_config_descriptor[] = {
  85.124 +	/* one configuration */
  85.125 +	0x09,       /*  u8  bLength; */
  85.126 +	0x02,       /*  u8  bDescriptorType; Configuration */
  85.127 +	0x22, 0x00, /*  u16 wTotalLength; */
  85.128 +	0x01,       /*  u8  bNumInterfaces; (1) */
  85.129 +	0x01,       /*  u8  bConfigurationValue; */
  85.130 +	0x04,       /*  u8  iConfiguration; */
  85.131 +	0xa0,       /*  u8  bmAttributes; 
  85.132 +				 Bit 7: must be set,
  85.133 +				     6: Self-powered,
  85.134 +				     5: Remote wakeup,
  85.135 +				     4..0: resvd */
  85.136 +	50,         /*  u8  MaxPower; */
  85.137 +      
  85.138 +	/* USB 1.1:
  85.139 +	 * USB 2.0, single TT organization (mandatory):
  85.140 +	 *	one interface, protocol 0
  85.141 +	 *
  85.142 +	 * USB 2.0, multiple TT organization (optional):
  85.143 +	 *	two interfaces, protocols 1 (like single TT)
  85.144 +	 *	and 2 (multiple TT mode) ... config is
  85.145 +	 *	sometimes settable
  85.146 +	 *	NOT IMPLEMENTED
  85.147 +	 */
  85.148 +
  85.149 +	/* one interface */
  85.150 +	0x09,       /*  u8  if_bLength; */
  85.151 +	0x04,       /*  u8  if_bDescriptorType; Interface */
  85.152 +	0x00,       /*  u8  if_bInterfaceNumber; */
  85.153 +	0x00,       /*  u8  if_bAlternateSetting; */
  85.154 +	0x01,       /*  u8  if_bNumEndpoints; */
  85.155 +	0x03,       /*  u8  if_bInterfaceClass; */
  85.156 +	0x01,       /*  u8  if_bInterfaceSubClass; */
  85.157 +	0x02,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
  85.158 +	0x05,       /*  u8  if_iInterface; */
  85.159 +
  85.160 +        /* HID descriptor */
  85.161 +        0x09,        /*  u8  bLength; */
  85.162 +        0x21,        /*  u8 bDescriptorType; */
  85.163 +        0x01, 0x00,  /*  u16 HID_class */
  85.164 +        0x00,        /*  u8 country_code */
  85.165 +        0x01,        /*  u8 num_descriptors */
  85.166 +        0x22,        /*  u8 type; Report */
  85.167 +        74, 0,       /*  u16 len */
  85.168 +
  85.169 +	/* one endpoint (status change endpoint) */
  85.170 +	0x07,       /*  u8  ep_bLength; */
  85.171 +	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
  85.172 +	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
  85.173 + 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
  85.174 + 	0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
  85.175 +	0x03,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
  85.176 +};
  85.177 +
  85.178 +static const uint8_t qemu_mouse_hid_report_descriptor[] = {
  85.179 +    0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 
  85.180 +    0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
  85.181 +    0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 
  85.182 +    0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
  85.183 +    0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, 
  85.184 +    0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
  85.185 +    0xC0, 0xC0,
  85.186 +};
  85.187 +
  85.188 +static const uint8_t qemu_tablet_hid_report_descriptor[] = {
  85.189 +        0x05, 0x01, /* Usage Page Generic Desktop */
  85.190 +        0x09, 0x01, /* Usage Mouse */
  85.191 +        0xA1, 0x01, /* Collection Application */
  85.192 +        0x09, 0x01, /* Usage Pointer */
  85.193 +        0xA1, 0x00, /* Collection Physical */
  85.194 +        0x05, 0x09, /* Usage Page Button */
  85.195 +        0x19, 0x01, /* Usage Minimum Button 1 */
  85.196 +        0x29, 0x03, /* Usage Maximum Button 3 */
  85.197 +        0x15, 0x00, /* Logical Minimum 0 */
  85.198 +        0x25, 0x01, /* Logical Maximum 1 */
  85.199 +        0x95, 0x03, /* Report Count 3 */
  85.200 +        0x75, 0x01, /* Report Size 1 */
  85.201 +        0x81, 0x02, /* Input (Data, Var, Abs) */
  85.202 +        0x95, 0x01, /* Report Count 1 */
  85.203 +        0x75, 0x05, /* Report Size 5 */
  85.204 +        0x81, 0x01, /* Input (Cnst, Var, Abs) */
  85.205 +        0x05, 0x01, /* Usage Page Generic Desktop */
  85.206 +        0x09, 0x30, /* Usage X */
  85.207 +        0x09, 0x31, /* Usage Y */
  85.208 +        0x15, 0x00, /* Logical Minimum 0 */
  85.209 +        0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
  85.210 +        0x35, 0x00, /* Physical Minimum 0 */
  85.211 +        0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
  85.212 +        0x75, 0x10, /* Report Size 16 */
  85.213 +        0x95, 0x02, /* Report Count 2 */
  85.214 +        0x81, 0x02, /* Input (Data, Var, Abs) */
  85.215 +        0x05, 0x01, /* Usage Page Generic Desktop */
  85.216 +        0x09, 0x38, /* Usage Wheel */
  85.217 +        0x15, 0x81, /* Logical Minimum -127 */
  85.218 +        0x25, 0x7F, /* Logical Maximum 127 */
  85.219 +        0x35, 0x00, /* Physical Minimum 0 (same as logical) */
  85.220 +        0x45, 0x00, /* Physical Maximum 0 (same as logical) */
  85.221 +        0x75, 0x08, /* Report Size 8 */
  85.222 +        0x95, 0x01, /* Report Count 1 */
  85.223 +        0x81, 0x02, /* Input (Data, Var, Rel) */
  85.224 +        0xC0,       /* End Collection */
  85.225 +        0xC0,       /* End Collection */
  85.226 +};
  85.227 +
  85.228 +static void usb_mouse_event(void *opaque,
  85.229 +                            int dx1, int dy1, int dz1, int buttons_state)
  85.230 +{
  85.231 +    USBMouseState *s = opaque;
  85.232 +
  85.233 +    s->dx += dx1;
  85.234 +    s->dy += dy1;
  85.235 +    s->dz += dz1;
  85.236 +    s->buttons_state = buttons_state;
  85.237 +}
  85.238 +
  85.239 +static void usb_tablet_event(void *opaque,
  85.240 +			     int x, int y, int dz, int buttons_state)
  85.241 +{
  85.242 +    USBMouseState *s = opaque;
  85.243 +
  85.244 +    s->x = x;
  85.245 +    s->y = y;
  85.246 +    s->dz += dz;
  85.247 +    s->buttons_state = buttons_state;
  85.248 +}
  85.249 +
  85.250 +static inline int int_clamp(int val, int vmin, int vmax)
  85.251 +{
  85.252 +    if (val < vmin)
  85.253 +        return vmin;
  85.254 +    else if (val > vmax)
  85.255 +        return vmax;
  85.256 +    else
  85.257 +        return val;
  85.258 +}
  85.259 +
  85.260 +static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
  85.261 +{
  85.262 +    int dx, dy, dz, b, l;
  85.263 +
  85.264 +    if (!s->mouse_grabbed) {
  85.265 +	qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
  85.266 +	s->mouse_grabbed = 1;
  85.267 +    }
  85.268 +    
  85.269 +    dx = int_clamp(s->dx, -128, 127);
  85.270 +    dy = int_clamp(s->dy, -128, 127);
  85.271 +    dz = int_clamp(s->dz, -128, 127);
  85.272 +
  85.273 +    s->dx -= dx;
  85.274 +    s->dy -= dy;
  85.275 +    s->dz -= dz;
  85.276 +    
  85.277 +    b = 0;
  85.278 +    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
  85.279 +        b |= 0x01;
  85.280 +    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
  85.281 +        b |= 0x02;
  85.282 +    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
  85.283 +        b |= 0x04;
  85.284 +    
  85.285 +    buf[0] = b;
  85.286 +    buf[1] = dx;
  85.287 +    buf[2] = dy;
  85.288 +    l = 3;
  85.289 +    if (len >= 4) {
  85.290 +        buf[3] = dz;
  85.291 +        l = 4;
  85.292 +    }
  85.293 +    return l;
  85.294 +}
  85.295 +
  85.296 +static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
  85.297 +{
  85.298 +    int dz, b, l;
  85.299 +
  85.300 +    if (!s->mouse_grabbed) {
  85.301 +	qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
  85.302 +	s->mouse_grabbed = 1;
  85.303 +    }
  85.304 +    
  85.305 +    dz = int_clamp(s->dz, -128, 127);
  85.306 +    s->dz -= dz;
  85.307 +
  85.308 +    /* Appears we have to invert the wheel direction */
  85.309 +    dz = 0 - dz;
  85.310 +    b = 0;
  85.311 +    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
  85.312 +        b |= 0x01;
  85.313 +    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
  85.314 +        b |= 0x02;
  85.315 +    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
  85.316 +        b |= 0x04;
  85.317 +
  85.318 +    buf[0] = b;
  85.319 +    buf[1] = s->x & 0xff;
  85.320 +    buf[2] = s->x >> 8;
  85.321 +    buf[3] = s->y & 0xff;
  85.322 +    buf[4] = s->y >> 8;
  85.323 +    buf[5] = dz;
  85.324 +    l = 6;
  85.325 +
  85.326 +    return l;
  85.327 +}
  85.328 +
  85.329 +static void usb_mouse_handle_reset(USBDevice *dev)
  85.330 +{
  85.331 +    USBMouseState *s = (USBMouseState *)dev;
  85.332 +
  85.333 +    s->dx = 0;
  85.334 +    s->dy = 0;
  85.335 +    s->dz = 0;
  85.336 +    s->x = 0;
  85.337 +    s->y = 0;
  85.338 +    s->buttons_state = 0;
  85.339 +}
  85.340 +
  85.341 +static int usb_mouse_handle_control(USBDevice *dev, int request, int value,
  85.342 +                                  int index, int length, uint8_t *data)
  85.343 +{
  85.344 +    USBMouseState *s = (USBMouseState *)dev;
  85.345 +    int ret = 0;
  85.346 +
  85.347 +    switch(request) {
  85.348 +    case DeviceRequest | USB_REQ_GET_STATUS:
  85.349 +        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
  85.350 +            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
  85.351 +        data[1] = 0x00;
  85.352 +        ret = 2;
  85.353 +        break;
  85.354 +    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
  85.355 +        if (value == USB_DEVICE_REMOTE_WAKEUP) {
  85.356 +            dev->remote_wakeup = 0;
  85.357 +        } else {
  85.358 +            goto fail;
  85.359 +        }
  85.360 +        ret = 0;
  85.361 +        break;
  85.362 +    case DeviceOutRequest | USB_REQ_SET_FEATURE:
  85.363 +        if (value == USB_DEVICE_REMOTE_WAKEUP) {
  85.364 +            dev->remote_wakeup = 1;
  85.365 +        } else {
  85.366 +            goto fail;
  85.367 +        }
  85.368 +        ret = 0;
  85.369 +        break;
  85.370 +    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
  85.371 +        dev->addr = value;
  85.372 +        ret = 0;
  85.373 +        break;
  85.374 +    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
  85.375 +        switch(value >> 8) {
  85.376 +        case USB_DT_DEVICE:
  85.377 +            memcpy(data, qemu_mouse_dev_descriptor, 
  85.378 +                   sizeof(qemu_mouse_dev_descriptor));
  85.379 +            ret = sizeof(qemu_mouse_dev_descriptor);
  85.380 +            break;
  85.381 +        case USB_DT_CONFIG:
  85.382 +	    if (s->kind == USB_MOUSE) {
  85.383 +		memcpy(data, qemu_mouse_config_descriptor, 
  85.384 +		       sizeof(qemu_mouse_config_descriptor));
  85.385 +		ret = sizeof(qemu_mouse_config_descriptor);
  85.386 +	    } else if (s->kind == USB_TABLET) {
  85.387 +		memcpy(data, qemu_tablet_config_descriptor, 
  85.388 +		       sizeof(qemu_tablet_config_descriptor));
  85.389 +		ret = sizeof(qemu_tablet_config_descriptor);
  85.390 +	    }		
  85.391 +            break;
  85.392 +        case USB_DT_STRING:
  85.393 +            switch(value & 0xff) {
  85.394 +            case 0:
  85.395 +                /* language ids */
  85.396 +                data[0] = 4;
  85.397 +                data[1] = 3;
  85.398 +                data[2] = 0x09;
  85.399 +                data[3] = 0x04;
  85.400 +                ret = 4;
  85.401 +                break;
  85.402 +            case 1:
  85.403 +                /* serial number */
  85.404 +                ret = set_usb_string(data, "1");
  85.405 +                break;
  85.406 +            case 2:
  85.407 +                /* product description */
  85.408 +		if (s->kind == USB_MOUSE)
  85.409 +		    ret = set_usb_string(data, "QEMU USB Mouse");
  85.410 +		else if (s->kind == USB_TABLET)
  85.411 +		    ret = set_usb_string(data, "QEMU USB Tablet");
  85.412 +                break;
  85.413 +            case 3:
  85.414 +                /* vendor description */
  85.415 +                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
  85.416 +                break;
  85.417 +            case 4:
  85.418 +                ret = set_usb_string(data, "HID Mouse");
  85.419 +                break;
  85.420 +            case 5:
  85.421 +                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
  85.422 +                break;
  85.423 +            default:
  85.424 +                goto fail;
  85.425 +            }
  85.426 +            break;
  85.427 +        default:
  85.428 +            goto fail;
  85.429 +        }
  85.430 +        break;
  85.431 +    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
  85.432 +        data[0] = 1;
  85.433 +        ret = 1;
  85.434 +        break;
  85.435 +    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
  85.436 +        ret = 0;
  85.437 +        break;
  85.438 +    case DeviceRequest | USB_REQ_GET_INTERFACE:
  85.439 +        data[0] = 0;
  85.440 +        ret = 1;
  85.441 +        break;
  85.442 +    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
  85.443 +        ret = 0;
  85.444 +        break;
  85.445 +        /* hid specific requests */
  85.446 +    case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
  85.447 +        switch(value >> 8) {
  85.448 +        case 0x22:
  85.449 +	    if (s->kind == USB_MOUSE) {
  85.450 +		memcpy(data, qemu_mouse_hid_report_descriptor, 
  85.451 +		       sizeof(qemu_mouse_hid_report_descriptor));
  85.452 +		ret = sizeof(qemu_mouse_hid_report_descriptor);
  85.453 +	    } else if (s->kind == USB_TABLET) {
  85.454 +		memcpy(data, qemu_tablet_hid_report_descriptor, 
  85.455 +		       sizeof(qemu_tablet_hid_report_descriptor));
  85.456 +		ret = sizeof(qemu_tablet_hid_report_descriptor);
  85.457 +	    }
  85.458 +	    break;
  85.459 +        default:
  85.460 +            goto fail;
  85.461 +        }
  85.462 +        break;
  85.463 +    case GET_REPORT:
  85.464 +	if (s->kind == USB_MOUSE)
  85.465 +	    ret = usb_mouse_poll(s, data, length);
  85.466 +	else if (s->kind == USB_TABLET)
  85.467 +	    ret = usb_tablet_poll(s, data, length);
  85.468 +        break;
  85.469 +    case SET_IDLE:
  85.470 +        ret = 0;
  85.471 +        break;
  85.472 +    default:
  85.473 +    fail:
  85.474 +        ret = USB_RET_STALL;
  85.475 +        break;
  85.476 +    }
  85.477 +    return ret;
  85.478 +}
  85.479 +
  85.480 +static int usb_mouse_handle_data(USBDevice *dev, int pid, 
  85.481 +                                 uint8_t devep, uint8_t *data, int len)
  85.482 +{
  85.483 +    USBMouseState *s = (USBMouseState *)dev;
  85.484 +    int ret = 0;
  85.485 +
  85.486 +    switch(pid) {
  85.487 +    case USB_TOKEN_IN:
  85.488 +        if (devep == 1) {
  85.489 +	    if (s->kind == USB_MOUSE)
  85.490 +		ret = usb_mouse_poll(s, data, len);
  85.491 +	    else if (s->kind == USB_TABLET)
  85.492 +		ret = usb_tablet_poll(s, data, len);
  85.493 +        } else {
  85.494 +            goto fail;
  85.495 +        }
  85.496 +        break;
  85.497 +    case USB_TOKEN_OUT:
  85.498 +    default:
  85.499 +    fail:
  85.500 +        ret = USB_RET_STALL;
  85.501 +        break;
  85.502 +    }
  85.503 +    return ret;
  85.504 +}
  85.505 +
  85.506 +USBDevice *usb_tablet_init(void)
  85.507 +{
  85.508 +    USBMouseState *s;
  85.509 +
  85.510 +    s = qemu_mallocz(sizeof(USBMouseState));
  85.511 +    if (!s)
  85.512 +        return NULL;
  85.513 +    s->dev.speed = USB_SPEED_FULL;
  85.514 +    s->dev.handle_packet = usb_generic_handle_packet;
  85.515 +
  85.516 +    s->dev.handle_reset = usb_mouse_handle_reset;
  85.517 +    s->dev.handle_control = usb_mouse_handle_control;
  85.518 +    s->dev.handle_data = usb_mouse_handle_data;
  85.519 +    s->kind = USB_TABLET;
  85.520 +
  85.521 +    return (USBDevice *)s;
  85.522 +}
  85.523 +
  85.524 +USBDevice *usb_mouse_init(void)
  85.525 +{
  85.526 +    USBMouseState *s;
  85.527 +
  85.528 +    s = qemu_mallocz(sizeof(USBMouseState));
  85.529 +    if (!s)
  85.530 +        return NULL;
  85.531 +    s->dev.speed = USB_SPEED_FULL;
  85.532 +    s->dev.handle_packet = usb_generic_handle_packet;
  85.533 +
  85.534 +    s->dev.handle_reset = usb_mouse_handle_reset;
  85.535 +    s->dev.handle_control = usb_mouse_handle_control;
  85.536 +    s->dev.handle_data = usb_mouse_handle_data;
  85.537 +    s->kind = USB_MOUSE;
  85.538 +
  85.539 +    return (USBDevice *)s;
  85.540 +}
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/tools/ioemu/hw/usb-hub.c	Tue Jun 13 12:12:24 2006 -0600
    86.3 @@ -0,0 +1,549 @@
    86.4 +/*
    86.5 + * QEMU USB HUB emulation
    86.6 + *
    86.7 + * Copyright (c) 2005 Fabrice Bellard
    86.8 + * 
    86.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   86.10 + * of this software and associated documentation files (the "Software"), to deal
   86.11 + * in the Software without restriction, including without limitation the rights
   86.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   86.13 + * copies of the Software, and to permit persons to whom the Software is
   86.14 + * furnished to do so, subject to the following conditions:
   86.15 + *
   86.16 + * The above copyright notice and this permission notice shall be included in
   86.17 + * all copies or substantial portions of the Software.
   86.18 + *
   86.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   86.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   86.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   86.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   86.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   86.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   86.25 + * THE SOFTWARE.
   86.26 + */
   86.27 +#include "vl.h"
   86.28 +
   86.29 +//#define DEBUG
   86.30 +
   86.31 +#define MAX_PORTS 8
   86.32 +
   86.33 +typedef struct USBHubPort {
   86.34 +    USBPort port;
   86.35 +    uint16_t wPortStatus;
   86.36 +    uint16_t wPortChange;
   86.37 +} USBHubPort;
   86.38 +
   86.39 +typedef struct USBHubState {
   86.40 +    USBDevice dev;
   86.41 +    int nb_ports;
   86.42 +    USBHubPort ports[MAX_PORTS];
   86.43 +} USBHubState;
   86.44 +
   86.45 +#define ClearHubFeature		(0x2000 | USB_REQ_CLEAR_FEATURE)
   86.46 +#define ClearPortFeature	(0x2300 | USB_REQ_CLEAR_FEATURE)
   86.47 +#define GetHubDescriptor	(0xa000 | USB_REQ_GET_DESCRIPTOR)
   86.48 +#define GetHubStatus		(0xa000 | USB_REQ_GET_STATUS)
   86.49 +#define GetPortStatus		(0xa300 | USB_REQ_GET_STATUS)
   86.50 +#define SetHubFeature		(0x2000 | USB_REQ_SET_FEATURE)
   86.51 +#define SetPortFeature		(0x2300 | USB_REQ_SET_FEATURE)
   86.52 +
   86.53 +#define PORT_STAT_CONNECTION	0x0001
   86.54 +#define PORT_STAT_ENABLE	0x0002
   86.55 +#define PORT_STAT_SUSPEND	0x0004
   86.56 +#define PORT_STAT_OVERCURRENT	0x0008
   86.57 +#define PORT_STAT_RESET		0x0010
   86.58 +#define PORT_STAT_POWER		0x0100
   86.59 +#define PORT_STAT_LOW_SPEED	0x0200
   86.60 +#define PORT_STAT_HIGH_SPEED    0x0400
   86.61 +#define PORT_STAT_TEST          0x0800
   86.62 +#define PORT_STAT_INDICATOR     0x1000
   86.63 +
   86.64 +#define PORT_STAT_C_CONNECTION	0x0001
   86.65 +#define PORT_STAT_C_ENABLE	0x0002
   86.66 +#define PORT_STAT_C_SUSPEND	0x0004
   86.67 +#define PORT_STAT_C_OVERCURRENT	0x0008
   86.68 +#define PORT_STAT_C_RESET	0x0010
   86.69 +
   86.70 +#define PORT_CONNECTION	        0
   86.71 +#define PORT_ENABLE		1
   86.72 +#define PORT_SUSPEND		2
   86.73 +#define PORT_OVERCURRENT	3
   86.74 +#define PORT_RESET		4
   86.75 +#define PORT_POWER		8
   86.76 +#define PORT_LOWSPEED		9
   86.77 +#define PORT_HIGHSPEED		10
   86.78 +#define PORT_C_CONNECTION	16
   86.79 +#define PORT_C_ENABLE		17
   86.80 +#define PORT_C_SUSPEND		18
   86.81 +#define PORT_C_OVERCURRENT	19
   86.82 +#define PORT_C_RESET		20
   86.83 +#define PORT_TEST               21
   86.84 +#define PORT_INDICATOR          22
   86.85 +
   86.86 +/* same as Linux kernel root hubs */
   86.87 +
   86.88 +static const uint8_t qemu_hub_dev_descriptor[] = {
   86.89 +	0x12,       /*  u8 bLength; */
   86.90 +	0x01,       /*  u8 bDescriptorType; Device */
   86.91 +	0x10, 0x01, /*  u16 bcdUSB; v1.1 */
   86.92 +
   86.93 +	0x09,	    /*  u8  bDeviceClass; HUB_CLASSCODE */
   86.94 +	0x00,	    /*  u8  bDeviceSubClass; */
   86.95 +	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
   86.96 +	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
   86.97 +
   86.98 +	0x00, 0x00, /*  u16 idVendor; */
   86.99 + 	0x00, 0x00, /*  u16 idProduct; */
  86.100 +	0x01, 0x01, /*  u16 bcdDevice */
  86.101 +
  86.102 +	0x03,       /*  u8  iManufacturer; */
  86.103 +	0x02,       /*  u8  iProduct; */
  86.104 +	0x01,       /*  u8  iSerialNumber; */
  86.105 +	0x01        /*  u8  bNumConfigurations; */
  86.106 +};
  86.107 +
  86.108 +/* XXX: patch interrupt size */
  86.109 +static const uint8_t qemu_hub_config_descriptor[] = {
  86.110 +
  86.111 +	/* one configuration */
  86.112 +	0x09,       /*  u8  bLength; */
  86.113 +	0x02,       /*  u8  bDescriptorType; Configuration */
  86.114 +	0x19, 0x00, /*  u16 wTotalLength; */
  86.115 +	0x01,       /*  u8  bNumInterfaces; (1) */
  86.116 +	0x01,       /*  u8  bConfigurationValue; */
  86.117 +	0x00,       /*  u8  iConfiguration; */
  86.118 +	0xc0,       /*  u8  bmAttributes; 
  86.119 +				 Bit 7: must be set,
  86.120 +				     6: Self-powered,
  86.121 +				     5: Remote wakeup,
  86.122 +				     4..0: resvd */
  86.123 +	0x00,       /*  u8  MaxPower; */
  86.124 +      
  86.125 +	/* USB 1.1:
  86.126 +	 * USB 2.0, single TT organization (mandatory):
  86.127 +	 *	one interface, protocol 0
  86.128 +	 *
  86.129 +	 * USB 2.0, multiple TT organization (optional):
  86.130 +	 *	two interfaces, protocols 1 (like single TT)
  86.131 +	 *	and 2 (multiple TT mode) ... config is
  86.132 +	 *	sometimes settable
  86.133 +	 *	NOT IMPLEMENTED
  86.134 +	 */
  86.135 +
  86.136 +	/* one interface */
  86.137 +	0x09,       /*  u8  if_bLength; */
  86.138 +	0x04,       /*  u8  if_bDescriptorType; Interface */
  86.139 +	0x00,       /*  u8  if_bInterfaceNumber; */
  86.140 +	0x00,       /*  u8  if_bAlternateSetting; */
  86.141 +	0x01,       /*  u8  if_bNumEndpoints; */
  86.142 +	0x09,       /*  u8  if_bInterfaceClass; HUB_CLASSCODE */
  86.143 +	0x00,       /*  u8  if_bInterfaceSubClass; */
  86.144 +	0x00,       /*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
  86.145 +	0x00,       /*  u8  if_iInterface; */
  86.146 +     
  86.147 +	/* one endpoint (status change endpoint) */
  86.148 +	0x07,       /*  u8  ep_bLength; */
  86.149 +	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
  86.150 +	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
  86.151 + 	0x03,       /*  u8  ep_bmAttributes; Interrupt */
  86.152 + 	0x02, 0x00, /*  u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
  86.153 +	0xff        /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
  86.154 +};
  86.155 +
  86.156 +static const uint8_t qemu_hub_hub_descriptor[] =
  86.157 +{
  86.158 +	0x09,			/*  u8  bLength; */
  86.159 +	0x29,			/*  u8  bDescriptorType; Hub-descriptor */
  86.160 +	0x00,			/*  u8  bNbrPorts; (patched later) */
  86.161 +	0x0a,			/* u16  wHubCharacteristics; */
  86.162 +	0x00,			/*   (per-port OC, no power switching) */
  86.163 +	0x01,			/*  u8  bPwrOn2pwrGood; 2ms */
  86.164 +	0x00			/*  u8  bHubContrCurrent; 0 mA */
  86.165 +
  86.166 +        /* DeviceRemovable and PortPwrCtrlMask patched in later */
  86.167 +};
  86.168 +
  86.169 +static void usb_hub_attach(USBPort *port1, USBDevice *dev)
  86.170 +{
  86.171 +    USBHubState *s = port1->opaque;
  86.172 +    USBHubPort *port = &s->ports[port1->index];
  86.173 +    
  86.174 +    if (dev) {
  86.175 +        if (port->port.dev)
  86.176 +            usb_attach(port1, NULL);
  86.177 +        
  86.178 +        port->wPortStatus |= PORT_STAT_CONNECTION;
  86.179 +        port->wPortChange |= PORT_STAT_C_CONNECTION;
  86.180 +        if (dev->speed == USB_SPEED_LOW)
  86.181 +            port->wPortStatus |= PORT_STAT_LOW_SPEED;
  86.182 +        else
  86.183 +            port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
  86.184 +        port->port.dev = dev;
  86.185 +    } else {
  86.186 +        dev = port->port.dev;
  86.187 +        if (dev) {
  86.188 +            port->wPortStatus &= ~PORT_STAT_CONNECTION;
  86.189 +            port->wPortChange |= PORT_STAT_C_CONNECTION;
  86.190 +            if (port->wPortStatus & PORT_STAT_ENABLE) {
  86.191 +                port->wPortStatus &= ~PORT_STAT_ENABLE;
  86.192 +                port->wPortChange |= PORT_STAT_C_ENABLE;
  86.193 +            }
  86.194 +            port->port.dev = NULL;
  86.195 +        }
  86.196 +    }
  86.197 +}
  86.198 +
  86.199 +static void usb_hub_handle_reset(USBDevice *dev)
  86.200 +{
  86.201 +    /* XXX: do it */
  86.202 +}
  86.203 +
  86.204 +static int usb_hub_handle_control(USBDevice *dev, int request, int value,
  86.205 +                                  int index, int length, uint8_t *data)
  86.206 +{
  86.207 +    USBHubState *s = (USBHubState *)dev;
  86.208 +    int ret;
  86.209 +
  86.210 +    switch(request) {
  86.211 +    case DeviceRequest | USB_REQ_GET_STATUS:
  86.212 +        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
  86.213 +            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
  86.214 +        data[1] = 0x00;
  86.215 +        ret = 2;
  86.216 +        break;
  86.217 +    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
  86.218 +        if (value == USB_DEVICE_REMOTE_WAKEUP) {
  86.219 +            dev->remote_wakeup = 0;
  86.220 +        } else {
  86.221 +            goto fail;
  86.222 +        }
  86.223 +        ret = 0;
  86.224 +        break;
  86.225 +    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
  86.226 +        if (value == 0 && index != 0x81) { /* clear ep halt */
  86.227 +            goto fail;
  86.228 +        }
  86.229 +        ret = 0;
  86.230 +        break;
  86.231 +    case DeviceOutRequest | USB_REQ_SET_FEATURE:
  86.232 +        if (value == USB_DEVICE_REMOTE_WAKEUP) {
  86.233 +            dev->remote_wakeup = 1;
  86.234 +        } else {
  86.235 +            goto fail;
  86.236 +        }
  86.237 +        ret = 0;
  86.238 +        break;
  86.239 +    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
  86.240 +        dev->addr = value;
  86.241 +        ret = 0;
  86.242 +        break;
  86.243 +    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
  86.244 +        switch(value >> 8) {
  86.245 +        case USB_DT_DEVICE:
  86.246 +            memcpy(data, qemu_hub_dev_descriptor, 
  86.247 +                   sizeof(qemu_hub_dev_descriptor));
  86.248 +            ret = sizeof(qemu_hub_dev_descriptor);
  86.249 +            break;
  86.250 +        case USB_DT_CONFIG:
  86.251 +            memcpy(data, qemu_hub_config_descriptor, 
  86.252 +                   sizeof(qemu_hub_config_descriptor));
  86.253 +
  86.254 +            /* status change endpoint size based on number
  86.255 +             * of ports */
  86.256 +            data[22] = (s->nb_ports + 1 + 7) / 8;
  86.257 +
  86.258 +            ret = sizeof(qemu_hub_config_descriptor);
  86.259 +            break;
  86.260 +        case USB_DT_STRING:
  86.261 +            switch(value & 0xff) {
  86.262 +            case 0:
  86.263 +                /* language ids */
  86.264 +                data[0] = 4;
  86.265 +                data[1] = 3;
  86.266 +                data[2] = 0x09;
  86.267 +                data[3] = 0x04;
  86.268 +                ret = 4;
  86.269 +                break;
  86.270 +            case 1:
  86.271 +                /* serial number */
  86.272 +                ret = set_usb_string(data, "314159");
  86.273 +                break;
  86.274 +            case 2:
  86.275 +                /* product description */
  86.276 +                ret = set_usb_string(data, "QEMU USB Hub");
  86.277 +                break;
  86.278 +            case 3:
  86.279 +                /* vendor description */
  86.280 +                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
  86.281 +                break;
  86.282 +            default:
  86.283 +                goto fail;
  86.284 +            }
  86.285 +            break;
  86.286 +        default:
  86.287 +            goto fail;
  86.288 +        }
  86.289 +        break;
  86.290 +    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
  86.291 +        data[0] = 1;
  86.292 +        ret = 1;
  86.293 +        break;
  86.294 +    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
  86.295 +        ret = 0;
  86.296 +        break;
  86.297 +    case DeviceRequest | USB_REQ_GET_INTERFACE:
  86.298 +        data[0] = 0;
  86.299 +        ret = 1;
  86.300 +        break;
  86.301 +    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
  86.302 +        ret = 0;
  86.303 +        break;
  86.304 +        /* usb specific requests */
  86.305 +    case GetHubStatus:
  86.306 +        data[0] = 0;
  86.307 +        data[1] = 0;
  86.308 +        data[2] = 0;
  86.309 +        data[3] = 0;
  86.310 +        ret = 4;
  86.311 +        break;
  86.312 +    case GetPortStatus:
  86.313 +        {
  86.314 +            unsigned int n = index - 1;
  86.315 +            USBHubPort *port;
  86.316 +            if (n >= s->nb_ports)
  86.317 +                goto fail;
  86.318 +            port = &s->ports[n];
  86.319 +            data[0] = port->wPortStatus;
  86.320 +            data[1] = port->wPortStatus >> 8;
  86.321 +            data[2] = port->wPortChange;
  86.322 +            data[3] = port->wPortChange >> 8;
  86.323 +            ret = 4;
  86.324 +        }
  86.325 +        break;
  86.326 +    case SetHubFeature:
  86.327 +    case ClearHubFeature:
  86.328 +        if (value == 0 || value == 1) {
  86.329 +        } else {
  86.330 +            goto fail;
  86.331 +        }
  86.332 +        ret = 0;
  86.333 +        break;
  86.334 +    case SetPortFeature:
  86.335 +        {
  86.336 +            unsigned int n = index - 1;
  86.337 +            USBHubPort *port;
  86.338 +            USBDevice *dev;
  86.339 +            if (n >= s->nb_ports)
  86.340 +                goto fail;
  86.341 +            port = &s->ports[n];
  86.342 +            dev = port->port.dev;
  86.343 +            switch(value) {
  86.344 +            case PORT_SUSPEND:
  86.345 +                port->wPortStatus |= PORT_STAT_SUSPEND;
  86.346 +                break;
  86.347 +            case PORT_RESET:
  86.348 +                if (dev) {
  86.349 +                    dev->handle_packet(dev, 
  86.350 +                                       USB_MSG_RESET, 0, 0, NULL, 0);
  86.351 +                    port->wPortChange |= PORT_STAT_C_RESET;
  86.352 +                    /* set enable bit */
  86.353 +                    port->wPortStatus |= PORT_STAT_ENABLE;
  86.354 +                }
  86.355 +                break;
  86.356 +            case PORT_POWER:
  86.357 +                break;
  86.358 +            default:
  86.359 +                goto fail;
  86.360 +            }
  86.361 +            ret = 0;
  86.362 +        }
  86.363 +        break;
  86.364 +    case ClearPortFeature:
  86.365 +        {
  86.366 +            unsigned int n = index - 1;
  86.367 +            USBHubPort *port;
  86.368 +            USBDevice *dev;
  86.369 +            if (n >= s->nb_ports)
  86.370 +                goto fail;
  86.371 +            port = &s->ports[n];
  86.372 +            dev = port->port.dev;
  86.373 +            switch(value) {
  86.374 +            case PORT_ENABLE:
  86.375 +                port->wPortStatus &= ~PORT_STAT_ENABLE;
  86.376 +                break;
  86.377 +            case PORT_C_ENABLE:
  86.378 +                port->wPortChange &= ~PORT_STAT_C_ENABLE;
  86.379 +                break;
  86.380 +            case PORT_SUSPEND:
  86.381 +                port->wPortStatus &= ~PORT_STAT_SUSPEND;
  86.382 +                break;
  86.383 +            case PORT_C_SUSPEND:
  86.384 +                port->wPortChange &= ~PORT_STAT_C_SUSPEND;
  86.385 +                break;
  86.386 +            case PORT_C_CONNECTION:
  86.387 +                port->wPortChange &= ~PORT_STAT_C_CONNECTION;
  86.388 +                break;
  86.389 +            case PORT_C_OVERCURRENT:
  86.390 +                port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
  86.391 +                break;
  86.392 +            case PORT_C_RESET:
  86.393 +                port->wPortChange &= ~PORT_STAT_C_RESET;
  86.394 +                break;
  86.395 +            default:
  86.396 +                goto fail;
  86.397 +            }
  86.398 +            ret = 0;
  86.399 +        }
  86.400 +        break;
  86.401 +    case GetHubDescriptor:
  86.402 +        {
  86.403 +            unsigned int n, limit, var_hub_size = 0;
  86.404 +            memcpy(data, qemu_hub_hub_descriptor, 
  86.405 +                   sizeof(qemu_hub_hub_descriptor));
  86.406 +            data[2] = s->nb_ports;
  86.407 +
  86.408 +            /* fill DeviceRemovable bits */
  86.409 +            limit = ((s->nb_ports + 1 + 7) / 8) + 7;
  86.410 +            for (n = 7; n < limit; n++) {
  86.411 +                data[n] = 0x00;
  86.412 +                var_hub_size++;
  86.413 +            }
  86.414 +
  86.415 +            /* fill PortPwrCtrlMask bits */
  86.416 +            limit = limit + ((s->nb_ports + 7) / 8);
  86.417 +            for (;n < limit; n++) {
  86.418 +                data[n] = 0xff;
  86.419 +                var_hub_size++;
  86.420 +            }
  86.421 +
  86.422 +            ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
  86.423 +            break;
  86.424 +        }
  86.425 +    default:
  86.426 +    fail:
  86.427 +        ret = USB_RET_STALL;
  86.428 +        break;
  86.429 +    }
  86.430 +    return ret;
  86.431 +}
  86.432 +
  86.433 +static int usb_hub_handle_data(USBDevice *dev, int pid, 
  86.434 +                               uint8_t devep, uint8_t *data, int len)
  86.435 +{
  86.436 +    USBHubState *s = (USBHubState *)dev;
  86.437 +    int ret;
  86.438 +
  86.439 +    switch(pid) {
  86.440 +    case USB_TOKEN_IN:
  86.441 +        if (devep == 1) {
  86.442 +            USBHubPort *port;
  86.443 +            unsigned int status;
  86.444 +            int i, n;
  86.445 +            n = (s->nb_ports + 1 + 7) / 8;
  86.446 +            if (len == 1) { /* FreeBSD workaround */
  86.447 +                n = 1;
  86.448 +            } else if (n > len) {
  86.449 +                return USB_RET_BABBLE;
  86.450 +            }
  86.451 +            status = 0;
  86.452 +            for(i = 0; i < s->nb_ports; i++) {
  86.453 +                port = &s->ports[i];
  86.454 +                if (port->wPortChange)
  86.455 +                    status |= (1 << (i + 1));
  86.456 +            }
  86.457 +            if (status != 0) {
  86.458 +                for(i = 0; i < n; i++) {
  86.459 +                    data[i] = status >> (8 * i);
  86.460 +                }
  86.461 +                ret = n;
  86.462 +            } else {
  86.463 +                ret = USB_RET_NAK; /* usb11 11.13.1 */
  86.464 +            }
  86.465 +        } else {
  86.466 +            goto fail;
  86.467 +        }
  86.468 +        break;
  86.469 +    case USB_TOKEN_OUT:
  86.470 +    default:
  86.471 +    fail:
  86.472 +        ret = USB_RET_STALL;
  86.473 +        break;
  86.474 +    }
  86.475 +    return ret;
  86.476 +}
  86.477 +
  86.478 +static int usb_hub_broadcast_packet(USBHubState *s, int pid, 
  86.479 +                                    uint8_t devaddr, uint8_t devep,
  86.480 +                                    uint8_t *data, int len)
  86.481 +{
  86.482 +    USBHubPort *port;
  86.483 +    USBDevice *dev;
  86.484 +    int i, ret;
  86.485 +
  86.486 +    for(i = 0; i < s->nb_ports; i++) {
  86.487 +        port = &s->ports[i];
  86.488 +        dev = port->port.dev;
  86.489 +        if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
  86.490 +            ret = dev->handle_packet(dev, pid, 
  86.491 +                                     devaddr, devep,
  86.492 +                                     data, len);
  86.493 +            if (ret != USB_RET_NODEV) {
  86.494 +                return ret;
  86.495 +            }
  86.496 +        }
  86.497 +    }
  86.498 +    return USB_RET_NODEV;
  86.499 +}
  86.500 +
  86.501 +static int usb_hub_handle_packet(USBDevice *dev, int pid, 
  86.502 +                                 uint8_t devaddr, uint8_t devep,
  86.503 +                                 uint8_t *data, int len)
  86.504 +{
  86.505 +    USBHubState *s = (USBHubState *)dev;
  86.506 +
  86.507 +#if defined(DEBUG) && 0
  86.508 +    printf("usb_hub: pid=0x%x\n", pid);
  86.509 +#endif
  86.510 +    if (dev->state == USB_STATE_DEFAULT &&
  86.511 +        dev->addr != 0 &&
  86.512 +        devaddr != dev->addr &&
  86.513 +        (pid == USB_TOKEN_SETUP || 
  86.514 +         pid == USB_TOKEN_OUT || 
  86.515 +         pid == USB_TOKEN_IN)) {
  86.516 +        /* broadcast the packet to the devices */
  86.517 +        return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
  86.518 +    }
  86.519 +    return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
  86.520 +}
  86.521 +
  86.522 +USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports)
  86.523 +{
  86.524 +    USBHubState *s;
  86.525 +    USBHubPort *port;
  86.526 +    int i;
  86.527 +
  86.528 +    if (nb_ports > MAX_PORTS)
  86.529 +        return NULL;
  86.530 +    s = qemu_mallocz(sizeof(USBHubState));
  86.531 +    if (!s)
  86.532 +        return NULL;
  86.533 +    s->dev.speed = USB_SPEED_FULL;
  86.534 +    s->dev.handle_packet = usb_hub_handle_packet;
  86.535 +
  86.536 +    /* generic USB device init */
  86.537 +    s->dev.handle_reset = usb_hub_handle_reset;
  86.538 +    s->dev.handle_control = usb_hub_handle_control;
  86.539 +    s->dev.handle_data = usb_hub_handle_data;
  86.540 +
  86.541 +    s->nb_ports = nb_ports;
  86.542 +    for(i = 0; i < s->nb_ports; i++) {
  86.543 +        port = &s->ports[i];
  86.544 +        port->wPortStatus = PORT_STAT_POWER;
  86.545 +        port->wPortChange = 0;
  86.546 +        port->port.attach = usb_hub_attach;
  86.547 +        port->port.opaque = s;
  86.548 +        port->port.index = i;
  86.549 +        usb_ports[i] = &port->port;
  86.550 +    }
  86.551 +    return (USBDevice *)s;
  86.552 +}
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/tools/ioemu/hw/usb-uhci.c	Tue Jun 13 12:12:24 2006 -0600
    87.3 @@ -0,0 +1,680 @@
    87.4 +/*
    87.5 + * USB UHCI controller emulation
    87.6 + * 
    87.7 + * Copyright (c) 2005 Fabrice Bellard
    87.8 + * 
    87.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   87.10 + * of this software and associated documentation files (the "Software"), to deal
   87.11 + * in the Software without restriction, including without limitation the rights
   87.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   87.13 + * copies of the Software, and to permit persons to whom the Software is
   87.14 + * furnished to do so, subject to the following conditions:
   87.15 + *
   87.16 + * The above copyright notice and this permission notice shall be included in
   87.17 + * all copies or substantial portions of the Software.
   87.18 + *
   87.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   87.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   87.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   87.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   87.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   87.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   87.25 + * THE SOFTWARE.
   87.26 + */
   87.27 +#include "vl.h"
   87.28 +
   87.29 +//#define DEBUG
   87.30 +//#define DEBUG_PACKET
   87.31 +
   87.32 +#define UHCI_CMD_GRESET   (1 << 2)
   87.33 +#define UHCI_CMD_HCRESET  (1 << 1)
   87.34 +#define UHCI_CMD_RS       (1 << 0)
   87.35 +
   87.36 +#define UHCI_STS_HCHALTED (1 << 5)
   87.37 +#define UHCI_STS_HCPERR   (1 << 4)
   87.38 +#define UHCI_STS_HSERR    (1 << 3)
   87.39 +#define UHCI_STS_RD       (1 << 2)
   87.40 +#define UHCI_STS_USBERR   (1 << 1)
   87.41 +#define UHCI_STS_USBINT   (1 << 0)
   87.42 +
   87.43 +#define TD_CTRL_SPD     (1 << 29)
   87.44 +#define TD_CTRL_ERROR_SHIFT  27
   87.45 +#define TD_CTRL_IOS     (1 << 25)
   87.46 +#define TD_CTRL_IOC     (1 << 24)
   87.47 +#define TD_CTRL_ACTIVE  (1 << 23)
   87.48 +#define TD_CTRL_STALL   (1 << 22)
   87.49 +#define TD_CTRL_BABBLE  (1 << 20)
   87.50 +#define TD_CTRL_NAK     (1 << 19)
   87.51 +#define TD_CTRL_TIMEOUT (1 << 18)
   87.52 +
   87.53 +#define UHCI_PORT_RESET (1 << 9)
   87.54 +#define UHCI_PORT_LSDA  (1 << 8)
   87.55 +#define UHCI_PORT_ENC   (1 << 3)
   87.56 +#define UHCI_PORT_EN    (1 << 2)
   87.57 +#define UHCI_PORT_CSC   (1 << 1)
   87.58 +#define UHCI_PORT_CCS   (1 << 0)
   87.59 +
   87.60 +#define FRAME_TIMER_FREQ 1000
   87.61 +
   87.62 +#define FRAME_MAX_LOOPS  100
   87.63 +
   87.64 +#define NB_PORTS 2
   87.65 +
   87.66 +typedef struct UHCIPort {
   87.67 +    USBPort port;
   87.68 +    uint16_t ctrl;
   87.69 +} UHCIPort;
   87.70 +
   87.71 +typedef struct UHCIState {
   87.72 +    PCIDevice dev;
   87.73 +    uint16_t cmd; /* cmd register */
   87.74 +    uint16_t status;
   87.75 +    uint16_t intr; /* interrupt enable register */
   87.76 +    uint16_t frnum; /* frame number */
   87.77 +    uint32_t fl_base_addr; /* frame list base address */
   87.78 +    uint8_t sof_timing;
   87.79 +    uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
   87.80 +    QEMUTimer *frame_timer;
   87.81 +    UHCIPort ports[NB_PORTS];
   87.82 +} UHCIState;
   87.83 +
   87.84 +typedef struct UHCI_TD {
   87.85 +    uint32_t link;
   87.86 +    uint32_t ctrl; /* see TD_CTRL_xxx */
   87.87 +    uint32_t token;
   87.88 +    uint32_t buffer;
   87.89 +} UHCI_TD;
   87.90 +
   87.91 +typedef struct UHCI_QH {
   87.92 +    uint32_t link;
   87.93 +    uint32_t el_link;
   87.94 +} UHCI_QH;
   87.95 +
   87.96 +static void uhci_attach(USBPort *port1, USBDevice *dev);
   87.97 +
   87.98 +static void uhci_update_irq(UHCIState *s)
   87.99 +{
  87.100 +    int level;
  87.101 +    if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
  87.102 +        ((s->status2 & 2) && (s->intr & (1 << 3))) ||
  87.103 +        ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
  87.104 +        ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
  87.105 +        (s->status & UHCI_STS_HSERR) ||
  87.106 +        (s->status & UHCI_STS_HCPERR)) {
  87.107 +        level = 1;
  87.108 +    } else {
  87.109 +        level = 0;
  87.110 +    }
  87.111 +    pci_set_irq(&s->dev, 3, level);
  87.112 +}
  87.113 +
  87.114 +static void uhci_reset(UHCIState *s)
  87.115 +{
  87.116 +    uint8_t *pci_conf;
  87.117 +    int i;
  87.118 +    UHCIPort *port;
  87.119 +
  87.120 +    pci_conf = s->dev.config;
  87.121 +
  87.122 +    pci_conf[0x6a] = 0x01; /* usb clock */
  87.123 +    pci_conf[0x6b] = 0x00;
  87.124 +    s->cmd = 0;
  87.125 +    s->status = 0;
  87.126 +    s->status2 = 0;
  87.127 +    s->intr = 0;
  87.128 +    s->fl_base_addr = 0;
  87.129 +    s->sof_timing = 64;
  87.130 +    for(i = 0; i < NB_PORTS; i++) {
  87.131 +        port = &s->ports[i];
  87.132 +        port->ctrl = 0x0080;
  87.133 +        if (port->port.dev)
  87.134 +            uhci_attach(&port->port, port->port.dev);
  87.135 +    }
  87.136 +}
  87.137 +
  87.138 +static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
  87.139 +{
  87.140 +    UHCIState *s = opaque;
  87.141 +    
  87.142 +    addr &= 0x1f;
  87.143 +    switch(addr) {
  87.144 +    case 0x0c:
  87.145 +        s->sof_timing = val;
  87.146 +        break;
  87.147 +    }
  87.148 +}
  87.149 +
  87.150 +static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
  87.151 +{
  87.152 +    UHCIState *s = opaque;
  87.153 +    uint32_t val;
  87.154 +
  87.155 +    addr &= 0x1f;
  87.156 +    switch(addr) {
  87.157 +    case 0x0c:
  87.158 +        val = s->sof_timing;
  87.159 +        break;
  87.160 +    default:
  87.161 +        val = 0xff;
  87.162 +        break;
  87.163 +    }
  87.164 +    return val;
  87.165 +}
  87.166 +
  87.167 +static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
  87.168 +{
  87.169 +    UHCIState *s = opaque;
  87.170 +    
  87.171 +    addr &= 0x1f;
  87.172 +#ifdef DEBUG
  87.173 +    printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
  87.174 +#endif
  87.175 +    switch(addr) {
  87.176 +    case 0x00:
  87.177 +        if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
  87.178 +            /* start frame processing */
  87.179 +            qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
  87.180 +            s->status &= ~UHCI_STS_HCHALTED;
  87.181 +        } else if (!(val & UHCI_CMD_RS)) {
  87.182 +            s->status |= UHCI_STS_HCHALTED;
  87.183 +        }
  87.184 +        if (val & UHCI_CMD_GRESET) {
  87.185 +            UHCIPort *port;
  87.186 +            USBDevice *dev;
  87.187 +            int i;
  87.188 +
  87.189 +            /* send reset on the USB bus */
  87.190 +            for(i = 0; i < NB_PORTS; i++) {
  87.191 +                port = &s->ports[i];
  87.192 +                dev = port->port.dev;
  87.193 +                if (dev) {
  87.194 +                    dev->handle_packet(dev, 
  87.195 +                                       USB_MSG_RESET, 0, 0, NULL, 0);
  87.196 +                }
  87.197 +            }
  87.198 +            uhci_reset(s);
  87.199 +            return;
  87.200 +        }
  87.201 +        if (val & UHCI_CMD_HCRESET) {
  87.202 +            uhci_reset(s);
  87.203 +            return;
  87.204 +        }
  87.205 +        s->cmd = val;
  87.206 +        break;
  87.207 +    case 0x02:
  87.208 +        s->status &= ~val;
  87.209 +        /* XXX: the chip spec is not coherent, so we add a hidden
  87.210 +           register to distinguish between IOC and SPD */
  87.211 +        if (val & UHCI_STS_USBINT)
  87.212 +            s->status2 = 0;
  87.213 +        uhci_update_irq(s);
  87.214 +        break;
  87.215 +    case 0x04:
  87.216 +        s->intr = val;
  87.217 +        uhci_update_irq(s);
  87.218 +        break;
  87.219 +    case 0x06:
  87.220 +        if (s->status & UHCI_STS_HCHALTED)
  87.221 +            s->frnum = val & 0x7ff;
  87.222 +        break;
  87.223 +    case 0x10 ... 0x1f:
  87.224 +        {
  87.225 +            UHCIPort *port;
  87.226 +            USBDevice *dev;
  87.227 +            int n;
  87.228 +
  87.229 +            n = (addr >> 1) & 7;
  87.230 +            if (n >= NB_PORTS)
  87.231 +                return;
  87.232 +            port = &s->ports[n];
  87.233 +            dev = port->port.dev;
  87.234 +            if (dev) {
  87.235 +                /* port reset */
  87.236 +                if ( (val & UHCI_PORT_RESET) && 
  87.237 +                     !(port->ctrl & UHCI_PORT_RESET) ) {
  87.238 +                    dev->handle_packet(dev, 
  87.239 +                                       USB_MSG_RESET, 0, 0, NULL, 0);
  87.240 +                }
  87.241 +            }
  87.242 +            port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
  87.243 +            /* some bits are reset when a '1' is written to them */
  87.244 +            port->ctrl &= ~(val & 0x000a);
  87.245 +        }
  87.246 +        break;
  87.247 +    }
  87.248 +}
  87.249 +
  87.250 +static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
  87.251 +{
  87.252 +    UHCIState *s = opaque;
  87.253 +    uint32_t val;
  87.254 +
  87.255 +    addr &= 0x1f;
  87.256 +    switch(addr) {
  87.257 +    case 0x00:
  87.258 +        val = s->cmd;
  87.259 +        break;
  87.260 +    case 0x02:
  87.261 +        val = s->status;
  87.262 +        break;
  87.263 +    case 0x04:
  87.264 +        val = s->intr;
  87.265 +        break;
  87.266 +    case 0x06:
  87.267 +        val = s->frnum;
  87.268 +        break;
  87.269 +    case 0x10 ... 0x1f:
  87.270 +        {
  87.271 +            UHCIPort *port;
  87.272 +            int n;
  87.273 +            n = (addr >> 1) & 7;
  87.274 +            if (n >= NB_PORTS) 
  87.275 +                goto read_default;
  87.276 +            port = &s->ports[n];
  87.277 +            val = port->ctrl;
  87.278 +        }
  87.279 +        break;
  87.280 +    default:
  87.281 +    read_default:
  87.282 +        val = 0xff7f; /* disabled port */
  87.283 +        break;
  87.284 +    }
  87.285 +#ifdef DEBUG
  87.286 +    printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
  87.287 +#endif
  87.288 +    return val;
  87.289 +}
  87.290 +
  87.291 +static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
  87.292 +{
  87.293 +    UHCIState *s = opaque;
  87.294 +
  87.295 +    addr &= 0x1f;
  87.296 +#ifdef DEBUG
  87.297 +    printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
  87.298 +#endif
  87.299 +    switch(addr) {
  87.300 +    case 0x08:
  87.301 +        s->fl_base_addr = val & ~0xfff;
  87.302 +        break;
  87.303 +    }
  87.304 +}
  87.305 +
  87.306 +static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
  87.307 +{
  87.308 +    UHCIState *s = opaque;
  87.309 +    uint32_t val;
  87.310 +
  87.311 +    addr &= 0x1f;
  87.312 +    switch(addr) {
  87.313 +    case 0x08:
  87.314 +        val = s->fl_base_addr;
  87.315 +        break;
  87.316 +    default:
  87.317 +        val = 0xffffffff;
  87.318 +        break;
  87.319 +    }
  87.320 +    return val;
  87.321 +}
  87.322 +
  87.323 +static void uhci_attach(USBPort *port1, USBDevice *dev)
  87.324 +{
  87.325 +    UHCIState *s = port1->opaque;
  87.326 +    UHCIPort *port = &s->ports[port1->index];
  87.327 +
  87.328 +    if (dev) {
  87.329 +        if (port->port.dev) {
  87.330 +            usb_attach(port1, NULL);
  87.331 +        }
  87.332 +        /* set connect status */
  87.333 +        if (!(port->ctrl & UHCI_PORT_CCS)) {
  87.334 +            port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
  87.335 +        }
  87.336 +        /* update speed */
  87.337 +        if (dev->speed == USB_SPEED_LOW)
  87.338 +            port->ctrl |= UHCI_PORT_LSDA;
  87.339 +        else
  87.340 +            port->ctrl &= ~UHCI_PORT_LSDA;
  87.341 +        port->port.dev = dev;
  87.342 +        /* send the attach message */
  87.343 +        dev->handle_packet(dev, 
  87.344 +                           USB_MSG_ATTACH, 0, 0, NULL, 0);
  87.345 +    } else {
  87.346 +        /* set connect status */
  87.347 +        if (!(port->ctrl & UHCI_PORT_CCS)) {
  87.348 +            port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
  87.349 +        }
  87.350 +        /* disable port */
  87.351 +        if (port->ctrl & UHCI_PORT_EN) {
  87.352 +            port->ctrl &= ~UHCI_PORT_EN;
  87.353 +            port->ctrl |= UHCI_PORT_ENC;
  87.354 +        }
  87.355 +        dev = port->port.dev;
  87.356 +        if (dev) {
  87.357 +            /* send the detach message */
  87.358 +            dev->handle_packet(dev, 
  87.359 +                               USB_MSG_DETACH, 0, 0, NULL, 0);
  87.360 +        }
  87.361 +        port->port.dev = NULL;
  87.362 +    }
  87.363 +}
  87.364 +
  87.365 +static int uhci_broadcast_packet(UHCIState *s, uint8_t pid, 
  87.366 +                                 uint8_t devaddr, uint8_t devep,
  87.367 +                                 uint8_t *data, int len)
  87.368 +{
  87.369 +    UHCIPort *port;
  87.370 +    USBDevice *dev;
  87.371 +    int i, ret;
  87.372 +
  87.373 +#ifdef DEBUG_PACKET
  87.374 +    {
  87.375 +        const char *pidstr;
  87.376 +        switch(pid) {
  87.377 +        case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
  87.378 +        case USB_TOKEN_IN: pidstr = "IN"; break;
  87.379 +        case USB_TOKEN_OUT: pidstr = "OUT"; break;
  87.380 +        default: pidstr = "?"; break;
  87.381 +        }
  87.382 +        printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
  87.383 +               s->frnum, pidstr, devaddr, devep, len);
  87.384 +        if (pid != USB_TOKEN_IN) {
  87.385 +            printf("     data_out=");
  87.386 +            for(i = 0; i < len; i++) {
  87.387 +                printf(" %02x", data[i]);
  87.388 +            }
  87.389 +            printf("\n");
  87.390 +        }
  87.391 +    }
  87.392 +#endif
  87.393 +    for(i = 0; i < NB_PORTS; i++) {
  87.394 +        port = &s->ports[i];
  87.395 +        dev = port->port.dev;
  87.396 +        if (dev && (port->ctrl & UHCI_PORT_EN)) {
  87.397 +            ret = dev->handle_packet(dev, pid, 
  87.398 +                                     devaddr, devep,
  87.399 +                                     data, len);
  87.400 +            if (ret != USB_RET_NODEV) {
  87.401 +#ifdef DEBUG_PACKET
  87.402 +                {
  87.403 +                    printf("     ret=%d ", ret);
  87.404 +                    if (pid == USB_TOKEN_IN && ret > 0) {
  87.405 +                        printf("data_in=");
  87.406 +                        for(i = 0; i < ret; i++) {
  87.407 +                            printf(" %02x", data[i]);
  87.408 +                        }
  87.409 +                    }
  87.410 +                    printf("\n");
  87.411 +                }
  87.412 +#endif
  87.413 +                return ret;
  87.414 +            }
  87.415 +        }
  87.416 +    }
  87.417 +    return USB_RET_NODEV;
  87.418 +}
  87.419 +
  87.420 +/* return -1 if fatal error (frame must be stopped)
  87.421 +          0 if TD successful
  87.422 +          1 if TD unsuccessful or inactive
  87.423 +*/
  87.424 +static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
  87.425 +{
  87.426 +    uint8_t pid;
  87.427 +    uint8_t buf[1280];
  87.428 +    int len, max_len, err, ret;
  87.429 +
  87.430 +    if (td->ctrl & TD_CTRL_IOC) {
  87.431 +        *int_mask |= 0x01;
  87.432 +    }
  87.433 +    
  87.434 +    if (!(td->ctrl & TD_CTRL_ACTIVE))
  87.435 +        return 1;
  87.436 +
  87.437 +    /* TD is active */
  87.438 +    max_len = ((td->token >> 21) + 1) & 0x7ff;
  87.439 +    pid = td->token & 0xff;
  87.440 +    switch(pid) {
  87.441 +    case USB_TOKEN_OUT:
  87.442 +    case USB_TOKEN_SETUP:
  87.443 +        cpu_physical_memory_read(td->buffer, buf, max_len);
  87.444 +        ret = uhci_broadcast_packet(s, pid, 
  87.445 +                                    (td->token >> 8) & 0x7f,
  87.446 +                                    (td->token >> 15) & 0xf,
  87.447 +                                    buf, max_len);
  87.448 +        len = max_len;
  87.449 +        break;
  87.450 +    case USB_TOKEN_IN:
  87.451 +        ret = uhci_broadcast_packet(s, pid, 
  87.452 +                                    (td->token >> 8) & 0x7f,
  87.453 +                                    (td->token >> 15) & 0xf,
  87.454 +                                    buf, max_len);
  87.455 +        if (ret >= 0) {
  87.456 +            len = ret;
  87.457 +            if (len > max_len) {
  87.458 +                len = max_len;
  87.459 +                ret = USB_RET_BABBLE;
  87.460 +            }
  87.461 +            if (len > 0) {
  87.462 +                /* write the data back */
  87.463 +                cpu_physical_memory_write(td->buffer, buf, len);
  87.464 +            }
  87.465 +        } else {
  87.466 +            len = 0;
  87.467 +        }
  87.468 +        break;
  87.469 +    default:
  87.470 +        /* invalid pid : frame interrupted */
  87.471 +        s->status |= UHCI_STS_HCPERR;
  87.472 +        uhci_update_irq(s);
  87.473 +        return -1;
  87.474 +    }
  87.475 +    if (td->ctrl & TD_CTRL_IOS)
  87.476 +        td->ctrl &= ~TD_CTRL_ACTIVE;
  87.477 +    if (ret >= 0) {
  87.478 +        td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
  87.479 +        td->ctrl &= ~TD_CTRL_ACTIVE;
  87.480 +        if (pid == USB_TOKEN_IN && 
  87.481 +            (td->ctrl & TD_CTRL_SPD) &&
  87.482 +            len < max_len) {
  87.483 +            *int_mask |= 0x02;
  87.484 +            /* short packet: do not update QH */
  87.485 +            return 1;
  87.486 +        } else {
  87.487 +            /* success */
  87.488 +            return 0;
  87.489 +        }
  87.490 +    } else {
  87.491 +        switch(ret) {
  87.492 +        default:
  87.493 +        case USB_RET_NODEV:
  87.494 +        do_timeout:
  87.495 +            td->ctrl |= TD_CTRL_TIMEOUT;
  87.496 +            err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
  87.497 +            if (err != 0) {
  87.498 +                err--;
  87.499 +                if (err == 0) {
  87.500 +                    td->ctrl &= ~TD_CTRL_ACTIVE;
  87.501 +                    s->status |= UHCI_STS_USBERR;
  87.502 +                    uhci_update_irq(s);
  87.503 +                }
  87.504 +            }
  87.505 +            td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) | 
  87.506 +                (err << TD_CTRL_ERROR_SHIFT);
  87.507 +            return 1;
  87.508 +        case USB_RET_NAK:
  87.509 +            td->ctrl |= TD_CTRL_NAK;
  87.510 +            if (pid == USB_TOKEN_SETUP)
  87.511 +                goto do_timeout;
  87.512 +            return 1;
  87.513 +        case USB_RET_STALL:
  87.514 +            td->ctrl |= TD_CTRL_STALL;
  87.515 +            td->ctrl &= ~TD_CTRL_ACTIVE;
  87.516 +            return 1;
  87.517 +        case USB_RET_BABBLE:
  87.518 +            td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
  87.519 +            td->ctrl &= ~TD_CTRL_ACTIVE;
  87.520 +            /* frame interrupted */
  87.521 +            return -1;
  87.522 +        }
  87.523 +    }
  87.524 +}
  87.525 +
  87.526 +static void uhci_frame_timer(void *opaque)
  87.527 +{
  87.528 +    UHCIState *s = opaque;
  87.529 +    int64_t expire_time;
  87.530 +    uint32_t frame_addr, link, old_td_ctrl, val;
  87.531 +    int int_mask, cnt, ret;
  87.532 +    UHCI_TD td;
  87.533 +    UHCI_QH qh;
  87.534 +
  87.535 +    if (!(s->cmd & UHCI_CMD_RS)) {
  87.536 +        qemu_del_timer(s->frame_timer);
  87.537 +        /* set hchalted bit in status - UHCI11D 2.1.2 */
  87.538 +        s->status |= UHCI_STS_HCHALTED;
  87.539 +        return;
  87.540 +    }
  87.541 +    frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
  87.542 +    cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
  87.543 +    le32_to_cpus(&link);
  87.544 +    int_mask = 0;
  87.545 +    cnt = FRAME_MAX_LOOPS;
  87.546 +    while ((link & 1) == 0) {
  87.547 +        if (--cnt == 0)
  87.548 +            break;
  87.549 +        /* valid frame */
  87.550 +        if (link & 2) {
  87.551 +            /* QH */
  87.552 +            cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
  87.553 +            le32_to_cpus(&qh.link);
  87.554 +            le32_to_cpus(&qh.el_link);
  87.555 +        depth_first:
  87.556 +            if (qh.el_link & 1) {
  87.557 +                /* no element : go to next entry */
  87.558 +                link = qh.link;
  87.559 +            } else if (qh.el_link & 2) {
  87.560 +                /* QH */
  87.561 +                link = qh.el_link;
  87.562 +            } else {
  87.563 +                /* TD */
  87.564 +                if (--cnt == 0)
  87.565 +                    break;
  87.566 +                cpu_physical_memory_read(qh.el_link & ~0xf, 
  87.567 +                                         (uint8_t *)&td, sizeof(td));
  87.568 +                le32_to_cpus(&td.link);
  87.569 +                le32_to_cpus(&td.ctrl);
  87.570 +                le32_to_cpus(&td.token);
  87.571 +                le32_to_cpus(&td.buffer);
  87.572 +                old_td_ctrl = td.ctrl;
  87.573 +                ret = uhci_handle_td(s, &td, &int_mask);
  87.574 +                /* update the status bits of the TD */
  87.575 +                if (old_td_ctrl != td.ctrl) {
  87.576 +                    val = cpu_to_le32(td.ctrl);
  87.577 +                    cpu_physical_memory_write((qh.el_link & ~0xf) + 4, 
  87.578 +                                              (const uint8_t *)&val, 
  87.579 +                                              sizeof(val));
  87.580 +                }
  87.581 +                if (ret < 0)
  87.582 +                    break; /* interrupted frame */
  87.583 +                if (ret == 0) {
  87.584 +                    /* update qh element link */
  87.585 +                    qh.el_link = td.link;
  87.586 +                    val = cpu_to_le32(qh.el_link);
  87.587 +                    cpu_physical_memory_write((link & ~0xf) + 4, 
  87.588 +                                              (const uint8_t *)&val, 
  87.589 +                                              sizeof(val));
  87.590 +                    if (qh.el_link & 4) {
  87.591 +                        /* depth first */
  87.592 +                        goto depth_first;
  87.593 +                    }
  87.594 +                }
  87.595 +                /* go to next entry */
  87.596 +                link = qh.link;
  87.597 +            }
  87.598 +        } else {
  87.599 +            /* TD */
  87.600 +            cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
  87.601 +            le32_to_cpus(&td.link);
  87.602 +            le32_to_cpus(&td.ctrl);
  87.603 +            le32_to_cpus(&td.token);
  87.604 +            le32_to_cpus(&td.buffer);
  87.605 +            old_td_ctrl = td.ctrl;
  87.606 +            ret = uhci_handle_td(s, &td, &int_mask);
  87.607 +            /* update the status bits of the TD */
  87.608 +            if (old_td_ctrl != td.ctrl) {
  87.609 +                val = cpu_to_le32(td.ctrl);
  87.610 +                cpu_physical_memory_write((link & ~0xf) + 4, 
  87.611 +                                          (const uint8_t *)&val, 
  87.612 +                                          sizeof(val));
  87.613 +            }
  87.614 +            if (ret < 0)
  87.615 +                break; /* interrupted frame */
  87.616 +            link = td.link;
  87.617 +        }
  87.618 +    }
  87.619 +    s->frnum = (s->frnum + 1) & 0x7ff;
  87.620 +    if (int_mask) {
  87.621 +        s->status2 |= int_mask;
  87.622 +        s->status |= UHCI_STS_USBINT;
  87.623 +        uhci_update_irq(s);
  87.624 +    }
  87.625 +    /* prepare the timer for the next frame */
  87.626 +    expire_time = qemu_get_clock(vm_clock) + 
  87.627 +        (ticks_per_sec / FRAME_TIMER_FREQ);
  87.628 +    qemu_mod_timer(s->frame_timer, expire_time);
  87.629 +}
  87.630 +
  87.631 +static void uhci_map(PCIDevice *pci_dev, int region_num, 
  87.632 +                    uint32_t addr, uint32_t size, int type)
  87.633 +{
  87.634 +    UHCIState *s = (UHCIState *)pci_dev;
  87.635 +
  87.636 +    register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
  87.637 +    register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
  87.638 +    register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
  87.639 +    register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
  87.640 +    register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
  87.641 +    register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
  87.642 +}
  87.643 +
  87.644 +void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
  87.645 +{
  87.646 +    UHCIState *s;
  87.647 +    uint8_t *pci_conf;
  87.648 +    UHCIPort *port;
  87.649 +    int i;
  87.650 +
  87.651 +    s = (UHCIState *)pci_register_device(bus,
  87.652 +                                        "USB-UHCI", sizeof(UHCIState),
  87.653 +                                        ((PCIDevice *)piix3_state)->devfn + 2, 
  87.654 +                                        NULL, NULL);
  87.655 +    pci_conf = s->dev.config;
  87.656 +    pci_conf[0x00] = 0x86;
  87.657 +    pci_conf[0x01] = 0x80;
  87.658 +    pci_conf[0x02] = 0x20;
  87.659 +    pci_conf[0x03] = 0x70;
  87.660 +    pci_conf[0x08] = 0x01; // revision number
  87.661 +    pci_conf[0x09] = 0x00;
  87.662 +    pci_conf[0x0a] = 0x03;
  87.663 +    pci_conf[0x0b] = 0x0c;
  87.664 +    pci_conf[0x0e] = 0x00; // header_type
  87.665 +    pci_conf[0x3d] = 4; // interrupt pin 3
  87.666 +    pci_conf[0x60] = 0x10; // release number
  87.667 +    
  87.668 +    for(i = 0; i < NB_PORTS; i++) {
  87.669 +        port = &s->ports[i];
  87.670 +        port->port.opaque = s;
  87.671 +        port->port.index = i;
  87.672 +        port->port.attach = uhci_attach;
  87.673 +        usb_ports[i] = &port->port;
  87.674 +    }
  87.675 +    s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
  87.676 +
  87.677 +    uhci_reset(s);
  87.678 +
  87.679 +    /* Use region 4 for consistency with real hardware.  BSD guests seem
  87.680 +       to rely on this.  */
  87.681 +    pci_register_io_region(&s->dev, 4, 0x20, 
  87.682 +                           PCI_ADDRESS_SPACE_IO, uhci_map);
  87.683 +}
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/tools/ioemu/hw/usb.c	Tue Jun 13 12:12:24 2006 -0600
    88.3 @@ -0,0 +1,193 @@
    88.4 +/*
    88.5 + * QEMU USB emulation
    88.6 + *
    88.7 + * Copyright (c) 2005 Fabrice Bellard
    88.8 + * 
    88.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   88.10 + * of this software and associated documentation files (the "Software"), to deal
   88.11 + * in the Software without restriction, including without limitation the rights
   88.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   88.13 + * copies of the Software, and to permit persons to whom the Software is
   88.14 + * furnished to do so, subject to the following conditions:
   88.15 + *
   88.16 + * The above copyright notice and this permission notice shall be included in
   88.17 + * all copies or substantial portions of the Software.
   88.18 + *
   88.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   88.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   88.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   88.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   88.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   88.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   88.25 + * THE SOFTWARE.
   88.26 + */
   88.27 +#include "vl.h"
   88.28 +
   88.29 +void usb_attach(USBPort *port, USBDevice *dev)
   88.30 +{
   88.31 +    port->attach(port, dev);
   88.32 +}
   88.33 +
   88.34 +/**********************/
   88.35 +/* generic USB device helpers (you are not forced to use them when
   88.36 +   writing your USB device driver, but they help handling the
   88.37 +   protocol) 
   88.38 +*/
   88.39 +
   88.40 +#define SETUP_STATE_IDLE 0
   88.41 +#define SETUP_STATE_DATA 1
   88.42 +#define SETUP_STATE_ACK  2
   88.43 +
   88.44 +int usb_generic_handle_packet(USBDevice *s, int pid, 
   88.45 +                              uint8_t devaddr, uint8_t devep,
   88.46 +                              uint8_t *data, int len)
   88.47 +{
   88.48 +    int l, ret = 0;
   88.49 +
   88.50 +    switch(pid) {
   88.51 +    case USB_MSG_ATTACH:
   88.52 +        s->state = USB_STATE_ATTACHED;
   88.53 +        break;
   88.54 +    case USB_MSG_DETACH:
   88.55 +        s->state = USB_STATE_NOTATTACHED;
   88.56 +        break;
   88.57 +    case USB_MSG_RESET:
   88.58 +        s->remote_wakeup = 0;
   88.59 +        s->addr = 0;
   88.60 +        s->state = USB_STATE_DEFAULT;
   88.61 +        s->handle_reset(s);
   88.62 +        break;
   88.63 +    case USB_TOKEN_SETUP:
   88.64 +        if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
   88.65 +            return USB_RET_NODEV;
   88.66 +        if (len != 8)
   88.67 +            goto fail;
   88.68 +        memcpy(s->setup_buf, data, 8);
   88.69 +        s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
   88.70 +        s->setup_index = 0;
   88.71 +        if (s->setup_buf[0] & USB_DIR_IN) {
   88.72 +            ret = s->handle_control(s, 
   88.73 +                                    (s->setup_buf[0] << 8) | s->setup_buf[1],
   88.74 +                                    (s->setup_buf[3] << 8) | s->setup_buf[2],
   88.75 +                                    (s->setup_buf[5] << 8) | s->setup_buf[4],
   88.76 +                                    s->setup_len,
   88.77 +                                    s->data_buf);
   88.78 +            if (ret < 0)
   88.79 +                return ret;
   88.80 +            if (ret < s->setup_len)
   88.81 +                s->setup_len = ret;
   88.82 +            s->setup_state = SETUP_STATE_DATA;
   88.83 +        } else {
   88.84 +            if (s->setup_len == 0)
   88.85 +                s->setup_state = SETUP_STATE_ACK;
   88.86 +            else
   88.87 +                s->setup_state = SETUP_STATE_DATA;
   88.88 +        }
   88.89 +        break;
   88.90 +    case USB_TOKEN_IN:
   88.91 +        if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
   88.92 +            return USB_RET_NODEV;
   88.93 +        switch(devep) {
   88.94 +        case 0:
   88.95 +            switch(s->setup_state) {
   88.96 +            case SETUP_STATE_ACK:
   88.97 +                if (!(s->setup_buf[0] & USB_DIR_IN)) {
   88.98 +                    s->setup_state = SETUP_STATE_IDLE;
   88.99 +                    ret = s->handle_control(s, 
  88.100 +                                      (s->setup_buf[0] << 8) | s->setup_buf[1],
  88.101 +                                      (s->setup_buf[3] << 8) | s->setup_buf[2],
  88.102 +                                      (s->setup_buf[5] << 8) | s->setup_buf[4],
  88.103 +                                      s->setup_len,
  88.104 +                                      s->data_buf);
  88.105 +                    if (ret > 0)
  88.106 +                        ret = 0;
  88.107 +                } else {
  88.108 +                    /* return 0 byte */
  88.109 +                }
  88.110 +                break;
  88.111 +            case SETUP_STATE_DATA:
  88.112 +                if (s->setup_buf[0] & USB_DIR_IN) {
  88.113 +                    l = s->setup_len - s->setup_index;
  88.114 +                    if (l > len)
  88.115 +                        l = len;
  88.116 +                    memcpy(data, s->data_buf + s->setup_index, l);
  88.117 +                    s->setup_index += l;
  88.118 +                    if (s->setup_index >= s->setup_len)
  88.119 +                        s->setup_state = SETUP_STATE_ACK;
  88.120 +                    ret = l;
  88.121 +                } else {
  88.122 +                    s->setup_state = SETUP_STATE_IDLE;
  88.123 +                    goto fail;
  88.124 +                }
  88.125 +                break;
  88.126 +            default:
  88.127 +                goto fail;
  88.128 +            }
  88.129 +            break;
  88.130 +        default:
  88.131 +            ret = s->handle_data(s, pid, devep, data, len);
  88.132 +            break;
  88.133 +        }
  88.134 +        break;
  88.135 +    case USB_TOKEN_OUT:
  88.136 +        if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
  88.137 +            return USB_RET_NODEV;
  88.138 +        switch(devep) {
  88.139 +        case 0:
  88.140 +            switch(s->setup_state) {
  88.141 +            case SETUP_STATE_ACK:
  88.142 +                if (s->setup_buf[0] & USB_DIR_IN) {
  88.143 +                    s->setup_state = SETUP_STATE_IDLE;
  88.144 +                    /* transfer OK */
  88.145 +                } else {
  88.146 +                    /* ignore additionnal output */
  88.147 +                }
  88.148 +                break;
  88.149 +            case SETUP_STATE_DATA:
  88.150 +                if (!(s->setup_buf[0] & USB_DIR_IN)) {
  88.151 +                    l = s->setup_len - s->setup_index;
  88.152 +                    if (l > len)
  88.153 +                        l = len;
  88.154 +                    memcpy(s->data_buf + s->setup_index, data, l);
  88.155 +                    s->setup_index += l;
  88.156 +                    if (s->setup_index >= s->setup_len)
  88.157 +                        s->setup_state = SETUP_STATE_ACK;
  88.158 +                    ret = l;
  88.159 +                } else {
  88.160 +                    s->setup_state = SETUP_STATE_IDLE;
  88.161 +                    goto fail;
  88.162 +                }
  88.163 +                break;
  88.164 +            default:
  88.165 +                goto fail;
  88.166 +            }
  88.167 +            break;
  88.168 +        default:
  88.169 +            ret = s->handle_data(s, pid, devep, data, len);
  88.170 +            break;
  88.171 +        }
  88.172 +        break;
  88.173 +    default:
  88.174 +    fail:
  88.175 +        ret = USB_RET_STALL;
  88.176 +        break;
  88.177 +    }
  88.178 +    return ret;
  88.179 +}
  88.180 +
  88.181 +/* XXX: fix overflow */
  88.182 +int set_usb_string(uint8_t *buf, const char *str)
  88.183 +{
  88.184 +    int len, i;
  88.185 +    uint8_t *q;
  88.186 +
  88.187 +    q = buf;
  88.188 +    len = strlen(str);
  88.189 +    *q++ = 2 * len + 2;
  88.190 +    *q++ = 3;
  88.191 +    for(i = 0; i < len; i++) {
  88.192 +        *q++ = str[i];
  88.193 +        *q++ = 0;
  88.194 +    }
  88.195 +    return q - buf;
  88.196 +}
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/tools/ioemu/hw/usb.h	Tue Jun 13 12:12:24 2006 -0600
    89.3 @@ -0,0 +1,166 @@
    89.4 +/*
    89.5 + * QEMU USB API
    89.6 + * 
    89.7 + * Copyright (c) 2005 Fabrice Bellard
    89.8 + * 
    89.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   89.10 + * of this software and associated documentation files (the "Software"), to deal
   89.11 + * in the Software without restriction, including without limitation the rights
   89.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   89.13 + * copies of the Software, and to permit persons to whom the Software is
   89.14 + * furnished to do so, subject to the following conditions:
   89.15 + *
   89.16 + * The above copyright notice and this permission notice shall be included in
   89.17 + * all copies or substantial portions of the Software.
   89.18 + *
   89.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   89.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   89.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   89.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   89.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   89.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   89.25 + * THE SOFTWARE.
   89.26 + */
   89.27 +#define USB_TOKEN_SETUP 0x2d
   89.28 +#define USB_TOKEN_IN    0x69 /* device -> host */
   89.29 +#define USB_TOKEN_OUT   0xe1 /* host -> device */
   89.30 +
   89.31 +/* specific usb messages, also sent in the 'pid' parameter */
   89.32 +#define USB_MSG_ATTACH   0x100
   89.33 +#define USB_MSG_DETACH   0x101
   89.34 +#define USB_MSG_RESET    0x102
   89.35 +
   89.36 +#define USB_RET_NODEV  (-1) 
   89.37 +#define USB_RET_NAK    (-2)
   89.38 +#define USB_RET_STALL  (-3)
   89.39 +#define USB_RET_BABBLE (-4)
   89.40 +
   89.41 +#define USB_SPEED_LOW   0
   89.42 +#define USB_SPEED_FULL  1
   89.43 +#define USB_SPEED_HIGH  2
   89.44 +
   89.45 +#define USB_STATE_NOTATTACHED 0
   89.46 +#define USB_STATE_ATTACHED    1
   89.47 +//#define USB_STATE_POWERED     2
   89.48 +#define USB_STATE_DEFAULT     3
   89.49 +//#define USB_STATE_ADDRESS     4
   89.50 +//#define	USB_STATE_CONFIGURED  5
   89.51 +#define USB_STATE_SUSPENDED   6
   89.52 +
   89.53 +#define USB_CLASS_AUDIO			1
   89.54 +#define USB_CLASS_COMM			2
   89.55 +#define USB_CLASS_HID			3
   89.56 +#define USB_CLASS_PHYSICAL		5
   89.57 +#define USB_CLASS_STILL_IMAGE		6
   89.58 +#define USB_CLASS_PRINTER		7
   89.59 +#define USB_CLASS_MASS_STORAGE		8
   89.60 +#define USB_CLASS_HUB			9
   89.61 +#define USB_CLASS_CDC_DATA		0x0a
   89.62 +#define USB_CLASS_CSCID			0x0b
   89.63 +#define USB_CLASS_CONTENT_SEC		0x0d
   89.64 +#define USB_CLASS_APP_SPEC		0xfe
   89.65 +#define USB_CLASS_VENDOR_SPEC		0xff
   89.66 +
   89.67 +#define USB_DIR_OUT			0
   89.68 +#define USB_DIR_IN			0x80
   89.69 +
   89.70 +#define USB_TYPE_MASK			(0x03 << 5)
   89.71 +#define USB_TYPE_STANDARD		(0x00 << 5)
   89.72 +#define USB_TYPE_CLASS			(0x01 << 5)
   89.73 +#define USB_TYPE_VENDOR			(0x02 << 5)
   89.74 +#define USB_TYPE_RESERVED		(0x03 << 5)
   89.75 +
   89.76 +#define USB_RECIP_MASK			0x1f
   89.77 +#define USB_RECIP_DEVICE		0x00
   89.78 +#define USB_RECIP_INTERFACE		0x01
   89.79 +#define USB_RECIP_ENDPOINT		0x02
   89.80 +#define USB_RECIP_OTHER			0x03
   89.81 +
   89.82 +#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
   89.83 +#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
   89.84 +#define InterfaceRequest \
   89.85 +        ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
   89.86 +#define InterfaceOutRequest \
   89.87 +        ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
   89.88 +#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
   89.89 +#define EndpointOutRequest \
   89.90 +        ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
   89.91 +
   89.92 +#define USB_REQ_GET_STATUS		0x00
   89.93 +#define USB_REQ_CLEAR_FEATURE		0x01
   89.94 +#define USB_REQ_SET_FEATURE		0x03
   89.95 +#define USB_REQ_SET_ADDRESS		0x05
   89.96 +#define USB_REQ_GET_DESCRIPTOR		0x06
   89.97 +#define USB_REQ_SET_DESCRIPTOR		0x07
   89.98 +#define USB_REQ_GET_CONFIGURATION	0x08
   89.99 +#define USB_REQ_SET_CONFIGURATION	0x09
  89.100 +#define USB_REQ_GET_INTERFACE		0x0A
  89.101 +#define USB_REQ_SET_INTERFACE		0x0B
  89.102 +#define USB_REQ_SYNCH_FRAME		0x0C
  89.103 +
  89.104 +#define USB_DEVICE_SELF_POWERED		0
  89.105 +#define USB_DEVICE_REMOTE_WAKEUP	1
  89.106 +
  89.107 +#define USB_DT_DEVICE			0x01
  89.108 +#define USB_DT_CONFIG			0x02
  89.109 +#define USB_DT_STRING			0x03
  89.110 +#define USB_DT_INTERFACE		0x04
  89.111 +#define USB_DT_ENDPOINT			0x05
  89.112 +
  89.113 +typedef struct USBPort USBPort;
  89.114 +typedef struct USBDevice USBDevice;
  89.115 +
  89.116 +/* definition of a USB device */
  89.117 +struct USBDevice {
  89.118 +    void *opaque;
  89.119 +    int (*handle_packet)(USBDevice *dev, int pid, 
  89.120 +                         uint8_t devaddr, uint8_t devep,
  89.121 +                         uint8_t *data, int len);
  89.122 +    int speed;
  89.123 +    
  89.124 +    /* The following fields are used by the generic USB device
  89.125 +       layer. They are here just to avoid creating a new structure for
  89.126 +       them. */
  89.127 +    void (*handle_reset)(USBDevice *dev);
  89.128 +    int (*handle_control)(USBDevice *dev, int request, int value,
  89.129 +                          int index, int length, uint8_t *data);
  89.130 +    int (*handle_data)(USBDevice *dev, int pid, uint8_t devep,
  89.131 +                       uint8_t *data, int len);
  89.132 +    uint8_t addr;
  89.133 +    
  89.134 +    int state;
  89.135 +    uint8_t setup_buf[8];
  89.136 +    uint8_t data_buf[1024];
  89.137 +    int remote_wakeup;
  89.138 +    int setup_state;
  89.139 +    int setup_len;
  89.140 +    int setup_index;
  89.141 +};
  89.142 +
  89.143 +/* USB port on which a device can be connected */
  89.144 +struct USBPort {
  89.145 +    USBDevice *dev;
  89.146 +    void (*attach)(USBPort *port, USBDevice *dev);
  89.147 +    void *opaque;
  89.148 +    int index; /* internal port index, may be used with the opaque */
  89.149 +};
  89.150 +
  89.151 +void usb_attach(USBPort *port, USBDevice *dev);
  89.152 +int usb_generic_handle_packet(USBDevice *s, int pid, 
  89.153 +                              uint8_t devaddr, uint8_t devep,
  89.154 +                              uint8_t *data, int len);
  89.155 +int set_usb_string(uint8_t *buf, const char *str);
  89.156 +
  89.157 +/* usb hub */
  89.158 +USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports);
  89.159 +
  89.160 +/* usb-uhci.c */
  89.161 +void usb_uhci_init(PCIBus *bus, USBPort **usb_ports);
  89.162 +
  89.163 +/* usb-linux.c */
  89.164 +USBDevice *usb_host_device_open(const char *devname);
  89.165 +void usb_host_info(void);
  89.166 +
  89.167 +/* usb-hid.c */
  89.168 +USBDevice *usb_mouse_init(void);
  89.169 +USBDevice *usb_tablet_init(void);
    90.1 --- a/tools/ioemu/hw/vga.c	Tue Jun 13 09:00:32 2006 -0600
    90.2 +++ b/tools/ioemu/hw/vga.c	Tue Jun 13 12:12:24 2006 -0600
    90.3 @@ -1995,6 +1995,7 @@ void vga_common_init(VGAState *s, Displa
    90.4      s->get_resolution = vga_get_resolution;
    90.5      /* XXX: currently needed for display */
    90.6      vga_state = s;
    90.7 +    vga_bios_init(s);
    90.8  }
    90.9  
   90.10  
   90.11 @@ -2082,7 +2083,6 @@ int vga_initialize(PCIBus *bus, DisplayS
   90.12  #endif
   90.13      }
   90.14  
   90.15 -    vga_bios_init(s);
   90.16      return 0;
   90.17  }
   90.18  
    91.1 --- a/tools/ioemu/monitor.c	Tue Jun 13 09:00:32 2006 -0600
    91.2 +++ b/tools/ioemu/monitor.c	Tue Jun 13 12:12:24 2006 -0600
    91.3 @@ -492,6 +492,10 @@ static term_cmd_t term_cmds[] = {
    91.4        "", "quit the emulator" },
    91.5      { "sendkey", "s", do_send_key, 
    91.6        "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
    91.7 +    { "usb_add", "s", do_usb_add,
    91.8 +      "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
    91.9 +    { "usb_del", "s", do_usb_del,
   91.10 +      "device", "remove USB device 'bus.addr'" },
   91.11      { NULL, NULL, }, 
   91.12  };
   91.13  
   91.14 @@ -510,6 +514,10 @@ static term_cmd_t info_cmds[] = {
   91.15        "", "show i8259 (PIC) state", },
   91.16      { "pci", "", pci_info,
   91.17        "", "show PCI info", },
   91.18 +    { "usb", "", usb_info,
   91.19 +      "", "show guest USB devices", },
   91.20 +    { "usbhost", "", usb_host_info,
   91.21 +      "", "show host USB devices", },
   91.22      { "hvmiopage", "", sp_info,
   91.23        "", "show HVM device model shared page info", },
   91.24      { NULL, NULL, },
    92.1 --- a/tools/ioemu/sdl.c	Tue Jun 13 09:00:32 2006 -0600
    92.2 +++ b/tools/ioemu/sdl.c	Tue Jun 13 12:12:24 2006 -0600
    92.3 @@ -49,8 +49,12 @@ static void* kbd_layout=0;
    92.4  static int gui_fullscreen_initial_grab;
    92.5  static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
    92.6  static uint8_t modifiers_state[256];
    92.7 +static int width, height;
    92.8 +static SDL_Cursor *sdl_cursor_normal;
    92.9 +static SDL_Cursor *sdl_cursor_hidden;
   92.10 +static int absolute_enabled = 0;
   92.11  
   92.12 -SDL_PixelFormat* sdl_get_format() {
   92.13 +SDL_PixelFormat* sdl_get_format(void) {
   92.14  	return screen->format;
   92.15  }
   92.16  
   92.17 @@ -69,6 +73,8 @@ static void sdl_resize(DisplayState *ds,
   92.18      flags |= SDL_RESIZABLE;
   92.19      if (gui_fullscreen)
   92.20          flags |= SDL_FULLSCREEN;
   92.21 +    width = w;
   92.22 +    height = h;
   92.23      screen = SDL_SetVideoMode(w, h, 0, flags);
   92.24      if (!screen) {
   92.25          fprintf(stderr, "Could not open SDL display\n");
   92.26 @@ -368,9 +374,21 @@ static void sdl_update_caption(void)
   92.27      SDL_WM_SetCaption(buf, domain_name);
   92.28  }
   92.29  
   92.30 +static void sdl_hide_cursor(void)
   92.31 +{
   92.32 +    SDL_SetCursor(sdl_cursor_hidden);
   92.33 +}
   92.34 +
   92.35 +static void sdl_show_cursor(void)
   92.36 +{
   92.37 +    if (!kbd_mouse_is_absolute()) {
   92.38 +	SDL_SetCursor(sdl_cursor_normal);
   92.39 +    }
   92.40 +}
   92.41 +
   92.42  static void sdl_grab_start(void)
   92.43  {
   92.44 -    SDL_ShowCursor(0);
   92.45 +    sdl_hide_cursor();
   92.46      SDL_WM_GrabInput(SDL_GRAB_ON);
   92.47      /* dummy read to avoid moving the mouse */
   92.48      SDL_GetRelativeMouseState(NULL, NULL);
   92.49 @@ -381,6 +399,7 @@ static void sdl_grab_start(void)
   92.50  static void sdl_grab_end(void)
   92.51  {
   92.52      SDL_WM_GrabInput(SDL_GRAB_OFF);
   92.53 +    sdl_show_cursor();
   92.54      SDL_ShowCursor(1);
   92.55      gui_grab = 0;
   92.56      sdl_update_caption();
   92.57 @@ -397,6 +416,21 @@ static void sdl_send_mouse_event(void)
   92.58          buttons |= MOUSE_EVENT_RBUTTON;
   92.59      if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
   92.60          buttons |= MOUSE_EVENT_MBUTTON;
   92.61 +
   92.62 +    if (kbd_mouse_is_absolute()) {
   92.63 +	if (!absolute_enabled) {
   92.64 +	    sdl_hide_cursor();
   92.65 +	    if (gui_grab) {
   92.66 +		sdl_grab_end();
   92.67 +	    }
   92.68 +	    absolute_enabled = 1;
   92.69 +	}
   92.70 +
   92.71 +	SDL_GetMouseState(&dx, &dy);
   92.72 +	dx = dx * 0x7FFF / width;
   92.73 +	dy = dy * 0x7FFF / height;
   92.74 +    }
   92.75 +
   92.76      /* XXX: test wheel */
   92.77      dz = 0;
   92.78  #ifdef SDL_BUTTON_WHEELUP
   92.79 @@ -405,7 +439,7 @@ static void sdl_send_mouse_event(void)
   92.80      if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN))
   92.81          dz++;
   92.82  #endif
   92.83 -    kbd_mouse_event(dx, dy, dz, buttons, 0, 0);
   92.84 +    kbd_mouse_event(dx, dy, dz, buttons);
   92.85  }
   92.86  
   92.87  static void toggle_full_screen(DisplayState *ds)
   92.88 @@ -571,6 +605,7 @@ static void sdl_cleanup(void)
   92.89  void sdl_display_init(DisplayState *ds, int full_screen)
   92.90  {
   92.91      int flags;
   92.92 +    uint8_t data = 0;
   92.93  
   92.94      if(keyboard_layout)
   92.95  	    kbd_layout=init_keyboard_layout(keyboard_layout);
   92.96 @@ -597,6 +632,9 @@ void sdl_display_init(DisplayState *ds, 
   92.97      SDL_EnableUNICODE(1);
   92.98      gui_grab = 0;
   92.99  
  92.100 +    sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
  92.101 +    sdl_cursor_normal = SDL_GetCursor();
  92.102 +
  92.103      atexit(sdl_cleanup);
  92.104      if (full_screen) {
  92.105          gui_fullscreen = 1;
    93.1 --- a/tools/ioemu/target-i386-dm/Makefile	Tue Jun 13 09:00:32 2006 -0600
    93.2 +++ b/tools/ioemu/target-i386-dm/Makefile	Tue Jun 13 12:12:24 2006 -0600
    93.3 @@ -275,6 +275,9 @@ audio.o fmodaudio.o: DEFINES := -I$(CONF
    93.4  LIBS += $(CONFIG_FMOD_LIB)
    93.5  endif
    93.6  
    93.7 +# USB layer
    93.8 +VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
    93.9 +
   93.10  # Hardware support
   93.11  VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
   93.12  VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o pc.o port-e9.o
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/tools/ioemu/usb-linux.c	Tue Jun 13 12:12:24 2006 -0600
    94.3 @@ -0,0 +1,488 @@
    94.4 +/*
    94.5 + * Linux host USB redirector
    94.6 + *
    94.7 + * Copyright (c) 2005 Fabrice Bellard
    94.8 + * 
    94.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   94.10 + * of this software and associated documentation files (the "Software"), to deal
   94.11 + * in the Software without restriction, including without limitation the rights
   94.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   94.13 + * copies of the Software, and to permit persons to whom the Software is
   94.14 + * furnished to do so, subject to the following conditions:
   94.15 + *
   94.16 + * The above copyright notice and this permission notice shall be included in
   94.17 + * all copies or substantial portions of the Software.
   94.18 + *
   94.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   94.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   94.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   94.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   94.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   94.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   94.25 + * THE SOFTWARE.
   94.26 + */
   94.27 +#include "vl.h"
   94.28 +
   94.29 +#if defined(__linux__)
   94.30 +#include <dirent.h>
   94.31 +#include <sys/ioctl.h>
   94.32 +#define __user /* new versions of usbdevice_fs.h use this private attribute */
   94.33 +#include <linux/usbdevice_fs.h>
   94.34 +#include <linux/version.h>
   94.35 +
   94.36 +/* We redefine it to avoid version problems */
   94.37 +struct usb_ctrltransfer {
   94.38 +    uint8_t  bRequestType;
   94.39 +    uint8_t  bRequest;
   94.40 +    uint16_t wValue;
   94.41 +    uint16_t wIndex;
   94.42 +    uint16_t wLength;
   94.43 +    uint32_t timeout;
   94.44 +    void *data;
   94.45 +};
   94.46 +
   94.47 +typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
   94.48 +                        int vendor_id, int product_id, 
   94.49 +                        const char *product_name, int speed);
   94.50 +static int usb_host_find_device(int *pbus_num, int *paddr, 
   94.51 +                                const char *devname);
   94.52 +
   94.53 +//#define DEBUG
   94.54 +
   94.55 +#define USBDEVFS_PATH "/proc/bus/usb"
   94.56 +
   94.57 +typedef struct USBHostDevice {
   94.58 +    USBDevice dev;
   94.59 +    int fd;
   94.60 +} USBHostDevice;
   94.61 +
   94.62 +static void usb_host_handle_reset(USBDevice *dev)
   94.63 +{
   94.64 +#if 0
   94.65 +    USBHostDevice *s = (USBHostDevice *)dev;
   94.66 +    /* USBDEVFS_RESET, but not the first time as it has already be
   94.67 +       done by the host OS */
   94.68 +    ioctl(s->fd, USBDEVFS_RESET);
   94.69 +#endif
   94.70 +} 
   94.71 +
   94.72 +static int usb_host_handle_control(USBDevice *dev,
   94.73 +                                   int request,
   94.74 +                                   int value,
   94.75 +                                   int index,
   94.76 +                                   int length,
   94.77 +                                   uint8_t *data)
   94.78 +{
   94.79 +    USBHostDevice *s = (USBHostDevice *)dev;
   94.80 +    struct usb_ctrltransfer ct;
   94.81 +    int ret;
   94.82 +
   94.83 +    if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
   94.84 +        /* specific SET_ADDRESS support */
   94.85 +        dev->addr = value;
   94.86 +        return 0;
   94.87 +    } else {
   94.88 +        ct.bRequestType = request >> 8;
   94.89 +        ct.bRequest = request;
   94.90 +        ct.wValue = value;
   94.91 +        ct.wIndex = index;
   94.92 +        ct.wLength = length;
   94.93 +        ct.timeout = 50;
   94.94 +        ct.data = data;
   94.95 +        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
   94.96 +        if (ret < 0) {
   94.97 +            switch(errno) {
   94.98 +            case ETIMEDOUT:
   94.99 +                return USB_RET_NAK;
  94.100 +            default:
  94.101 +                return USB_RET_STALL;
  94.102 +            }
  94.103 +        } else {
  94.104 +            return ret;
  94.105 +        }
  94.106 +   }
  94.107 +}
  94.108 +
  94.109 +static int usb_host_handle_data(USBDevice *dev, int pid, 
  94.110 +                                uint8_t devep,
  94.111 +                                uint8_t *data, int len)
  94.112 +{
  94.113 +    USBHostDevice *s = (USBHostDevice *)dev;
  94.114 +    struct usbdevfs_bulktransfer bt;
  94.115 +    int ret;
  94.116 +
  94.117 +    /* XXX: optimize and handle all data types by looking at the
  94.118 +       config descriptor */
  94.119 +    if (pid == USB_TOKEN_IN)
  94.120 +        devep |= 0x80;
  94.121 +    bt.ep = devep;
  94.122 +    bt.len = len;
  94.123 +    bt.timeout = 50;
  94.124 +    bt.data = data;
  94.125 +    ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
  94.126 +    if (ret < 0) {
  94.127 +        switch(errno) {
  94.128 +        case ETIMEDOUT:
  94.129 +            return USB_RET_NAK;
  94.130 +        case EPIPE:
  94.131 +        default:
  94.132 +#ifdef DEBUG
  94.133 +            printf("handle_data: errno=%d\n", errno);
  94.134 +#endif
  94.135 +            return USB_RET_STALL;
  94.136 +        }
  94.137 +    } else {
  94.138 +        return ret;
  94.139 +    }
  94.140 +}
  94.141 +
  94.142 +/* XXX: exclude high speed devices or implement EHCI */
  94.143 +USBDevice *usb_host_device_open(const char *devname)
  94.144 +{
  94.145 +    int fd, interface, ret, i;
  94.146 +    USBHostDevice *dev;
  94.147 +    struct usbdevfs_connectinfo ci;
  94.148 +    uint8_t descr[1024];
  94.149 +    char buf[1024];
  94.150 +    int descr_len, dev_descr_len, config_descr_len, nb_interfaces;
  94.151 +    int bus_num, addr;
  94.152 +
  94.153 +    if (usb_host_find_device(&bus_num, &addr, devname) < 0) 
  94.154 +        return NULL;
  94.155 +    
  94.156 +    snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d", 
  94.157 +             bus_num, addr);
  94.158 +    fd = open(buf, O_RDWR);
  94.159 +    if (fd < 0) {
  94.160 +        perror(buf);
  94.161 +        return NULL;
  94.162 +    }
  94.163 +
  94.164 +    /* read the config description */
  94.165 +    descr_len = read(fd, descr, sizeof(descr));
  94.166 +    if (descr_len <= 0) {
  94.167 +        perror("read descr");
  94.168 +        goto fail;
  94.169 +    }
  94.170 +    
  94.171 +    i = 0;
  94.172 +    dev_descr_len = descr[0];
  94.173 +    if (dev_descr_len > descr_len)
  94.174 +        goto fail;
  94.175 +    i += dev_descr_len;
  94.176 +    config_descr_len = descr[i];
  94.177 +    if (i + config_descr_len > descr_len)
  94.178 +        goto fail;
  94.179 +    nb_interfaces = descr[i + 4];
  94.180 +    if (nb_interfaces != 1) {
  94.181 +        /* NOTE: currently we grab only one interface */
  94.182 +        fprintf(stderr, "usb_host: only one interface supported\n");
  94.183 +        goto fail;
  94.184 +    }
  94.185 +
  94.186 +#ifdef USBDEVFS_DISCONNECT
  94.187 +    /* earlier Linux 2.4 do not support that */
  94.188 +    {
  94.189 +        struct usbdevfs_ioctl ctrl;
  94.190 +        ctrl.ioctl_code = USBDEVFS_DISCONNECT;
  94.191 +        ctrl.ifno = 0;
  94.192 +        ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl);
  94.193 +        if (ret < 0 && errno != ENODATA) {
  94.194 +            perror("USBDEVFS_DISCONNECT");
  94.195 +            goto fail;
  94.196 +        }
  94.197 +    }
  94.198 +#endif
  94.199 +
  94.200 +    /* XXX: only grab if all interfaces are free */
  94.201 +    interface = 0;
  94.202 +    ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
  94.203 +    if (ret < 0) {
  94.204 +        if (errno == EBUSY) {
  94.205 +            fprintf(stderr, "usb_host: device already grabbed\n");
  94.206 +        } else {
  94.207 +            perror("USBDEVFS_CLAIMINTERFACE");
  94.208 +        }
  94.209 +    fail:
  94.210 +        close(fd);
  94.211 +        return NULL;
  94.212 +    }
  94.213 +
  94.214 +    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
  94.215 +    if (ret < 0) {
  94.216 +        perror("USBDEVFS_CONNECTINFO");
  94.217 +        goto fail;
  94.218 +    }
  94.219 +
  94.220 +#ifdef DEBUG
  94.221 +    printf("host USB device %d.%d grabbed\n", bus_num, addr);
  94.222 +#endif    
  94.223 +
  94.224 +    dev = qemu_mallocz(sizeof(USBHostDevice));
  94.225 +    if (!dev)
  94.226 +        goto fail;
  94.227 +    dev->fd = fd;
  94.228 +    if (ci.slow)
  94.229 +        dev->dev.speed = USB_SPEED_LOW;
  94.230 +    else
  94.231 +        dev->dev.speed = USB_SPEED_HIGH;
  94.232 +    dev->dev.handle_packet = usb_generic_handle_packet;
  94.233 +
  94.234 +    dev->dev.handle_reset = usb_host_handle_reset;
  94.235 +    dev->dev.handle_control = usb_host_handle_control;
  94.236 +    dev->dev.handle_data = usb_host_handle_data;
  94.237 +    return (USBDevice *)dev;
  94.238 +}
  94.239 +
  94.240 +static int get_tag_value(char *buf, int buf_size,
  94.241 +                         const char *str, const char *tag, 
  94.242 +                         const char *stopchars)
  94.243 +{
  94.244 +    const char *p;
  94.245 +    char *q;
  94.246 +    p = strstr(str, tag);
  94.247 +    if (!p)
  94.248 +        return -1;
  94.249 +    p += strlen(tag);
  94.250 +    while (isspace(*p))
  94.251 +        p++;
  94.252 +    q = buf;
  94.253 +    while (*p != '\0' && !strchr(stopchars, *p)) {
  94.254 +        if ((q - buf) < (buf_size - 1))
  94.255 +            *q++ = *p;
  94.256 +        p++;
  94.257 +    }
  94.258 +    *q = '\0';
  94.259 +    return q - buf;
  94.260 +}
  94.261 +
  94.262 +static int usb_host_scan(void *opaque, USBScanFunc *func)
  94.263 +{
  94.264 +    FILE *f;
  94.265 +    char line[1024];
  94.266 +    char buf[1024];
  94.267 +    int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
  94.268 +    int ret;
  94.269 +    char product_name[512];
  94.270 +    
  94.271 +    f = fopen(USBDEVFS_PATH "/devices", "r");
  94.272 +    if (!f) {
  94.273 +        term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
  94.274 +        return 0;
  94.275 +    }
  94.276 +    device_count = 0;
  94.277 +    bus_num = addr = speed = class_id = product_id = vendor_id = 0;
  94.278 +    ret = 0;
  94.279 +    for(;;) {
  94.280 +        if (fgets(line, sizeof(line), f) == NULL)
  94.281 +            break;
  94.282 +        if (strlen(line) > 0)
  94.283 +            line[strlen(line) - 1] = '\0';
  94.284 +        if (line[0] == 'T' && line[1] == ':') {
  94.285 +            if (device_count && (vendor_id || product_id)) {
  94.286 +                /* New device.  Add the previously discovered device.  */
  94.287 +                ret = func(opaque, bus_num, addr, class_id, vendor_id, 
  94.288 +                           product_id, product_name, speed);
  94.289 +                if (ret)
  94.290 +                    goto the_end;
  94.291 +            }
  94.292 +            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
  94.293 +                goto fail;
  94.294 +            bus_num = atoi(buf);
  94.295 +            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
  94.296 +                goto fail;
  94.297 +            addr = atoi(buf);
  94.298 +            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
  94.299 +                goto fail;
  94.300 +            if (!strcmp(buf, "480"))
  94.301 +                speed = USB_SPEED_HIGH;
  94.302 +            else if (!strcmp(buf, "1.5"))
  94.303 +                speed = USB_SPEED_LOW;
  94.304 +            else
  94.305 +                speed = USB_SPEED_FULL;
  94.306 +            product_name[0] = '\0';
  94.307 +            class_id = 0xff;
  94.308 +            device_count++;
  94.309 +            product_id = 0;
  94.310 +            vendor_id = 0;
  94.311 +        } else if (line[0] == 'P' && line[1] == ':') {
  94.312 +            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
  94.313 +                goto fail;
  94.314 +            vendor_id = strtoul(buf, NULL, 16);
  94.315 +            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
  94.316 +                goto fail;
  94.317 +            product_id = strtoul(buf, NULL, 16);
  94.318 +        } else if (line[0] == 'S' && line[1] == ':') {
  94.319 +            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
  94.320 +                goto fail;
  94.321 +            pstrcpy(product_name, sizeof(product_name), buf);
  94.322 +        } else if (line[0] == 'D' && line[1] == ':') {
  94.323 +            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
  94.324 +                goto fail;
  94.325 +            class_id = strtoul(buf, NULL, 16);
  94.326 +        }
  94.327 +    fail: ;
  94.328 +    }
  94.329 +    if (device_count && (vendor_id || product_id)) {
  94.330 +        /* Add the last device.  */
  94.331 +        ret = func(opaque, bus_num, addr, class_id, vendor_id, 
  94.332 +                   product_id, product_name, speed);
  94.333 +    }
  94.334 + the_end:
  94.335 +    fclose(f);
  94.336 +    return ret;
  94.337 +}
  94.338 +
  94.339 +typedef struct FindDeviceState {
  94.340 +    int vendor_id;
  94.341 +    int product_id;
  94.342 +    int bus_num;
  94.343 +    int addr;
  94.344 +} FindDeviceState;
  94.345 +
  94.346 +static int usb_host_find_device_scan(void *opaque, int bus_num, int addr, 
  94.347 +                                     int class_id,
  94.348 +                                     int vendor_id, int product_id, 
  94.349 +                                     const char *product_name, int speed)
  94.350 +{
  94.351 +    FindDeviceState *s = opaque;
  94.352 +    if (vendor_id == s->vendor_id &&
  94.353 +        product_id == s->product_id) {
  94.354 +        s->bus_num = bus_num;
  94.355 +        s->addr = addr;
  94.356 +        return 1;
  94.357 +    } else {
  94.358 +        return 0;
  94.359 +    }
  94.360 +}
  94.361 +
  94.362 +/* the syntax is : 
  94.363 +   'bus.addr' (decimal numbers) or 
  94.364 +   'vendor_id:product_id' (hexa numbers) */
  94.365 +static int usb_host_find_device(int *pbus_num, int *paddr, 
  94.366 +                                const char *devname)
  94.367 +{
  94.368 +    const char *p;
  94.369 +    int ret;
  94.370 +    FindDeviceState fs;
  94.371 +
  94.372 +    p = strchr(devname, '.');
  94.373 +    if (p) {
  94.374 +        *pbus_num = strtoul(devname, NULL, 0);
  94.375 +        *paddr = strtoul(p + 1, NULL, 0);
  94.376 +        return 0;
  94.377 +    }
  94.378 +    p = strchr(devname, ':');
  94.379 +    if (p) {
  94.380 +        fs.vendor_id = strtoul(devname, NULL, 16);
  94.381 +        fs.product_id = strtoul(p + 1, NULL, 16);
  94.382 +        ret = usb_host_scan(&fs, usb_host_find_device_scan);
  94.383 +        if (ret) {
  94.384 +            *pbus_num = fs.bus_num;
  94.385 +            *paddr = fs.addr;
  94.386 +            return 0;
  94.387 +        }
  94.388 +    }
  94.389 +    return -1;
  94.390 +}
  94.391 +
  94.392 +/**********************/
  94.393 +/* USB host device info */
  94.394 +
  94.395 +struct usb_class_info {
  94.396 +    int class;
  94.397 +    const char *class_name;
  94.398 +};
  94.399 +
  94.400 +static const struct usb_class_info usb_class_info[] = {
  94.401 +    { USB_CLASS_AUDIO, "Audio"},
  94.402 +    { USB_CLASS_COMM, "Communication"},
  94.403 +    { USB_CLASS_HID, "HID"},
  94.404 +    { USB_CLASS_HUB, "Hub" },
  94.405 +    { USB_CLASS_PHYSICAL, "Physical" },
  94.406 +    { USB_CLASS_PRINTER, "Printer" },
  94.407 +    { USB_CLASS_MASS_STORAGE, "Storage" },
  94.408 +    { USB_CLASS_CDC_DATA, "Data" },
  94.409 +    { USB_CLASS_APP_SPEC, "Application Specific" },
  94.410 +    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
  94.411 +    { USB_CLASS_STILL_IMAGE, "Still Image" },
  94.412 +    { USB_CLASS_CSCID, 	"Smart Card" },
  94.413 +    { USB_CLASS_CONTENT_SEC, "Content Security" },
  94.414 +    { -1, NULL }
  94.415 +};
  94.416 +
  94.417 +static const char *usb_class_str(uint8_t class)
  94.418 +{
  94.419 +    const struct usb_class_info *p;
  94.420 +    for(p = usb_class_info; p->class != -1; p++) {
  94.421 +        if (p->class == class)
  94.422 +            break;
  94.423 +    }
  94.424 +    return p->class_name;
  94.425 +}
  94.426 +
  94.427 +void usb_info_device(int bus_num, int addr, int class_id,
  94.428 +                     int vendor_id, int product_id, 
  94.429 +                     const char *product_name,
  94.430 +                     int speed)
  94.431 +{
  94.432 +    const char *class_str, *speed_str;
  94.433 +
  94.434 +    switch(speed) {
  94.435 +    case USB_SPEED_LOW: 
  94.436 +        speed_str = "1.5"; 
  94.437 +        break;
  94.438 +    case USB_SPEED_FULL: 
  94.439 +        speed_str = "12"; 
  94.440 +        break;
  94.441 +    case USB_SPEED_HIGH: 
  94.442 +        speed_str = "480"; 
  94.443 +        break;
  94.444 +    default:
  94.445 +        speed_str = "?"; 
  94.446 +        break;
  94.447 +    }
  94.448 +
  94.449 +    term_printf("  Device %d.%d, speed %s Mb/s\n", 
  94.450 +                bus_num, addr, speed_str);
  94.451 +    class_str = usb_class_str(class_id);
  94.452 +    if (class_str) 
  94.453 +        term_printf("    %s:", class_str);
  94.454 +    else
  94.455 +        term_printf("    Class %02x:", class_id);
  94.456 +    term_printf(" USB device %04x:%04x", vendor_id, product_id);
  94.457 +    if (product_name[0] != '\0')
  94.458 +        term_printf(", %s", product_name);
  94.459 +    term_printf("\n");
  94.460 +}
  94.461 +
  94.462 +static int usb_host_info_device(void *opaque, int bus_num, int addr, 
  94.463 +                                int class_id,
  94.464 +                                int vendor_id, int product_id, 
  94.465 +                                const char *product_name,
  94.466 +                                int speed)
  94.467 +{
  94.468 +    usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
  94.469 +                    product_name, speed);
  94.470 +    return 0;
  94.471 +}
  94.472 +
  94.473 +void usb_host_info(void)
  94.474 +{
  94.475 +    usb_host_scan(NULL, usb_host_info_device);
  94.476 +}
  94.477 +
  94.478 +#else
  94.479 +
  94.480 +void usb_host_info(void)
  94.481 +{
  94.482 +    term_printf("USB host devices not supported\n");
  94.483 +}
  94.484 +
  94.485 +/* XXX: modify configure to compile the right host driver */
  94.486 +USBDevice *usb_host_device_open(const char *devname)
  94.487 +{
  94.488 +    return NULL;
  94.489 +}
  94.490 +
  94.491 +#endif
    95.1 --- a/tools/ioemu/vl.c	Tue Jun 13 09:00:32 2006 -0600
    95.2 +++ b/tools/ioemu/vl.c	Tue Jun 13 12:12:24 2006 -0600
    95.3 @@ -144,8 +144,12 @@ int graphic_height = 600;
    95.4  int graphic_depth = 15;
    95.5  int full_screen = 0;
    95.6  int repeat_key = 1;
    95.7 +int usb_enabled = 0;
    95.8 +USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
    95.9 +USBDevice *vm_usb_hub;
   95.10  TextConsole *vga_console;
   95.11  CharDriverState *serial_hds[MAX_SERIAL_PORTS];
   95.12 +int serial_summa_port = -1;
   95.13  int xc_handle;
   95.14  time_t timeoffset = 0;
   95.15  
   95.16 @@ -437,6 +441,7 @@ static QEMUPutKBDEvent *qemu_put_kbd_eve
   95.17  static void *qemu_put_kbd_event_opaque;
   95.18  static QEMUPutMouseEvent *qemu_put_mouse_event;
   95.19  static void *qemu_put_mouse_event_opaque;
   95.20 +static int qemu_put_mouse_event_absolute;
   95.21  
   95.22  void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
   95.23  {
   95.24 @@ -444,10 +449,11 @@ void qemu_add_kbd_event_handler(QEMUPutK
   95.25      qemu_put_kbd_event = func;
   95.26  }
   95.27  
   95.28 -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
   95.29 +void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
   95.30  {
   95.31      qemu_put_mouse_event_opaque = opaque;
   95.32      qemu_put_mouse_event = func;
   95.33 +    qemu_put_mouse_event_absolute = absolute;
   95.34  }
   95.35  
   95.36  void kbd_put_keycode(int keycode)
   95.37 @@ -457,14 +463,19 @@ void kbd_put_keycode(int keycode)
   95.38      }
   95.39  }
   95.40  
   95.41 -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y)
   95.42 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
   95.43  {
   95.44      if (qemu_put_mouse_event) {
   95.45          qemu_put_mouse_event(qemu_put_mouse_event_opaque,
   95.46 -                             dx, dy, dz, buttons_state, x, y);
   95.47 +                             dx, dy, dz, buttons_state);
   95.48      }
   95.49  }
   95.50  
   95.51 +int kbd_mouse_is_absolute(void)
   95.52 +{
   95.53 +    return qemu_put_mouse_event_absolute;
   95.54 +}
   95.55 +
   95.56  /***********************************************************/
   95.57  /* timers */
   95.58  
   95.59 @@ -1643,6 +1654,121 @@ static int net_fd_init(NetDriverState *n
   95.60  }
   95.61  
   95.62  #endif /* !_WIN32 */
   95.63 + 
   95.64 +/***********************************************************/
   95.65 +/* USB devices */
   95.66 +
   95.67 +static int usb_device_add(const char *devname)
   95.68 +{
   95.69 +    const char *p;
   95.70 +    USBDevice *dev;
   95.71 +    int i;
   95.72 +
   95.73 +    if (!vm_usb_hub)
   95.74 +        return -1;
   95.75 +    for(i = 0;i < MAX_VM_USB_PORTS; i++) {
   95.76 +        if (!vm_usb_ports[i]->dev)
   95.77 +            break;
   95.78 +    }
   95.79 +    if (i == MAX_VM_USB_PORTS)
   95.80 +        return -1;
   95.81 +
   95.82 +    if (strstart(devname, "host:", &p)) {
   95.83 +        dev = usb_host_device_open(p);
   95.84 +        if (!dev)
   95.85 +            return -1;
   95.86 +    } else if (!strcmp(devname, "mouse")) {
   95.87 +        dev = usb_mouse_init();
   95.88 +        if (!dev)
   95.89 +            return -1;
   95.90 +    } else if (!strcmp(devname, "tablet")) {
   95.91 +	dev = usb_tablet_init();
   95.92 +	if (!dev)
   95.93 +	    return -1;
   95.94 +    } else {
   95.95 +        return -1;
   95.96 +    }
   95.97 +    usb_attach(vm_usb_ports[i], dev);
   95.98 +    return 0;
   95.99 +}
  95.100 +
  95.101 +static int usb_device_del(const char *devname)
  95.102 +{
  95.103 +    USBDevice *dev;
  95.104 +    int bus_num, addr, i;
  95.105 +    const char *p;
  95.106 +
  95.107 +    if (!vm_usb_hub)
  95.108 +        return -1;
  95.109 +
  95.110 +    p = strchr(devname, '.');
  95.111 +    if (!p) 
  95.112 +        return -1;
  95.113 +    bus_num = strtoul(devname, NULL, 0);
  95.114 +    addr = strtoul(p + 1, NULL, 0);
  95.115 +    if (bus_num != 0)
  95.116 +        return -1;
  95.117 +    for(i = 0;i < MAX_VM_USB_PORTS; i++) {
  95.118 +        dev = vm_usb_ports[i]->dev;
  95.119 +        if (dev && dev->addr == addr)
  95.120 +            break;
  95.121 +    }
  95.122 +    if (i == MAX_VM_USB_PORTS)
  95.123 +        return -1;
  95.124 +    usb_attach(vm_usb_ports[i], NULL);
  95.125 +    return 0;
  95.126 +}
  95.127 +
  95.128 +void do_usb_add(const char *devname)
  95.129 +{
  95.130 +    int ret;
  95.131 +    ret = usb_device_add(devname);
  95.132 +    if (ret < 0) 
  95.133 +        term_printf("Could not add USB device '%s'\n", devname);
  95.134 +}
  95.135 +
  95.136 +void do_usb_del(const char *devname)
  95.137 +{
  95.138 +    int ret;
  95.139 +    ret = usb_device_del(devname);
  95.140 +    if (ret < 0) 
  95.141 +        term_printf("Could not remove USB device '%s'\n", devname);
  95.142 +}
  95.143 +
  95.144 +void usb_info(void)
  95.145 +{
  95.146 +    USBDevice *dev;
  95.147 +    int i;
  95.148 +    const char *speed_str;
  95.149 +
  95.150 +    if (!vm_usb_hub) {
  95.151 +        term_printf("USB support not enabled\n");
  95.152 +        return;
  95.153 +    }
  95.154 +
  95.155 +    for(i = 0; i < MAX_VM_USB_PORTS; i++) {
  95.156 +        dev = vm_usb_ports[i]->dev;
  95.157 +        if (dev) {
  95.158 +            term_printf("Hub port %d:\n", i);
  95.159 +            switch(dev->speed) {
  95.160 +            case USB_SPEED_LOW: 
  95.161 +                speed_str = "1.5"; 
  95.162 +                break;
  95.163 +            case USB_SPEED_FULL: 
  95.164 +                speed_str = "12"; 
  95.165 +                break;
  95.166 +            case USB_SPEED_HIGH: 
  95.167 +                speed_str = "480"; 
  95.168 +                break;
  95.169 +            default:
  95.170 +                speed_str = "?"; 
  95.171 +                break;
  95.172 +            }
  95.173 +            term_printf("  Device %d.%d, speed %s Mb/s\n", 
  95.174 +                        0, dev->addr, speed_str);
  95.175 +        }
  95.176 +    }
  95.177 +}
  95.178  
  95.179  /***********************************************************/
  95.180  /* dumb display */
  95.181 @@ -2213,6 +2339,8 @@ void help(void)
  95.182             "-enable-audio   enable audio support\n"
  95.183             "-localtime      set the real time clock to local time [default=utc]\n"
  95.184             "-full-screen    start in full screen\n"
  95.185 +           "-usb            enable the USB driver (will be the default soon)\n"
  95.186 +           "-usbdevice name add the host or guest USB device 'name'\n"
  95.187  #ifdef TARGET_PPC
  95.188             "-prep           Simulate a PREP system (default is PowerMAC)\n"
  95.189             "-g WxH[xDEPTH]  Set the initial VGA graphic mode\n"
  95.190 @@ -2354,6 +2482,8 @@ enum {
  95.191      QEMU_OPTION_full_screen,
  95.192      QEMU_OPTION_vgaacc,
  95.193      QEMU_OPTION_repeatkey,
  95.194 +    QEMU_OPTION_usb,
  95.195 +    QEMU_OPTION_usbdevice,
  95.196  };
  95.197  
  95.198  typedef struct QEMUOption {
  95.199 @@ -2427,8 +2557,10 @@ const QEMUOption qemu_options[] = {
  95.200      { "serial", 1, QEMU_OPTION_serial },
  95.201      { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
  95.202      { "full-screen", 0, QEMU_OPTION_full_screen },
  95.203 +    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
  95.204  
  95.205      /* temporary options */
  95.206 +    { "usb", 0, QEMU_OPTION_usb },
  95.207      { "pci", 0, QEMU_OPTION_pci },
  95.208      { "nic-ne2000", 0, QEMU_OPTION_nic_ne2000 },
  95.209      { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
  95.210 @@ -2457,7 +2589,7 @@ int unset_mm_mapping(int xc_handle,
  95.211                       uint32_t domid,
  95.212                       unsigned long nr_pages,
  95.213                       unsigned int address_bits,
  95.214 -                     unsigned long *extent_start)
  95.215 +                     xen_pfn_t *extent_start)
  95.216  {
  95.217      int err = 0;
  95.218      xc_dominfo_t info;
  95.219 @@ -2490,7 +2622,7 @@ int set_mm_mapping(int xc_handle,
  95.220                      uint32_t domid,
  95.221                      unsigned long nr_pages,
  95.222                      unsigned int address_bits,
  95.223 -                    unsigned long *extent_start)
  95.224 +                    xen_pfn_t *extent_start)
  95.225  {
  95.226      xc_dominfo_t info;
  95.227      int err = 0;
  95.228 @@ -2498,7 +2630,7 @@ int set_mm_mapping(int xc_handle,
  95.229      xc_domain_getinfo(xc_handle, domid, 1, &info);
  95.230  
  95.231      if ( xc_domain_setmaxmem(xc_handle, domid,
  95.232 -                             (info.nr_pages + nr_pages) * PAGE_SIZE/1024) != 0)
  95.233 +                             info.max_memkb + nr_pages * PAGE_SIZE/1024) !=0)
  95.234      {
  95.235          fprintf(logfile, "set maxmem returned error %d\n", errno);
  95.236          return -1;
  95.237 @@ -2554,9 +2686,12 @@ int main(int argc, char **argv)
  95.238      char monitor_device[128];
  95.239      char serial_devices[MAX_SERIAL_PORTS][128];
  95.240      int serial_device_index;
  95.241 +    char usb_devices[MAX_VM_USB_PORTS][128];
  95.242 +    int usb_devices_index;
  95.243      char qemu_dm_logfilename[64];
  95.244      const char *loadvm = NULL;
  95.245 -    unsigned long nr_pages, *page_array;
  95.246 +    unsigned long nr_pages;
  95.247 +    xen_pfn_t *page_array;
  95.248      extern void *shared_page;
  95.249  
  95.250  #if !defined(CONFIG_SOFTMMU)
  95.251 @@ -2588,11 +2723,12 @@ int main(int argc, char **argv)
  95.252      pstrcpy(monitor_device, sizeof(monitor_device), "vc");
  95.253  
  95.254      pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
  95.255 -    pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null");
  95.256 -    for(i = 2; i < MAX_SERIAL_PORTS; i++)
  95.257 +    serial_summa_port = -1;
  95.258 +    for(i = 1; i < MAX_SERIAL_PORTS; i++)
  95.259          serial_devices[i][0] = '\0';
  95.260      serial_device_index = 0;
  95.261  
  95.262 +    usb_devices_index = 0;
  95.263      nb_tun_fds = 0;
  95.264      net_if_type = -1;
  95.265      nb_nics = 1;
  95.266 @@ -2937,6 +3073,20 @@ int main(int argc, char **argv)
  95.267              case QEMU_OPTION_full_screen:
  95.268                  full_screen = 1;
  95.269                  break;
  95.270 +            case QEMU_OPTION_usb:
  95.271 +                usb_enabled = 1;
  95.272 +                break;
  95.273 +            case QEMU_OPTION_usbdevice:
  95.274 +                usb_enabled = 1;
  95.275 +                if (usb_devices_index >= MAX_VM_USB_PORTS) {
  95.276 +                    fprintf(stderr, "Too many USB devices\n");
  95.277 +                    exit(1);
  95.278 +                }
  95.279 +                pstrcpy(usb_devices[usb_devices_index],
  95.280 +                        sizeof(usb_devices[usb_devices_index]),
  95.281 +                        optarg);
  95.282 +                usb_devices_index++;
  95.283 +                break;
  95.284              case QEMU_OPTION_domainname:
  95.285                  strncat(domain_name, optarg, sizeof(domain_name) - 20);
  95.286                  break;
  95.287 @@ -3022,8 +3172,8 @@ int main(int argc, char **argv)
  95.288  
  95.289      xc_handle = xc_interface_open();
  95.290  
  95.291 -    if ( (page_array = (unsigned long *)
  95.292 -                        malloc(nr_pages * sizeof(unsigned long))) == NULL)
  95.293 +    if ( (page_array = (xen_pfn_t *)
  95.294 +                        malloc(nr_pages * sizeof(xen_pfn_t))) == NULL)
  95.295      {
  95.296          fprintf(logfile, "malloc returned error %d\n", errno);
  95.297          exit(-1);
  95.298 @@ -3078,8 +3228,8 @@ int main(int argc, char **argv)
  95.299                                         page_array[0]);
  95.300  #endif
  95.301  
  95.302 -    fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
  95.303 -           (page_array[nr_pages - 1]));
  95.304 +    fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", (nr_pages-1),
  95.305 +           (uint64_t)(page_array[nr_pages - 1]));
  95.306  
  95.307      /* we always create the cdrom drive, even if no disk is there */
  95.308      bdrv_init();
  95.309 @@ -3137,6 +3287,17 @@ int main(int argc, char **argv)
  95.310          }
  95.311      }
  95.312  
  95.313 +    /* init USB devices */
  95.314 +    if (usb_enabled) {
  95.315 +        vm_usb_hub = usb_hub_init(vm_usb_ports, MAX_VM_USB_PORTS);
  95.316 +        for(i = 0; i < usb_devices_index; i++) {
  95.317 +            if (usb_device_add(usb_devices[i]) < 0) {
  95.318 +                fprintf(stderr, "Warning: could not add USB device %s\n",
  95.319 +                        usb_devices[i]);
  95.320 +            }
  95.321 +        }
  95.322 +    }
  95.323 +
  95.324      /* init CPU state */
  95.325      env = cpu_init();
  95.326      global_env = env;
  95.327 @@ -3173,6 +3334,20 @@ int main(int argc, char **argv)
  95.328      }
  95.329      monitor_init(monitor_hd, !nographic);
  95.330  
  95.331 +    /* Find which port should be the Summagraphics port */
  95.332 +    /* It's the first unspecified serial line. Note that COM1 is set */
  95.333 +    /* by default, so the Summagraphics port would be COM2 or higher */
  95.334 +
  95.335 +    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
  95.336 +      if (serial_devices[i][0] != '\0')
  95.337 +	continue;
  95.338 +      serial_summa_port = i;
  95.339 +      pstrcpy(serial_devices[serial_summa_port], sizeof(serial_devices[0]), "null");
  95.340 +      break;
  95.341 +    }
  95.342 +
  95.343 +    /* Now, open the ports */
  95.344 +
  95.345      for(i = 0; i < MAX_SERIAL_PORTS; i++) {
  95.346          if (serial_devices[i][0] != '\0') {
  95.347              serial_hds[i] = qemu_chr_open(serial_devices[i]);
    96.1 --- a/tools/ioemu/vl.h	Tue Jun 13 09:00:32 2006 -0600
    96.2 +++ b/tools/ioemu/vl.h	Tue Jun 13 12:12:24 2006 -0600
    96.3 @@ -154,13 +154,14 @@ extern int graphic_depth;
    96.4  #define MOUSE_EVENT_MBUTTON 0x04
    96.5  
    96.6  typedef void QEMUPutKBDEvent(void *opaque, int keycode);
    96.7 -typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state, int x, int y);
    96.8 +typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
    96.9  
   96.10  void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
   96.11 -void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
   96.12 +void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute);
   96.13  
   96.14  void kbd_put_keycode(int keycode);
   96.15 -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y);
   96.16 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
   96.17 +int kbd_mouse_is_absolute(void);
   96.18  
   96.19  /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
   96.20     constants) */
   96.21 @@ -238,9 +239,9 @@ void console_select(unsigned int index);
   96.22  /* serial ports */
   96.23  
   96.24  #define MAX_SERIAL_PORTS 4
   96.25 -#define SUMMA_PORT	1
   96.26  
   96.27  extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
   96.28 +extern int serial_summa_port;
   96.29  
   96.30  /* network redirectors support */
   96.31  
   96.32 @@ -633,6 +634,7 @@ void pci_pcnet_init(PCIBus *bus, NetDriv
   96.33  void kbd_init(void);
   96.34  extern const char* keyboard_layout;
   96.35  extern int repeat_key;
   96.36 +extern int usb_enabled;
   96.37  
   96.38  /* mc146818rtc.c */
   96.39  
   96.40 @@ -792,6 +794,19 @@ void adb_mouse_init(ADBBusState *bus);
   96.41  
   96.42  /* cuda.c */
   96.43  
   96.44 +#include "hw/usb.h"
   96.45 +
   96.46 +/* usb ports of the VM */
   96.47 +
   96.48 +#define MAX_VM_USB_PORTS 8
   96.49 +
   96.50 +extern USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
   96.51 +extern USBDevice *vm_usb_hub;
   96.52 +
   96.53 +void do_usb_add(const char *devname);
   96.54 +void do_usb_del(const char *devname);
   96.55 +void usb_info(void);
   96.56 +
   96.57  extern ADBBusState adb_bus;
   96.58  int cuda_init(openpic_t *openpic, int irq);
   96.59  
    97.1 --- a/tools/ioemu/vnc.c	Tue Jun 13 09:00:32 2006 -0600
    97.2 +++ b/tools/ioemu/vnc.c	Tue Jun 13 12:12:24 2006 -0600
    97.3 @@ -138,9 +138,16 @@ static void init_mouse(int max_x,int max
    97.4  }
    97.5  
    97.6  static void mouse_refresh() {
    97.7 +	static int last_x = -1;
    97.8 +	static int last_y = -1;
    97.9 +	static int last_z = -1;
   97.10 +	static int last_b = -1;
   97.11  	int dx=0,dy=0,dz=new_mouse_z;
   97.12  	static int counter=1;
   97.13  
   97.14 +	if (new_mouse_x == last_x && new_mouse_y == last_y &&
   97.15 +	    new_mouse_z == last_z && new_mouse_buttons == last_b)
   97.16 +		return;
   97.17  	/*
   97.18  	 *  Simulate lifting the mouse by pressing left <ctl><alt> together
   97.19  	 *  e.g. don't send mouse events.
   97.20 @@ -148,27 +155,40 @@ static void mouse_refresh() {
   97.21  	if (ctl_keys == 3) {
   97.22  		mouse_x = new_mouse_x;
   97.23  		mouse_y = new_mouse_y;
   97.24 +		last_x = new_mouse_x;
   97.25 +		last_y = new_mouse_y;
   97.26 +		last_z = new_mouse_z;
   97.27 +		last_b = new_mouse_buttons;
   97.28  		return;
   97.29  	}
   97.30  	counter++;
   97.31 -	if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
   97.32 -
   97.33 -	dx=new_mouse_x-mouse_x;
   97.34 -	dy=new_mouse_y-mouse_y;
   97.35 -
   97.36 -	if(mouse_magic->sonic_wall_is_orthogonal) {
   97.37 -		if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; }
   97.38 -		if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; }
   97.39 +	//fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
   97.40 +	if (kbd_mouse_is_absolute()) {
   97.41 +		kbd_mouse_event(new_mouse_x * 0x7FFF / screen->width,
   97.42 +				new_mouse_y * 0x7FFF / screen->height, dz, new_mouse_buttons);
   97.43  	} else {
   97.44 -		if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) {
   97.45 -			dx/=2; mouse_x+=dx;
   97.46 -			dy/=2; mouse_y+=dy;
   97.47 +		if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
   97.48 +
   97.49 +		dx=new_mouse_x-last_x;
   97.50 +		dy=new_mouse_y-last_y;
   97.51 +
   97.52 +		if(mouse_magic->sonic_wall_is_orthogonal) {
   97.53 +			if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; }
   97.54 +			if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; }
   97.55 +		} else {
   97.56 +			if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) {
   97.57 +				dx/=2; mouse_x+=dx;
   97.58 +				dy/=2; mouse_y+=dy;
   97.59 +			}
   97.60  		}
   97.61 +		if (last_x != -1)
   97.62 +			kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
   97.63 +
   97.64  	}
   97.65 -	//fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
   97.66 -	kbd_mouse_event(dx,dy,dz,new_mouse_buttons,new_mouse_x,new_mouse_y);
   97.67 -	mouse_x+=dx;
   97.68 -	mouse_y+=dy;
   97.69 +	last_x = new_mouse_x;
   97.70 +	last_y = new_mouse_y;
   97.71 +	last_z = new_mouse_z;
   97.72 +	last_b = new_mouse_buttons;
   97.73  		
   97.74  	updates_since_mouse=0;
   97.75  }
   97.76 @@ -250,7 +270,7 @@ static void mouse_calibration_refresh() 
   97.77  	
   97.78  	if(calibration_step==0) {
   97.79  		x=0; y=1;
   97.80 -		kbd_mouse_event(0,-1,0,0,x,y);
   97.81 +		kbd_mouse_event(0,-1,0,0);
   97.82  		calibration_step++;
   97.83  	} else if(calibration_step==1) {
   97.84  		// find out the initial position of the cursor
   97.85 @@ -282,7 +302,7 @@ static void mouse_calibration_refresh() 
   97.86  		} else {
   97.87  			y++;
   97.88  move_calibrate:
   97.89 -			kbd_mouse_event(-x,-y,0,0,x,y);
   97.90 +			kbd_mouse_event(-x,-y,0,0);
   97.91  			before_update=last_update;
   97.92  		}
   97.93  	} else if(calibration_step==3) {
    98.1 --- a/tools/libxc/xc_core.c	Tue Jun 13 09:00:32 2006 -0600
    98.2 +++ b/tools/libxc/xc_core.c	Tue Jun 13 12:12:24 2006 -0600
    98.3 @@ -28,7 +28,7 @@ xc_domain_dumpcore_via_callback(int xc_h
    98.4                                  dumpcore_rtn_t dump_rtn)
    98.5  {
    98.6      unsigned long nr_pages;
    98.7 -    unsigned long *page_array = NULL;
    98.8 +    xen_pfn_t *page_array = NULL;
    98.9      xc_dominfo_t info;
   98.10      int i, nr_vcpus = 0;
   98.11      char *dump_mem, *dump_mem_start = NULL;
   98.12 @@ -70,7 +70,7 @@ xc_domain_dumpcore_via_callback(int xc_h
   98.13          sizeof(vcpu_guest_context_t)*nr_vcpus;
   98.14      dummy_len = (sizeof(struct xc_core_header) +
   98.15                   (sizeof(vcpu_guest_context_t) * nr_vcpus) +
   98.16 -                 (nr_pages * sizeof(unsigned long)));
   98.17 +                 (nr_pages * sizeof(xen_pfn_t)));
   98.18      header.xch_pages_offset = round_pgup(dummy_len);
   98.19  
   98.20      sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
   98.21 @@ -81,17 +81,17 @@ xc_domain_dumpcore_via_callback(int xc_h
   98.22      if ( sts != 0 )
   98.23          goto error_out;
   98.24  
   98.25 -    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
   98.26 +    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
   98.27      {
   98.28 -        printf("Could not allocate memory\n");
   98.29 +        IPRINTF("Could not allocate memory\n");
   98.30          goto error_out;
   98.31      }
   98.32      if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
   98.33      {
   98.34 -        printf("Could not get the page frame list\n");
   98.35 +        IPRINTF("Could not get the page frame list\n");
   98.36          goto error_out;
   98.37      }
   98.38 -    sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(unsigned long));
   98.39 +    sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(xen_pfn_t));
   98.40      if ( sts != 0 )
   98.41          goto error_out;
   98.42  
    99.1 --- a/tools/libxc/xc_domain.c	Tue Jun 13 09:00:32 2006 -0600
    99.2 +++ b/tools/libxc/xc_domain.c	Tue Jun 13 12:12:24 2006 -0600
    99.3 @@ -291,7 +291,7 @@ int xc_domain_memory_increase_reservatio
    99.4                                            unsigned long nr_extents,
    99.5                                            unsigned int extent_order,
    99.6                                            unsigned int address_bits,
    99.7 -                                          unsigned long *extent_start)
    99.8 +                                          xen_pfn_t *extent_start)
    99.9  {
   99.10      int err;
   99.11      struct xen_memory_reservation reservation = {
   99.12 @@ -310,7 +310,7 @@ int xc_domain_memory_increase_reservatio
   99.13  
   99.14      if ( err > 0 )
   99.15      {
   99.16 -        fprintf(stderr, "Failed allocation for dom %d: "
   99.17 +        DPRINTF("Failed allocation for dom %d: "
   99.18                  "%ld pages order %d addr_bits %d\n",
   99.19                  domid, nr_extents, extent_order, address_bits);
   99.20          errno = ENOMEM;
   99.21 @@ -324,7 +324,7 @@ int xc_domain_memory_decrease_reservatio
   99.22                                            uint32_t domid,
   99.23                                            unsigned long nr_extents,
   99.24                                            unsigned int extent_order,
   99.25 -                                          unsigned long *extent_start)
   99.26 +                                          xen_pfn_t *extent_start)
   99.27  {
   99.28      int err;
   99.29      struct xen_memory_reservation reservation = {
   99.30 @@ -338,7 +338,7 @@ int xc_domain_memory_decrease_reservatio
   99.31  
   99.32      if ( extent_start == NULL )
   99.33      {
   99.34 -        fprintf(stderr,"decrease_reservation extent_start is NULL!\n");
   99.35 +        DPRINTF("decrease_reservation extent_start is NULL!\n");
   99.36          errno = EINVAL;
   99.37          return -1;
   99.38      }
   99.39 @@ -349,7 +349,7 @@ int xc_domain_memory_decrease_reservatio
   99.40  
   99.41      if ( err > 0 )
   99.42      {
   99.43 -        fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
   99.44 +        DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n",
   99.45                  domid, nr_extents, extent_order);
   99.46          errno = EBUSY;
   99.47          err = -1;
   99.48 @@ -363,7 +363,7 @@ int xc_domain_memory_populate_physmap(in
   99.49                                            unsigned long nr_extents,
   99.50                                            unsigned int extent_order,
   99.51                                            unsigned int address_bits,
   99.52 -                                          unsigned long *extent_start)
   99.53 +                                          xen_pfn_t *extent_start)
   99.54  {
   99.55      int err;
   99.56      struct xen_memory_reservation reservation = {
   99.57 @@ -380,7 +380,7 @@ int xc_domain_memory_populate_physmap(in
   99.58  
   99.59      if ( err > 0 )
   99.60      {
   99.61 -        fprintf(stderr,"Failed deallocation for dom %d: %ld pages order %d\n",
   99.62 +        DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n",
   99.63                  domid, nr_extents, extent_order);
   99.64          errno = EBUSY;
   99.65          err = -1;
   99.66 @@ -392,8 +392,8 @@ int xc_domain_memory_populate_physmap(in
   99.67  int xc_domain_translate_gpfn_list(int xc_handle,
   99.68                                    uint32_t domid,
   99.69                                    unsigned long nr_gpfns,
   99.70 -                                  unsigned long *gpfn_list,
   99.71 -                                  unsigned long *mfn_list)
   99.72 +                                  xen_pfn_t *gpfn_list,
   99.73 +                                  xen_pfn_t *mfn_list)
   99.74  {
   99.75      struct xen_translate_gpfn_list op = {
   99.76          .domid        = domid,
   100.1 --- a/tools/libxc/xc_hvm_build.c	Tue Jun 13 09:00:32 2006 -0600
   100.2 +++ b/tools/libxc/xc_hvm_build.c	Tue Jun 13 12:12:24 2006 -0600
   100.3 @@ -135,7 +135,7 @@ static void set_hvm_info_checksum(struct
   100.4   * hvmloader will use this info to set BIOS accordingly
   100.5   */
   100.6  static int set_hvm_info(int xc_handle, uint32_t dom,
   100.7 -                        unsigned long *pfn_list, unsigned int vcpus,
   100.8 +                        xen_pfn_t *pfn_list, unsigned int vcpus,
   100.9                          unsigned int pae, unsigned int acpi, unsigned int apic)
  100.10  {
  100.11      char *va_map;
  100.12 @@ -178,7 +178,7 @@ static int setup_guest(int xc_handle,
  100.13                         unsigned int store_evtchn,
  100.14                         unsigned long *store_mfn)
  100.15  {
  100.16 -    unsigned long *page_array = NULL;
  100.17 +    xen_pfn_t *page_array = NULL;
  100.18      unsigned long count, i;
  100.19      unsigned long long ptr;
  100.20      xc_mmu_t *mmu = NULL;
  100.21 @@ -207,12 +207,12 @@ static int setup_guest(int xc_handle,
  100.22      /* memsize is in megabytes */
  100.23      v_end = (unsigned long long)memsize << 20;
  100.24  
  100.25 -    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
  100.26 +    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
  100.27             "  Loaded HVM loader:    %08lx->%08lx\n"
  100.28             "  TOTAL:                %08lx->%016llx\n",
  100.29             dsi.v_kernstart, dsi.v_kernend,
  100.30             dsi.v_start, v_end);
  100.31 -    printf("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
  100.32 +    IPRINTF("  ENTRY ADDRESS:        %08lx\n", dsi.v_kernentry);
  100.33  
  100.34      if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
  100.35      {
  100.36 @@ -223,7 +223,7 @@ static int setup_guest(int xc_handle,
  100.37          goto error_out;
  100.38      }
  100.39  
  100.40 -    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
  100.41 +    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL )
  100.42      {
  100.43          PERROR("Could not allocate memory.\n");
  100.44          goto error_out;
   101.1 --- a/tools/libxc/xc_ia64_stubs.c	Tue Jun 13 09:00:32 2006 -0600
   101.2 +++ b/tools/libxc/xc_ia64_stubs.c	Tue Jun 13 12:12:24 2006 -0600
   101.3 @@ -57,7 +57,7 @@ xc_plan9_build(int xc_handle,
   101.4  
   101.5  int xc_ia64_get_pfn_list(int xc_handle,
   101.6                           uint32_t domid,
   101.7 -                         unsigned long *pfn_buf,
   101.8 +                         xen_pfn_t *pfn_buf,
   101.9                           unsigned int start_page,
  101.10                           unsigned int nr_pages)
  101.11  {
  101.12 @@ -65,7 +65,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
  101.13      int num_pfns,ret;
  101.14      unsigned int __start_page, __nr_pages;
  101.15      unsigned long max_pfns;
  101.16 -    unsigned long *__pfn_buf;
  101.17 +    xen_pfn_t *__pfn_buf;
  101.18  
  101.19      __start_page = start_page;
  101.20      __nr_pages = nr_pages;
  101.21 @@ -80,7 +80,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
  101.22          set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf);
  101.23  
  101.24          if ( (max_pfns != -1UL)
  101.25 -            && mlock(__pfn_buf, __nr_pages * sizeof(unsigned long)) != 0 )
  101.26 +            && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0 )
  101.27          {
  101.28              PERROR("Could not lock pfn list buffer");
  101.29              return -1;
  101.30 @@ -89,7 +89,7 @@ int xc_ia64_get_pfn_list(int xc_handle,
  101.31          ret = do_dom0_op(xc_handle, &op);
  101.32  
  101.33          if (max_pfns != -1UL)
  101.34 -            (void)munlock(__pfn_buf, __nr_pages * sizeof(unsigned long));
  101.35 +            (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
  101.36  
  101.37          if (max_pfns == -1UL)
  101.38              return 0;
  101.39 @@ -122,10 +122,10 @@ int xc_ia64_copy_to_domain_pages(int xc_
  101.40  {
  101.41      // N.B. gva should be page aligned
  101.42  
  101.43 -    unsigned long *page_array = NULL;
  101.44 +    xen_pfn_t *page_array = NULL;
  101.45      int i;
  101.46  
  101.47 -    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){
  101.48 +    if ( (page_array = malloc(nr_pages * sizeof(xen_pfn_t))) == NULL ){
  101.49          PERROR("Could not allocate memory");
  101.50          goto error_out;
  101.51      }
  101.52 @@ -669,7 +669,7 @@ static int setup_guest(  int xc_handle,
  101.53  
  101.54          vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
  101.55          if (vp_eport < 0) {
  101.56 -            fprintf(stderr, "Couldn't get unbound port from VMX guest.\n");
  101.57 +            DPRINTF("Couldn't get unbound port from VMX guest.\n");
  101.58              goto error_out;
  101.59          }
  101.60          sp->vcpu_iodata[i].vp_eport = vp_eport;
   102.1 --- a/tools/libxc/xc_linux.c	Tue Jun 13 09:00:32 2006 -0600
   102.2 +++ b/tools/libxc/xc_linux.c	Tue Jun 13 12:12:24 2006 -0600
   102.3 @@ -28,7 +28,7 @@ int xc_interface_close(int xc_handle)
   102.4  }
   102.5  
   102.6  void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
   102.7 -                           unsigned long *arr, int num)
   102.8 +                           xen_pfn_t *arr, int num)
   102.9  {
  102.10      privcmd_mmapbatch_t ioctlx;
  102.11      void *addr;
   103.1 --- a/tools/libxc/xc_linux_build.c	Tue Jun 13 09:00:32 2006 -0600
   103.2 +++ b/tools/libxc/xc_linux_build.c	Tue Jun 13 12:12:24 2006 -0600
   103.3 @@ -10,6 +10,7 @@
   103.4  #include "xc_aout9.h"
   103.5  #include <stdlib.h>
   103.6  #include <unistd.h>
   103.7 +#include <inttypes.h>
   103.8  #include <zlib.h>
   103.9  
  103.10  #if defined(__i386__)
  103.11 @@ -136,7 +137,7 @@ static int probeimageformat(const char *
  103.12  int load_initrd(int xc_handle, domid_t dom,
  103.13                  struct initrd_info *initrd,
  103.14                  unsigned long physbase,
  103.15 -                unsigned long *phys_to_mach)
  103.16 +                xen_pfn_t *phys_to_mach)
  103.17  {
  103.18      char page[PAGE_SIZE];
  103.19      unsigned long pfn_start, pfn, nr_pages;
  103.20 @@ -189,7 +190,7 @@ static int setup_pg_tables(int xc_handle
  103.21                             vcpu_guest_context_t *ctxt,
  103.22                             unsigned long dsi_v_start,
  103.23                             unsigned long v_end,
  103.24 -                           unsigned long *page_array,
  103.25 +                           xen_pfn_t *page_array,
  103.26                             unsigned long vpt_start,
  103.27                             unsigned long vpt_end,
  103.28                             unsigned shadow_mode_enabled)
  103.29 @@ -205,9 +206,9 @@ static int setup_pg_tables(int xc_handle
  103.30      alloc_pt(l2tab, vl2tab, pl2tab);
  103.31      vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
  103.32      if (shadow_mode_enabled)
  103.33 -        ctxt->ctrlreg[3] = pl2tab;
  103.34 +        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl2tab >> PAGE_SHIFT);
  103.35      else
  103.36 -        ctxt->ctrlreg[3] = l2tab;
  103.37 +        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l2tab >> PAGE_SHIFT);
  103.38  
  103.39      for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
  103.40      {
  103.41 @@ -251,26 +252,42 @@ static int setup_pg_tables_pae(int xc_ha
  103.42                                 vcpu_guest_context_t *ctxt,
  103.43                                 unsigned long dsi_v_start,
  103.44                                 unsigned long v_end,
  103.45 -                               unsigned long *page_array,
  103.46 +                               xen_pfn_t *page_array,
  103.47                                 unsigned long vpt_start,
  103.48                                 unsigned long vpt_end,
  103.49 -                               unsigned shadow_mode_enabled)
  103.50 +                               unsigned shadow_mode_enabled,
  103.51 +                               unsigned pae_mode)
  103.52  {
  103.53      l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
  103.54      l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
  103.55      l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
  103.56      uint64_t l1tab, l2tab, l3tab, pl1tab, pl2tab, pl3tab;
  103.57 -    unsigned long ppt_alloc, count;
  103.58 +    unsigned long ppt_alloc, count, nmfn;
  103.59  
  103.60      /* First allocate page for page dir. */
  103.61      ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
  103.62  
  103.63 +    if ( pae_mode == PAEKERN_extended_cr3 )
  103.64 +    {
  103.65 +        ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
  103.66 +    }
  103.67 +    else if ( page_array[ppt_alloc] > 0xfffff )
  103.68 +    {
  103.69 +        nmfn = xc_make_page_below_4G(xc_handle, dom, page_array[ppt_alloc]);
  103.70 +        if ( nmfn == 0 )
  103.71 +        {
  103.72 +            DPRINTF("Couldn't get a page below 4GB :-(\n");
  103.73 +            goto error_out;
  103.74 +        }
  103.75 +        page_array[ppt_alloc] = nmfn;
  103.76 +    }
  103.77 +
  103.78      alloc_pt(l3tab, vl3tab, pl3tab);
  103.79      vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
  103.80      if (shadow_mode_enabled)
  103.81 -        ctxt->ctrlreg[3] = pl3tab;
  103.82 +        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl3tab >> PAGE_SHIFT);
  103.83      else
  103.84 -        ctxt->ctrlreg[3] = l3tab;
  103.85 +        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l3tab >> PAGE_SHIFT);
  103.86  
  103.87      for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
  103.88      {
  103.89 @@ -340,7 +357,7 @@ static int setup_pg_tables_64(int xc_han
  103.90                                vcpu_guest_context_t *ctxt,
  103.91                                unsigned long dsi_v_start,
  103.92                                unsigned long v_end,
  103.93 -                              unsigned long *page_array,
  103.94 +                              xen_pfn_t *page_array,
  103.95                                unsigned long vpt_start,
  103.96                                unsigned long vpt_end,
  103.97                                int shadow_mode_enabled)
  103.98 @@ -361,9 +378,9 @@ static int setup_pg_tables_64(int xc_han
  103.99      alloc_pt(l4tab, vl4tab, pl4tab);
 103.100      vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
 103.101      if (shadow_mode_enabled)
 103.102 -        ctxt->ctrlreg[3] = pl4tab;
 103.103 +        ctxt->ctrlreg[3] = xen_pfn_to_cr3(pl4tab >> PAGE_SHIFT);
 103.104      else
 103.105 -        ctxt->ctrlreg[3] = l4tab;
 103.106 +        ctxt->ctrlreg[3] = xen_pfn_to_cr3(l4tab >> PAGE_SHIFT);
 103.107  
 103.108      for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
 103.109      {
 103.110 @@ -451,7 +468,7 @@ static int setup_guest(int xc_handle,
 103.111                         unsigned int console_evtchn, unsigned long *console_mfn,
 103.112                         uint32_t required_features[XENFEAT_NR_SUBMAPS])
 103.113  {
 103.114 -    unsigned long *page_array = NULL;
 103.115 +    xen_pfn_t *page_array = NULL;
 103.116      struct load_funcs load_funcs;
 103.117      struct domain_setup_info dsi;
 103.118      unsigned long vinitrd_start;
 103.119 @@ -478,7 +495,7 @@ static int setup_guest(int xc_handle,
 103.120  
 103.121      start_page = dsi.v_start >> PAGE_SHIFT;
 103.122      pgnr = (v_end - dsi.v_start) >> PAGE_SHIFT;
 103.123 -    if ( (page_array = malloc(pgnr * sizeof(unsigned long))) == NULL )
 103.124 +    if ( (page_array = malloc(pgnr * sizeof(xen_pfn_t))) == NULL )
 103.125      {
 103.126          PERROR("Could not allocate memory");
 103.127          goto error_out;
 103.128 @@ -493,14 +510,14 @@ static int setup_guest(int xc_handle,
 103.129  
 103.130  #define _p(a) ((void *) (a))
 103.131  
 103.132 -    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
 103.133 +    IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
 103.134             " Loaded kernel: %p->%p\n"
 103.135             " Init. ramdisk: %p->%p\n"
 103.136             " TOTAL:         %p->%p\n",
 103.137             _p(dsi.v_kernstart), _p(dsi.v_kernend),
 103.138             _p(vinitrd_start),   _p(vinitrd_end),
 103.139             _p(dsi.v_start),     _p(v_end));
 103.140 -    printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
 103.141 +    IPRINTF(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
 103.142  
 103.143      (load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
 103.144                             &dsi);
 103.145 @@ -524,7 +541,7 @@ static int setup_guest(int xc_handle,
 103.146  
 103.147      *store_mfn = page_array[1];
 103.148      *console_mfn = page_array[2];
 103.149 -    printf("start_info: 0x%lx at 0x%lx, "
 103.150 +    IPRINTF("start_info: 0x%lx at 0x%lx, "
 103.151             "store_mfn: 0x%lx at 0x%lx, "
 103.152             "console_mfn: 0x%lx at 0x%lx\n",
 103.153             page_array[0], nr_pages,
 103.154 @@ -579,11 +596,11 @@ static int compat_check(int xc_handle, s
 103.155      }
 103.156  
 103.157      if (strstr(xen_caps, "xen-3.0-x86_32p")) {
 103.158 -        if (!dsi->pae_kernel) {
 103.159 +        if (dsi->pae_kernel == PAEKERN_no) {
 103.160              ERROR("Non PAE-kernel on PAE host.");
 103.161              return 0;
 103.162          }
 103.163 -    } else if (dsi->pae_kernel) {
 103.164 +    } else if (dsi->pae_kernel != PAEKERN_no) {
 103.165          ERROR("PAE-kernel on non-PAE host.");
 103.166          return 0;
 103.167      }
 103.168 @@ -591,6 +608,16 @@ static int compat_check(int xc_handle, s
 103.169      return 1;
 103.170  }
 103.171  
 103.172 +static inline int increment_ulong(unsigned long *pval, unsigned long inc)
 103.173 +{
 103.174 +    if ( inc >= -*pval )
 103.175 +    {
 103.176 +        ERROR("Value wrapped to zero: image too large?");
 103.177 +        return 0;
 103.178 +    }
 103.179 +    *pval += inc;
 103.180 +    return 1;
 103.181 +}
 103.182  
 103.183  static int setup_guest(int xc_handle,
 103.184                         uint32_t dom,
 103.185 @@ -606,7 +633,7 @@ static int setup_guest(int xc_handle,
 103.186                         unsigned int console_evtchn, unsigned long *console_mfn,
 103.187                         uint32_t required_features[XENFEAT_NR_SUBMAPS])
 103.188  {
 103.189 -    unsigned long *page_array = NULL;
 103.190 +    xen_pfn_t *page_array = NULL;
 103.191      unsigned long count, i, hypercall_pfn;
 103.192      start_info_t *start_info;
 103.193      shared_info_t *shared_info;
 103.194 @@ -617,7 +644,7 @@ static int setup_guest(int xc_handle,
 103.195  
 103.196      unsigned long nr_pt_pages;
 103.197      unsigned long physmap_pfn;
 103.198 -    unsigned long *physmap, *physmap_e;
 103.199 +    xen_pfn_t *physmap, *physmap_e;
 103.200  
 103.201      struct load_funcs load_funcs;
 103.202      struct domain_setup_info dsi;
 103.203 @@ -667,13 +694,14 @@ static int setup_guest(int xc_handle,
 103.204              goto error_out;
 103.205          }
 103.206  
 103.207 -        printf("Supported features  = { %08x }.\n", supported_features[0]);
 103.208 -        printf("Required features   = { %08x }.\n", required_features[0]);
 103.209 +        IPRINTF("Supported features  = { %08x }.\n", supported_features[0]);
 103.210 +        IPRINTF("Required features   = { %08x }.\n", required_features[0]);
 103.211      }
 103.212  
 103.213      for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
 103.214      {
 103.215 -        if ( (supported_features[i]&required_features[i]) != required_features[i] )
 103.216 +        if ( (supported_features[i] & required_features[i]) !=
 103.217 +             required_features[i] )
 103.218          {
 103.219              ERROR("Guest kernel does not support a required feature.");
 103.220              goto error_out;
 103.221 @@ -691,35 +719,64 @@ static int setup_guest(int xc_handle,
 103.222       * which we solve by exhaustive search.
 103.223       */
 103.224      v_end = round_pgup(dsi.v_end);
 103.225 +    if ( v_end == 0 )
 103.226 +    {
 103.227 +        ERROR("End of mapped kernel image too close to end of memory");
 103.228 +        goto error_out;
 103.229 +    }
 103.230      vinitrd_start = v_end;
 103.231 -    v_end += round_pgup(initrd->len);
 103.232 +    if ( !increment_ulong(&v_end, round_pgup(initrd->len)) )
 103.233 +        goto error_out;
 103.234      vphysmap_start = v_end;
 103.235 -    v_end += round_pgup(nr_pages * sizeof(unsigned long));
 103.236 +    if ( !increment_ulong(&v_end, round_pgup(nr_pages * sizeof(long))) )
 103.237 +        goto error_out;
 103.238      vstartinfo_start = v_end;
 103.239 -    v_end += PAGE_SIZE;
 103.240 +    if ( !increment_ulong(&v_end, PAGE_SIZE) )
 103.241 +        goto error_out;
 103.242      vstoreinfo_start = v_end;
 103.243 -    v_end += PAGE_SIZE;
 103.244 +    if ( !increment_ulong(&v_end, PAGE_SIZE) )
 103.245 +        goto error_out;
 103.246      vconsole_start = v_end;
 103.247 -    v_end += PAGE_SIZE;
 103.248 +    if ( !increment_ulong(&v_end, PAGE_SIZE) )
 103.249 +        goto error_out;
 103.250      if ( shadow_mode_enabled ) {
 103.251          vsharedinfo_start = v_end;
 103.252 -        v_end += PAGE_SIZE;