ia64/linux-2.6.18-xen.hg

view drivers/xen/usbback/interface.c @ 912:dd42cdb0ab89

[IA64] Build blktap2 driver by default in x86 builds.

add CONFIG_XEN_BLKDEV_TAP2=y to buildconfigs/linux-defconfig_xen_ia64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Mon Jun 29 12:09:16 2009 +0900 (2009-06-29)
parents 4c7eb2e71e9d
children
line source
1 /*
2 * interface.c
3 *
4 * Xen USB backend interface management.
5 *
6 * Copyright (C) 2009, FUJITSU LABORATORIES LTD.
7 * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 *
22 * or, by your choice,
23 *
24 * When distributed separately from the Linux kernel or incorporated into
25 * other software packages, subject to the following license:
26 *
27 * Permission is hereby granted, free of charge, to any person obtaining a copy
28 * of this software and associated documentation files (the "Software"), to
29 * deal in the Software without restriction, including without limitation the
30 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
31 * sell copies of the Software, and to permit persons to whom the Software is
32 * furnished to do so, subject to the following conditions:
33 *
34 * The above copyright notice and this permission notice shall be included in
35 * all copies or substantial portions of the Software.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43 * DEALINGS IN THE SOFTWARE.
44 */
46 #include "usbback.h"
48 static LIST_HEAD(usbif_list);
49 static DEFINE_SPINLOCK(usbif_list_lock);
51 usbif_t *find_usbif(int dom_id, int dev_id)
52 {
53 usbif_t *usbif;
54 int found = 0;
55 unsigned long flags;
57 spin_lock_irqsave(&usbif_list_lock, flags);
58 list_for_each_entry(usbif, &usbif_list, usbif_list) {
59 if (usbif->domid == dom_id
60 && usbif->handle == dev_id) {
61 found = 1;
62 break;
63 }
64 }
65 spin_unlock_irqrestore(&usbif_list_lock, flags);
67 if (found)
68 return usbif;
70 return NULL;
71 }
73 usbif_t *usbif_alloc(domid_t domid, unsigned int handle)
74 {
75 usbif_t *usbif;
76 unsigned long flags;
77 int i;
79 usbif = kzalloc(sizeof(usbif_t), GFP_KERNEL);
80 if (!usbif)
81 return NULL;
83 usbif->domid = domid;
84 usbif->handle = handle;
85 spin_lock_init(&usbif->ring_lock);
86 atomic_set(&usbif->refcnt, 0);
87 init_waitqueue_head(&usbif->wq);
88 init_waitqueue_head(&usbif->waiting_to_free);
89 spin_lock_init(&usbif->plug_lock);
90 INIT_LIST_HEAD(&usbif->plugged_devices);
91 spin_lock_init(&usbif->addr_lock);
92 for (i = 0; i < USB_DEV_ADDR_SIZE; i++) {
93 usbif->addr_table[i] = NULL;
94 }
96 spin_lock_irqsave(&usbif_list_lock, flags);
97 list_add(&usbif->usbif_list, &usbif_list);
98 spin_unlock_irqrestore(&usbif_list_lock, flags);
100 return usbif;
101 }
103 static int map_frontend_page(usbif_t *usbif, unsigned long shared_page)
104 {
105 struct gnttab_map_grant_ref op;
107 gnttab_set_map_op(&op, (unsigned long)usbif->ring_area->addr,
108 GNTMAP_host_map, shared_page, usbif->domid);
110 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
111 BUG();
113 if (op.status) {
114 printk(KERN_ERR "grant table operation failure\n");
115 return op.status;
116 }
118 usbif->shmem_ref = shared_page;
119 usbif->shmem_handle = op.handle;
121 return 0;
122 }
124 static void unmap_frontend_page(usbif_t *usbif)
125 {
126 struct gnttab_unmap_grant_ref op;
128 gnttab_set_unmap_op(&op, (unsigned long)usbif->ring_area->addr,
129 GNTMAP_host_map, usbif->shmem_handle);
131 if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
132 BUG();
133 }
135 int usbif_map(usbif_t *usbif, unsigned long shared_page, unsigned int evtchn)
136 {
137 int err;
138 usbif_sring_t *sring;
140 if (usbif->irq)
141 return 0;
143 if ((usbif->ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
144 return -ENOMEM;
146 err = map_frontend_page(usbif, shared_page);
147 if (err) {
148 free_vm_area(usbif->ring_area);
149 return err;
150 }
152 sring = (usbif_sring_t *) usbif->ring_area->addr;
153 BACK_RING_INIT(&usbif->ring, sring, PAGE_SIZE);
155 err = bind_interdomain_evtchn_to_irqhandler(
156 usbif->domid, evtchn, usbbk_be_int, 0, "usbif-backend", usbif);
157 if (err < 0)
158 {
159 unmap_frontend_page(usbif);
160 free_vm_area(usbif->ring_area);
161 usbif->ring.sring = NULL;
162 return err;
163 }
164 usbif->irq = err;
166 return 0;
167 }
169 void usbif_disconnect(usbif_t *usbif)
170 {
171 struct usbstub *stub, *tmp;
172 unsigned long flags;
174 if (usbif->xenusbd) {
175 kthread_stop(usbif->xenusbd);
176 usbif->xenusbd = NULL;
177 }
179 spin_lock_irqsave(&usbif->plug_lock, flags);
180 list_for_each_entry_safe(stub, tmp, &usbif->plugged_devices, plugged_list) {
181 usbbk_unlink_urbs(stub);
182 detach_device_without_lock(usbif, stub);
183 }
184 spin_unlock_irqrestore(&usbif->plug_lock, flags);
186 wait_event(usbif->waiting_to_free, atomic_read(&usbif->refcnt) == 0);
188 if (usbif->irq) {
189 unbind_from_irqhandler(usbif->irq, usbif);
190 usbif->irq = 0;
191 }
193 if (usbif->ring.sring) {
194 unmap_frontend_page(usbif);
195 free_vm_area(usbif->ring_area);
196 usbif->ring.sring = NULL;
197 }
198 }
200 void usbif_free(usbif_t *usbif)
201 {
202 unsigned long flags;
204 spin_lock_irqsave(&usbif_list_lock, flags);
205 list_del(&usbif->usbif_list);
206 spin_unlock_irqrestore(&usbif_list_lock, flags);
207 kfree(usbif);
208 }