4 * Xen USB Virtual Host Controller driver
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.
47 #include "usbfront-dbg.c"
48 #include "usbfront-hub.c"
49 #include "usbfront-q.c"
51 static void xenhcd_watchdog(unsigned long param)
53 struct usbfront_info *info = (struct usbfront_info *) param;
56 spin_lock_irqsave(&info->lock, flags);
57 if (likely(HC_IS_RUNNING(info_to_hcd(info)->state))) {
58 timer_action_done(info, TIMER_RING_WATCHDOG);
59 xenhcd_giveback_unlinked_urbs(info);
60 xenhcd_kick_pending_urbs(info);
62 spin_unlock_irqrestore(&info->lock, flags);
68 static int xenhcd_setup(struct usb_hcd *hcd)
70 struct usbfront_info *info = hcd_to_info(hcd);
72 spin_lock_init(&info->lock);
73 INIT_LIST_HEAD(&info->pending_submit_list);
74 INIT_LIST_HEAD(&info->pending_unlink_list);
75 INIT_LIST_HEAD(&info->in_progress_list);
76 INIT_LIST_HEAD(&info->giveback_waiting_list);
77 init_timer(&info->watchdog);
78 info->watchdog.function = xenhcd_watchdog;
79 info->watchdog.data = (unsigned long) info;
86 static int xenhcd_run(struct usb_hcd *hcd)
88 hcd->uses_new_polling = 1;
89 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
90 hcd->state = HC_STATE_RUNNING;
91 create_debug_file(hcd_to_info(hcd));
98 static void xenhcd_stop(struct usb_hcd *hcd)
100 struct usbfront_info *info = hcd_to_info(hcd);
102 del_timer_sync(&info->watchdog);
103 remove_debug_file(info);
104 spin_lock_irq(&info->lock);
105 /* cancel all urbs */
106 hcd->state = HC_STATE_HALT;
107 xenhcd_cancel_all_enqueued_urbs(info);
108 xenhcd_giveback_unlinked_urbs(info);
109 spin_unlock_irq(&info->lock);
113 * called as .urb_enqueue()
114 * non-error returns are promise to giveback the urb later
116 static int xenhcd_urb_enqueue(struct usb_hcd *hcd,
120 struct usbfront_info *info = hcd_to_info(hcd);
121 struct urb_priv *urbp;
125 spin_lock_irqsave(&info->lock, flags);
127 urbp = alloc_urb_priv(urb);
134 ret = xenhcd_submit_urb(info, urbp);
139 spin_unlock_irqrestore(&info->lock, flags);
144 * called as .urb_dequeue()
146 static int xenhcd_urb_dequeue(struct usb_hcd *hcd,
147 struct urb *urb, int status)
149 struct usbfront_info *info = hcd_to_info(hcd);
150 struct urb_priv *urbp;
154 spin_lock_irqsave(&info->lock, flags);
160 urbp->status = status;
161 ret = xenhcd_unlink_urb(info, urbp);
164 spin_unlock_irqrestore(&info->lock, flags);
169 * called from usb_get_current_frame_number(),
170 * but, almost all drivers not use such function.
172 static int xenhcd_get_frame(struct usb_hcd *hcd)
174 /* it means error, but probably no problem :-) */
178 static const char hcd_name[] = "xen_hcd";
180 struct hc_driver xen_usb20_hc_driver = {
181 .description = hcd_name,
182 .product_desc = "Xen USB2.0 Virtual Host Controller",
183 .hcd_priv_size = sizeof(struct usbfront_info),
186 /* basic HC lifecycle operations */
187 .reset = xenhcd_setup,
191 /* managing urb I/O */
192 .urb_enqueue = xenhcd_urb_enqueue,
193 .urb_dequeue = xenhcd_urb_dequeue,
194 .get_frame_number = xenhcd_get_frame,
196 /* root hub operations */
197 .hub_status_data = xenhcd_hub_status_data,
198 .hub_control = xenhcd_hub_control,
201 .bus_suspend = xenhcd_bus_suspend,
202 .bus_resume = xenhcd_bus_resume,
207 struct hc_driver xen_usb11_hc_driver = {
208 .description = hcd_name,
209 .product_desc = "Xen USB1.1 Virtual Host Controller",
210 .hcd_priv_size = sizeof(struct usbfront_info),
213 /* basic HC lifecycle operations */
214 .reset = xenhcd_setup,
218 /* managing urb I/O */
219 .urb_enqueue = xenhcd_urb_enqueue,
220 .urb_dequeue = xenhcd_urb_dequeue,
221 .get_frame_number = xenhcd_get_frame,
223 /* root hub operations */
224 .hub_status_data = xenhcd_hub_status_data,
225 .hub_control = xenhcd_hub_control,
228 .bus_suspend = xenhcd_bus_suspend,
229 .bus_resume = xenhcd_bus_resume,