4 * Xen USB backend interface management.
6 * Copyright (C) 2009, FUJITSU LABORATORIES LTD.
7 * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
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.
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.
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/>.
24 * When distributed separately from the Linux kernel or incorporated into
25 * other software packages, subject to the following license:
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:
34 * The above copyright notice and this permission notice shall be included in
35 * all copies or substantial portions of the Software.
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.
46 #include <linux/vmalloc.h>
48 #include <xen/evtchn.h>
50 static LIST_HEAD(usbif_list);
51 static DEFINE_SPINLOCK(usbif_list_lock);
53 usbif_t *find_usbif(domid_t domid, unsigned int handle)
59 spin_lock_irqsave(&usbif_list_lock, flags);
60 list_for_each_entry(usbif, &usbif_list, usbif_list) {
61 if (usbif->domid == domid
62 && usbif->handle == handle) {
67 spin_unlock_irqrestore(&usbif_list_lock, flags);
75 usbif_t *usbif_alloc(domid_t domid, unsigned int handle)
81 usbif = kzalloc(sizeof(usbif_t), GFP_KERNEL);
86 usbif->handle = handle;
87 spin_lock_init(&usbif->urb_ring_lock);
88 spin_lock_init(&usbif->conn_ring_lock);
89 atomic_set(&usbif->refcnt, 0);
90 init_waitqueue_head(&usbif->wq);
91 init_waitqueue_head(&usbif->waiting_to_free);
92 spin_lock_init(&usbif->stub_lock);
93 INIT_LIST_HEAD(&usbif->stub_list);
94 spin_lock_init(&usbif->addr_lock);
95 for (i = 0; i < USB_DEV_ADDR_SIZE; i++)
96 usbif->addr_table[i] = NULL;
98 spin_lock_irqsave(&usbif_list_lock, flags);
99 list_add(&usbif->usbif_list, &usbif_list);
100 spin_unlock_irqrestore(&usbif_list_lock, flags);
105 int usbif_map(usbif_t *usbif, grant_ref_t urb_ring_ref,
106 grant_ref_t conn_ring_ref, evtchn_port_t evtchn)
109 struct vm_struct *area;
110 usbif_urb_sring_t *urb_sring;
111 usbif_conn_sring_t *conn_sring;
116 area = xenbus_map_ring_valloc(usbif->xbdev, urb_ring_ref);
118 return PTR_ERR(area);
119 usbif->urb_ring_area = area;
120 area = xenbus_map_ring_valloc(usbif->xbdev, conn_ring_ref);
125 usbif->conn_ring_area = area;
127 err = bind_interdomain_evtchn_to_irqhandler(
128 usbif->domid, evtchn, usbbk_be_int, 0,
129 "usbif-backend", usbif);
134 urb_sring = (usbif_urb_sring_t *) usbif->urb_ring_area->addr;
135 BACK_RING_INIT(&usbif->urb_ring, urb_sring, PAGE_SIZE);
137 conn_sring = (usbif_conn_sring_t *) usbif->conn_ring_area->addr;
138 BACK_RING_INIT(&usbif->conn_ring, conn_sring, PAGE_SIZE);
143 xenbus_unmap_ring_vfree(usbif->xbdev, usbif->conn_ring_area);
145 xenbus_unmap_ring_vfree(usbif->xbdev, usbif->urb_ring_area);
150 void usbif_disconnect(usbif_t *usbif)
152 struct usbstub *stub, *tmp;
155 if (usbif->xenusbd) {
156 kthread_stop(usbif->xenusbd);
157 usbif->xenusbd = NULL;
160 spin_lock_irqsave(&usbif->stub_lock, flags);
161 list_for_each_entry_safe(stub, tmp, &usbif->stub_list, dev_list) {
162 usbbk_unlink_urbs(stub);
163 detach_device_without_lock(usbif, stub);
165 spin_unlock_irqrestore(&usbif->stub_lock, flags);
167 wait_event(usbif->waiting_to_free, atomic_read(&usbif->refcnt) == 0);
170 unbind_from_irqhandler(usbif->irq, usbif);
174 if (usbif->urb_ring.sring) {
175 xenbus_unmap_ring_vfree(usbif->xbdev, usbif->urb_ring_area);
176 xenbus_unmap_ring_vfree(usbif->xbdev, usbif->conn_ring_area);
177 usbif->urb_ring.sring = NULL;
178 usbif->conn_ring.sring = NULL;
182 void usbif_free(usbif_t *usbif)
186 spin_lock_irqsave(&usbif_list_lock, flags);
187 list_del(&usbif->usbif_list);
188 spin_unlock_irqrestore(&usbif_list_lock, flags);