Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / usbfront / usbfront.h
1 /*
2  * usbfront.h
3  *
4  * This file is part of 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  */
45
46 #ifndef __XEN_USBFRONT_H__
47 #define __XEN_USBFRONT_H__
48
49 #include <linux/module.h>
50 #include <linux/usb.h>
51 #include <linux/list.h>
52 #include <linux/kthread.h>
53 #include <linux/wait.h>
54 #include <linux/usb/hcd.h>
55 #include <asm/io.h>
56 #include <xen/xenbus.h>
57 #include <xen/evtchn.h>
58 #include <xen/gnttab.h>
59 #include <xen/interface/xen.h>
60 #include <xen/interface/io/usbif.h>
61
62 static inline struct usbfront_info *hcd_to_info(struct usb_hcd *hcd)
63 {
64         return (struct usbfront_info *) (hcd->hcd_priv);
65 }
66
67 static inline struct usb_hcd *info_to_hcd(struct usbfront_info *info)
68 {
69         return container_of((void *) info, struct usb_hcd, hcd_priv);
70 }
71
72 /* Private per-URB data */
73 struct urb_priv {
74         struct list_head list;
75         struct urb *urb;
76         int req_id;     /* RING_REQUEST id for submitting */
77         int unlink_req_id; /* RING_REQUEST id for unlinking */
78         int status;
79         unsigned unlinked:1; /* dequeued marker */
80 };
81
82 /* virtual roothub port status */
83 struct rhport_status {
84         u32 status;
85         unsigned resuming:1; /* in resuming */
86         unsigned c_connection:1; /* connection changed */
87         unsigned long timeout;
88 };
89
90 /* status of attached device */
91 struct vdevice_status {
92         int devnum;
93         enum usb_device_state status;
94         enum usb_device_speed speed;
95 };
96
97 /* RING request shadow */
98 struct usb_shadow {
99         usbif_urb_request_t req;
100         struct urb *urb;
101 };
102
103 /* statistics for tuning, monitoring, ... */
104 struct xenhcd_stats {
105         unsigned long ring_full; /* RING_FULL conditions */
106         unsigned long complete; /* normal givebacked urbs */
107         unsigned long unlink; /* unlinked urbs */
108 };
109
110 struct usbfront_info {
111         /* Virtual Host Controller has 4 urb queues */
112         struct list_head pending_submit_list;
113         struct list_head pending_unlink_list;
114         struct list_head in_progress_list;
115         struct list_head giveback_waiting_list;
116
117         spinlock_t lock;
118
119         /* timer that kick pending and giveback waiting urbs */
120         struct timer_list watchdog;
121         unsigned long actions;
122
123         /* virtual root hub */
124         int rh_numports;
125         struct rhport_status ports[USB_MAXCHILDREN];
126         struct vdevice_status devices[USB_MAXCHILDREN];
127
128         /* Xen related staff */
129         struct xenbus_device *xbdev;
130         int urb_ring_ref;
131         int conn_ring_ref;
132         usbif_urb_front_ring_t urb_ring;
133         usbif_conn_front_ring_t conn_ring;
134
135         unsigned int irq; /* event channel */
136         struct usb_shadow shadow[USB_URB_RING_SIZE];
137         unsigned long shadow_free;
138
139         /* RING_RESPONSE thread */
140         struct task_struct *kthread;
141         wait_queue_head_t wq;
142         unsigned int waiting_resp;
143
144         /* xmit statistics */
145 #ifdef XENHCD_STATS
146         struct xenhcd_stats stats;
147 #define COUNT(x) do { (x)++; } while (0)
148 #else
149 #define COUNT(x) do {} while (0)
150 #endif
151 };
152
153 #define XENHCD_RING_JIFFIES (HZ/200)
154 #define XENHCD_SCAN_JIFFIES 1
155
156 enum xenhcd_timer_action {
157         TIMER_RING_WATCHDOG,
158         TIMER_SCAN_PENDING_URBS,
159 };
160
161 static inline void
162 timer_action_done(struct usbfront_info *info, enum xenhcd_timer_action action)
163 {
164         clear_bit(action, &info->actions);
165 }
166
167 static inline void
168 timer_action(struct usbfront_info *info, enum xenhcd_timer_action action)
169 {
170         if (timer_pending(&info->watchdog)
171                         && test_bit(TIMER_SCAN_PENDING_URBS, &info->actions))
172                 return;
173
174         if (!test_and_set_bit(action, &info->actions)) {
175                 unsigned long t;
176
177                 switch (action) {
178                 case TIMER_RING_WATCHDOG:
179                         t = XENHCD_RING_JIFFIES;
180                         break;
181                 default:
182                         t = XENHCD_SCAN_JIFFIES;
183                         break;
184                 }
185                 mod_timer(&info->watchdog, t + jiffies);
186         }
187 }
188
189 extern struct kmem_cache *xenhcd_urbp_cachep;
190 extern struct hc_driver xen_usb20_hc_driver;
191 extern struct hc_driver xen_usb11_hc_driver;
192 irqreturn_t xenhcd_int(int irq, void *dev_id);
193 void xenhcd_rhport_state_change(struct usbfront_info *info,
194                                 int port, enum usb_device_speed speed);
195 int xenhcd_schedule(void *arg);
196
197 #endif /* __XEN_USBFRONT_H__ */