ia64/linux-2.6.18-xen.hg

view drivers/xen/usbfront/usbfront-hcd.c @ 845:4c7eb2e71e9d

pvusb: Fix license headers.

Signed-off-by: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:11:23 2009 +0100 (2009-03-31)
parents 8f996719f2ff
children
line source
1 /*
2 * usbfront-hcd.c
3 *
4 * Xen USB Virtual Host Controller driver
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 "usbfront.h"
47 #include "usbfront-dbg.c"
48 #include "usbfront-hub.c"
49 #include "usbfront-q.c"
51 static void xenhcd_watchdog(unsigned long param)
52 {
53 struct usbfront_info *info = (struct usbfront_info *) param;
54 unsigned long flags;
56 spin_lock_irqsave(&info->lock, flags);
57 if (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);
61 }
62 spin_unlock_irqrestore(&info->lock, flags);
63 }
65 /*
66 * one-time HC init
67 */
68 static int xenhcd_setup(struct usb_hcd *hcd)
69 {
70 struct usbfront_info *info = hcd_to_info(hcd);
72 spin_lock_init(&info->lock);
73 INIT_LIST_HEAD(&info->pending_urbs);
74 INIT_LIST_HEAD(&info->inprogress_urbs);
75 INIT_LIST_HEAD(&info->unlinked_urbs);
76 init_timer(&info->watchdog);
77 info->watchdog.function = xenhcd_watchdog;
78 info->watchdog.data = (unsigned long) info;
79 return 0;
80 }
82 /*
83 * start HC running
84 */
85 static int xenhcd_run(struct usb_hcd *hcd)
86 {
87 hcd->uses_new_polling = 1;
88 hcd->poll_rh = 0;
89 hcd->state = HC_STATE_RUNNING;
90 create_debug_file(hcd_to_info(hcd));
91 return 0;
92 }
94 /*
95 * stop running HC
96 */
97 static void xenhcd_stop(struct usb_hcd *hcd)
98 {
99 struct usbfront_info *info = hcd_to_info(hcd);
101 del_timer_sync(&info->watchdog);
102 remove_debug_file(info);
103 spin_lock_irq(&info->lock);
104 /*
105 * TODO: port power off, cancel all urbs.
106 */
108 if (HC_IS_RUNNING(hcd->state))
109 hcd->state = HC_STATE_HALT;
110 spin_unlock_irq(&info->lock);
111 }
113 /*
114 * TODO: incomplete suspend/resume functions!
115 */
116 #if 0
117 #ifdef CONFIG_PM
118 /*
119 * suspend running HC
120 */
121 static int xenhcd_suspend(struct usb_hcd *hcd, pm_message_t message)
122 {
123 struct usbfront_info *info = hcd_to_info(hcd);
124 unsigned long flags;
125 int ret = 0;
127 spin_lock_irqsave(&info->lock, flags);
128 if (hcd->state != HC_STATE_SUSPENDED) {
129 ret = -EINVAL;
130 goto done;
131 }
133 /*
134 * TODO:
135 * canceling all transfer, clear all hc queue,
136 * stop kthread,
137 */
139 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
140 done:
141 spin_unlock_irqrestore(&info->lock, flags);
143 return ret;
144 }
146 /*
147 * resume HC
148 */
149 static int xenhcd_resume(struct usb_hcd *hcd)
150 {
151 struct usbfront_info *info = hcd_to_info(hcd);
152 int ret = -EINVAL;
154 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
156 /*
157 * TODO:
158 * re-init HC.
159 * resume all roothub ports.
160 */
162 return ret;
163 }
164 #endif
165 #endif
167 /*
168 * called as .urb_enqueue()
169 * non-error returns are promise to giveback the urb later
170 */
171 static int xenhcd_urb_enqueue(struct usb_hcd *hcd,
172 struct usb_host_endpoint *ep,
173 struct urb *urb,
174 gfp_t mem_flags)
175 {
176 struct usbfront_info *info = hcd_to_info(hcd);
177 struct urb_priv *urbp;
178 unsigned long flags;
179 int ret = 0;
181 spin_lock_irqsave(&info->lock, flags);
183 urbp = alloc_urb_priv(urb);
184 if (!urbp) {
185 ret = -ENOMEM;
186 goto done;
187 }
189 ret = xenhcd_submit_urb(info, urbp);
190 if (ret != 0)
191 free_urb_priv(urbp);
193 done:
194 spin_unlock_irqrestore(&info->lock, flags);
195 return ret;
196 }
198 /*
199 * called as .urb_dequeue()
200 *
201 * just mark the urb as unlinked
202 * if the urb is in pending_urbs, move to unlinked_urbs
203 * TODO:
204 * canceling the urb transfer in backend
205 */
206 static int xenhcd_urb_dequeue(struct usb_hcd *hcd,
207 struct urb *urb)
208 {
209 struct usbfront_info *info = hcd_to_info(hcd);
210 struct urb_priv *urbp;
211 unsigned long flags;
212 int ret = 0;
214 spin_lock_irqsave(&info->lock, flags);
216 urbp = urb->hcpriv;
217 if (!urbp)
218 goto done;
220 ret = xenhcd_unlink_urb(info, urbp);
222 done:
223 spin_unlock_irqrestore(&info->lock, flags);
224 return ret;
225 }
227 /*
228 * called from usb_get_current_frame_number(),
229 * but, almost all drivers not use such function.
230 */
231 static int xenhcd_get_frame(struct usb_hcd *hcd)
232 {
233 /* it means error, but probably no problem :-) */
234 return 0;
235 }
237 /*
238 * TODO:
239 * suspend/resume whole hcd and roothub
240 */
241 static const char hcd_name[] = "xen_hcd";
243 struct hc_driver usbfront_hc_driver = {
244 .description = hcd_name,
245 .product_desc = DRIVER_DESC,
246 .hcd_priv_size = sizeof(struct usbfront_info),
247 .flags = HCD_USB2,
249 /*
250 * basic HC lifecycle operations
251 */
252 .reset = xenhcd_setup,
253 .start = xenhcd_run,
254 .stop = xenhcd_stop,
255 #if 0
256 #ifdef CONFIG_PM
257 .suspend = xenhcd_suspend,
258 .resume = xenhcd_resume,
259 #endif
260 #endif
261 /*
262 * managing urb I/O
263 */
264 .urb_enqueue = xenhcd_urb_enqueue,
265 .urb_dequeue = xenhcd_urb_dequeue,
266 .get_frame_number = xenhcd_get_frame,
268 /*
269 * root hub operations
270 */
271 .hub_status_data = xenhcd_hub_status_data,
272 .hub_control = xenhcd_hub_control,
273 #if 0
274 #ifdef CONFIG_PM
275 .bus_suspend = xenhcd_bus_suspend,
276 .bus_resume = xenhcd_bus_resume,
277 #endif
278 #endif
279 };