1b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata/*
2b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * This program is free software; you can redistribute it and/or modify
3b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * it under the terms of the GNU General Public License as published by
4b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * the Free Software Foundation; either version 2 of the License, or
5b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * (at your option) any later version.
6b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata *
7b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * This program is distributed in the hope that it will be useful,
8b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * but WITHOUT ANY WARRANTY; without even the implied warranty of
9b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * GNU General Public License for more details.
11b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata *
12b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * You should have received a copy of the GNU General Public License
13b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * along with this program; if not, write to the Free Software
14b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata *
16b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * Copyright (C) IBM Corp. 2006
17b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata *
18b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata */
20b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
21b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata#include <linux/mm.h>
225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
23b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata#include <asm/page.h>
24b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata#include <xen/xencomm.h>
25b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata#include <xen/interface/xen.h>
2675909fd619d15400e7c6d0fc3af09838ee8b166eIsaku Yamahata#include <asm/xen/xencomm.h>	/* for xencomm_is_phys_contiguous() */
27b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
28b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastatic int xencomm_init(struct xencomm_desc *desc,
29b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			void *buffer, unsigned long bytes)
30b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
31b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long recorded = 0;
32b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	int i = 0;
33b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
34b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	while ((recorded < bytes) && (i < desc->nr_addrs)) {
35b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		unsigned long vaddr = (unsigned long)buffer + recorded;
36b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		unsigned long paddr;
37b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		int offset;
38b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		int chunksz;
39b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
40b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		offset = vaddr % PAGE_SIZE; /* handle partial pages */
41b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		chunksz = min(PAGE_SIZE - offset, bytes - recorded);
42b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
43b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		paddr = xencomm_vtop(vaddr);
44b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		if (paddr == ~0UL) {
45b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			printk(KERN_DEBUG "%s: couldn't translate vaddr %lx\n",
46b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			       __func__, vaddr);
47b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			return -EINVAL;
48b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		}
49b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
50b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		desc->address[i++] = paddr;
51b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		recorded += chunksz;
52b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
53b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
54b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (recorded < bytes) {
55b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		printk(KERN_DEBUG
56b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		       "%s: could only translate %ld of %ld bytes\n",
57b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		       __func__, recorded, bytes);
58b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return -ENOSPC;
59b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
60b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
61b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	/* mark remaining addresses invalid (just for safety) */
62b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	while (i < desc->nr_addrs)
63b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		desc->address[i++] = XENCOMM_INVALID;
64b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
65b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	desc->magic = XENCOMM_MAGIC;
66b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
67b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return 0;
68b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
69b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
70b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastatic struct xencomm_desc *xencomm_alloc(gfp_t gfp_mask,
71b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata					  void *buffer, unsigned long bytes)
72b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
73b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	struct xencomm_desc *desc;
74b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long buffer_ulong = (unsigned long)buffer;
75b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long start = buffer_ulong & PAGE_MASK;
76b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long end = (buffer_ulong + bytes) | ~PAGE_MASK;
77b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long nr_addrs = (end - start + 1) >> PAGE_SHIFT;
78b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long size = sizeof(*desc) +
79b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		sizeof(desc->address[0]) * nr_addrs;
80b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
81b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	/*
82b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	 * slab allocator returns at least sizeof(void*) aligned pointer.
83b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	 * When sizeof(*desc) > sizeof(void*), struct xencomm_desc might
84b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	 * cross page boundary.
85b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	 */
86b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (sizeof(*desc) > sizeof(void *)) {
87b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		unsigned long order = get_order(size);
88b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		desc = (struct xencomm_desc *)__get_free_pages(gfp_mask,
89b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata							       order);
90b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		if (desc == NULL)
91b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			return NULL;
92b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
93b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		desc->nr_addrs =
94b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			((PAGE_SIZE << order) - sizeof(struct xencomm_desc)) /
95b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			sizeof(*desc->address);
96b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	} else {
97b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		desc = kmalloc(size, gfp_mask);
98b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		if (desc == NULL)
99b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			return NULL;
100b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
101b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		desc->nr_addrs = nr_addrs;
102b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
103b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return desc;
104b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
105b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
106b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatavoid xencomm_free(struct xencomm_handle *desc)
107b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
108b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (desc && !((ulong)desc & XENCOMM_INLINE_FLAG)) {
109b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		struct xencomm_desc *desc__ = (struct xencomm_desc *)desc;
110b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		if (sizeof(*desc__) > sizeof(void *)) {
111b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			unsigned long size = sizeof(*desc__) +
112b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata				sizeof(desc__->address[0]) * desc__->nr_addrs;
113b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			unsigned long order = get_order(size);
114b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			free_pages((unsigned long)__va(desc), order);
115b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		} else
116b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			kfree(__va(desc));
117b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
118b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
119b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
120b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastatic int xencomm_create(void *buffer, unsigned long bytes,
121b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			  struct xencomm_desc **ret, gfp_t gfp_mask)
122b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
123b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	struct xencomm_desc *desc;
124b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	int rc;
125b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
126b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	pr_debug("%s: %p[%ld]\n", __func__, buffer, bytes);
127b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
128b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (bytes == 0) {
129b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		/* don't create a descriptor; Xen recognizes NULL. */
130b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		BUG_ON(buffer != NULL);
131b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		*ret = NULL;
132b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return 0;
133b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
134b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
135b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	BUG_ON(buffer == NULL); /* 'bytes' is non-zero */
136b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
137b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	desc = xencomm_alloc(gfp_mask, buffer, bytes);
138b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (!desc) {
139b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		printk(KERN_DEBUG "%s failure\n", "xencomm_alloc");
140b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return -ENOMEM;
141b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
142b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
143b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	rc = xencomm_init(desc, buffer, bytes);
144b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (rc) {
145b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		printk(KERN_DEBUG "%s failure: %d\n", "xencomm_init", rc);
146b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		xencomm_free((struct xencomm_handle *)__pa(desc));
147b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return rc;
148b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	}
149b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
150b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	*ret = desc;
151b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return 0;
152b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
153b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
154b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastatic struct xencomm_handle *xencomm_create_inline(void *ptr)
155b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
156b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long paddr;
157b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
15875909fd619d15400e7c6d0fc3af09838ee8b166eIsaku Yamahata	BUG_ON(!xencomm_is_phys_contiguous((unsigned long)ptr));
159b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
160b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	paddr = (unsigned long)xencomm_pa(ptr);
161b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	BUG_ON(paddr & XENCOMM_INLINE_FLAG);
162b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG);
163b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
164b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
165b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata/* "mini" routine, for stack-based communications: */
166b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastatic int xencomm_create_mini(void *buffer,
167b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	unsigned long bytes, struct xencomm_mini *xc_desc,
168b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	struct xencomm_desc **ret)
169b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
170b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	int rc = 0;
171b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	struct xencomm_desc *desc;
172b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	BUG_ON(((unsigned long)xc_desc) % sizeof(*xc_desc) != 0);
173b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
174b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	desc = (void *)xc_desc;
175b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
176b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	desc->nr_addrs = XENCOMM_MINI_ADDRS;
177b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
178b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	rc = xencomm_init(desc, buffer, bytes);
179b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (!rc)
180b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		*ret = desc;
181b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
182b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return rc;
183b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
184b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
185b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastruct xencomm_handle *xencomm_map(void *ptr, unsigned long bytes)
186b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
187b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	int rc;
188b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	struct xencomm_desc *desc;
189b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
19075909fd619d15400e7c6d0fc3af09838ee8b166eIsaku Yamahata	if (xencomm_is_phys_contiguous((unsigned long)ptr))
191b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return xencomm_create_inline(ptr);
192b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
193b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	rc = xencomm_create(ptr, bytes, &desc, GFP_KERNEL);
194b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
195b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (rc || desc == NULL)
196b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return NULL;
197b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
198b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return xencomm_pa(desc);
199b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
200b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
201b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahatastruct xencomm_handle *__xencomm_map_no_alloc(void *ptr, unsigned long bytes,
202b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata			struct xencomm_mini *xc_desc)
203b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata{
204b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	int rc;
205b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	struct xencomm_desc *desc = NULL;
206b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
20775909fd619d15400e7c6d0fc3af09838ee8b166eIsaku Yamahata	if (xencomm_is_phys_contiguous((unsigned long)ptr))
208b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return xencomm_create_inline(ptr);
209b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
210b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	rc = xencomm_create_mini(ptr, bytes, xc_desc,
211b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata				&desc);
212b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
213b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	if (rc)
214b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata		return NULL;
215b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata
216b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata	return xencomm_pa(desc);
217b15993fcc1bf15f717fb4414b32e4a11534dfdc4Isaku Yamahata}
218