win-pvdrivers

view xenusb/xenusb.h @ 1031:329b9b9d47ec

re-enable xenusb. compiles but untested.
author James Harper <james.harper@bendigoit.com.au>
date Thu Feb 21 20:37:38 2013 +1100 (2013-02-21)
parents ea3c61839ff5
children
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #pragma warning(disable: 4127)
22 #pragma warning(disable : 4200) // zero-sized array
24 #if !defined(_XENUSB_H_)
25 #define _XENUSB_H_
27 #define __attribute__(arg) /* empty */
29 #define ECONNRESET 104
30 #define ESHUTDOWN 108
31 #define EINPROGRESS 115
32 #define EISCONN 127
34 #include <ntifs.h>
35 #include <ntddk.h>
37 #define DDKAPI
38 //#include <wdm.h>
39 #include <wdf.h>
40 #include <initguid.h>
41 #include <wdmguid.h>
42 #include <errno.h>
43 #define NTSTRSAFE_LIB
44 #include <ntstrsafe.h>
45 #include <liblfds.h>
47 #define __DRIVER_NAME "XenUSB"
49 #include <xen_windows.h>
50 #include <io/ring.h>
51 #include <io/usbif.h>
52 #include <io/xenbus.h>
53 #include <usb.h>
54 #include <usbioctl.h>
55 #include <usbdlib.h>
56 #include <hubbusif.h>
57 #include <usbbusif.h>
59 #define C_HUB_LOCAL_POWER 0
60 #define C_HUB_OVER_CURRENT 1
61 #define PORT_CONNECTION 0
62 #define PORT_ENABLE 1
63 #define PORT_SUSPEND 2
64 #define PORT_OVER_CURRENT 3
65 #define PORT_RESET 4
66 #define PORT_POWER 8
67 #define PORT_LOW_SPEED 9
68 #define PORT_HIGH_SPEED 10
69 #define C_PORT_CONNECTION 16
70 #define C_PORT_ENABLE 17
71 #define C_PORT_SUSPEND 18
72 #define C_PORT_OVER_CURRENT 19
73 #define C_PORT_RESET 20
74 #define PORT_TEST 21
75 #define PORT_INDICATOR 22
77 #define XENUSB_POOL_TAG (ULONG)'XenU'
79 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
81 #define CHILD_STATE_EMPTY 0
82 #define CHILD_STATE_DELETED 1
83 #define CHILD_STATE_ADDED 2
85 #define LINUX_PIPE_DIRECTION_OUT 0x00000000
86 #define LINUX_PIPE_DIRECTION_IN 0x00000080
88 /* these are linux definitions - different to usb standard */
89 #define LINUX_PIPE_TYPE_ISOC 0x00000000
90 #define LINUX_PIPE_TYPE_INTR 0x40000000
91 #define LINUX_PIPE_TYPE_CTRL 0x80000000
92 #define LINUX_PIPE_TYPE_BULK 0xC0000000
94 /*
95 * urb->transfer_flags:
96 */
97 #define LINUX_URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
98 #define LINUX_URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
99 #define LINUX_URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
100 #define LINUX_URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
101 #define LINUX_URB_NO_FSBR 0x0020 /* UHCI-specific */
102 #define LINUX_URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
103 #define LINUX_URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
105 struct _pvurb;
106 struct _partial_pvurb;
107 typedef struct _pvurb pvurb_t;
108 typedef struct _partial_pvurb partial_pvurb_t;
110 /* needs to be at least USB_URB_RING_SIZE number of requests available */
111 #define MAX_REQ_ID_COUNT 64
112 #define REQ_ID_COUNT min(MAX_REQ_ID_COUNT, USB_URB_RING_SIZE)
114 /*
115 for IOCTL_PVUSB_SUBMIT_URB, the pvusb_urb_t struct is passed as Parameters.Others.Arg1
116 req must have pipe, transfer_flags, buffer_length, and u fields filled in
117 */
119 #define IOCTL_INTERNAL_PVUSB_SUBMIT_URB CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
121 struct _partial_pvurb {
122 LIST_ENTRY entry;
123 pvurb_t *pvurb;
124 partial_pvurb_t *other_partial_pvurb; /* link to the cancelled or cancelling partial_pvurb */
125 usbif_urb_request_t req;
126 usbif_urb_response_t rsp;
127 PMDL mdl;
128 BOOLEAN on_ring; /* is (or has been) on the hardware ring */
129 };
131 struct _pvurb {
132 /* set by xenusb_devurb.c */
133 usbif_urb_request_t req; /* only pipe, transfer_flags, isoc/intr filled out by submitter */
134 PMDL mdl; /* can be null for requests with no data */
135 /* set by xenusb_fdo.c */
136 usbif_urb_response_t rsp; /* only status, actual_length, error_count valid */
137 NTSTATUS status;
138 WDFREQUEST request;
139 ULONG ref; /* reference counting */
140 ULONG total_length;
141 pvurb_t *next; /* collect then process responses as they come off the ring */
142 };
144 struct _xenusb_endpoint_t;
145 struct _xenusb_interface_t;
146 struct _xenusb_config_t;
147 struct _xenusb_device_t;
148 typedef struct _xenusb_endpoint_t xenusb_endpoint_t, *pxenusb_endpoint_t;
149 typedef struct _xenusb_interface_t xenusb_interface_t;
150 typedef struct _xenusb_config_t xenusb_config_t;
151 typedef struct _xenusb_device_t xenusb_device_t;
153 typedef struct _xenusb_endpoint_t {
154 xenusb_interface_t *interface;
155 ULONG pipe_value;
156 WDFQUEUE queue;
157 WDFSPINLOCK lock;
158 USB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
159 };
160 //WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pxenusb_endpoint_t, GetEndpoint)
162 typedef struct _xenusb_interface_t {
163 xenusb_config_t *config;
164 USB_INTERFACE_DESCRIPTOR interface_descriptor;
165 xenusb_endpoint_t *endpoints[0];
166 } xenusb_interface_t;
168 typedef struct _xenusb_config_t {
169 xenusb_device_t *device;
170 USB_CONFIGURATION_DESCRIPTOR config_descriptor;
171 PUCHAR config_descriptor_all;
172 xenusb_interface_t *interfaces[0];
173 } xenusb_config_t;
175 typedef struct _xenusb_device_t {
176 WDFDEVICE pdo_device;
177 UCHAR address;
178 USB_DEVICE_DESCRIPTOR device_descriptor;
179 ULONG port_number;
180 WDFQUEUE urb_queue;
181 USB_DEVICE_SPEED device_speed;
182 USB_DEVICE_TYPE device_type;
183 xenusb_config_t *active_config;
184 xenusb_interface_t *active_interface;
185 xenusb_config_t **configs; /* pointer to an array of configs */
186 } xenusb_device_t;
188 #define USB_PORT_TYPE_NOT_CONNECTED 0
189 #define USB_PORT_TYPE_LOW_SPEED 1
190 #define USB_PORT_TYPE_FULL_SPEED 2
191 #define USB_PORT_TYPE_HIGH_SPEED 3
193 typedef struct
194 {
195 ULONG port_number;
196 ULONG port_type;
197 USHORT port_status;
198 USHORT port_change;
199 ULONG reset_counter;
200 } xenusb_port_t;
202 #define DEVICE_STATE_DISCONNECTED 0 /* -> INITIALISING */
203 #define DEVICE_STATE_INITIALISING 1 /* -> ACTIVE or INACTIVE */
204 #define DEVICE_STATE_INACTIVE 2
205 #define DEVICE_STATE_ACTIVE 3 /* -> DISCONNECTING */
206 #define DEVICE_STATE_DISCONNECTING 4 /* -> DISCONNECTED */
208 /*
209 TODO: this driver crashes under checked build of windows (or probably just checked usbhub.sys)
210 Needs a magic number of (ULONG)'HUBx' at the start of BusContext
211 Other magic numbers (ULONG)'BStx' at offset 0x4C of some structure
212 and (ULONG)'HUB ' somewhere in an FDO extension(?)
213 */
215 typedef struct {
216 ULONG magic; /* (ULONG)'HUBx' */
217 /* other magic numbers are (ULONG)'BStx' at offset 0x4C and (ULONG)'HUB ' somewhere in an FDO extension(?) */
218 BOOLEAN XenBus_ShuttingDown;
219 WDFQUEUE io_queue;
220 WDFQUEUE pvurb_queue;
221 WDFCHILDLIST child_list;
222 PDEVICE_OBJECT pdo;
224 WDFDEVICE root_hub_device;
226 XN_HANDLE handle;
227 ULONG device_state;
228 ULONG backend_state;
229 KEVENT backend_event;
230 KDPC event_dpc;
232 struct stack_state *req_id_ss;
233 partial_pvurb_t *partial_pvurbs[MAX_REQ_ID_COUNT];
235 PUCHAR config_page;
237 /* protected by conn_ring_lock */
238 ULONG num_ports;
239 xenusb_port_t ports[32];
241 KSPIN_LOCK urb_ring_lock;
242 usbif_urb_sring_t *urb_sring;
243 usbif_urb_front_ring_t urb_ring;
244 grant_ref_t urb_sring_gref;
246 LIST_ENTRY partial_pvurb_queue;
247 LIST_ENTRY partial_pvurb_ring;
249 KSPIN_LOCK conn_ring_lock;
250 usbif_conn_sring_t *conn_sring;
251 usbif_conn_front_ring_t conn_ring;
252 grant_ref_t conn_sring_gref;
254 domid_t backend_id;
255 evtchn_port_t event_channel;
256 } XENUSB_DEVICE_DATA, *PXENUSB_DEVICE_DATA;
258 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENUSB_DEVICE_DATA, GetXudd)
260 #define DEV_ID_COUNT 64
262 typedef struct {
263 WDFDEVICE wdf_device;
264 WDFDEVICE wdf_device_bus_fdo;
265 WDFIOTARGET bus_fdo_target;
266 WDFQUEUE io_queue;
267 WDFQUEUE urb_queue;
268 ULONG device_number;
269 struct stack_state *dev_id_ss;
270 xenusb_device_t *usb_device;
271 PVOID BusCallbackContext;
272 PRH_INIT_CALLBACK BusCallbackFunction;
273 } XENUSB_PDO_DEVICE_DATA, *PXENUSB_PDO_DEVICE_DATA;
275 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENUSB_PDO_DEVICE_DATA, GetXupdd)
277 #if 0
278 typedef struct {
279 UCHAR usb_class;
280 UCHAR usb_subclass;
281 UCHAR usb_protocol;
282 } xenusb_compatible_id_details_t;
283 #endif
285 typedef struct {
286 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
287 ULONG device_number;
288 //ULONG port_number;
289 //ULONG port_type;
290 //USHORT vendor_id;
291 //USHORT product_id;
292 //xenusb_compatible_id_details_t xucid[1];
293 } XENUSB_PDO_IDENTIFICATION_DESCRIPTION, *PXENUSB_PDO_IDENTIFICATION_DESCRIPTION;
296 static uint16_t
297 get_id_from_freelist(struct stack_state *ss) {
298 ULONG_PTR _id;
299 if (!stack_pop(ss, (VOID *)&_id)) {
300 FUNCTION_MSG("No more id's\n");
301 return (uint16_t)-1;
302 }
303 return (uint16_t)_id;
304 }
306 static VOID
307 put_id_on_freelist(struct stack_state *ss, uint16_t id) {
308 ULONG_PTR _id = id;
309 stack_push(ss, (VOID *)_id);
310 }
312 static
313 ULONGLONG parse_numeric_string(PCHAR string) {
314 ULONGLONG val = 0;
315 while (*string != 0) {
316 val = val * 10 + (*string - '0');
317 string++;
318 }
319 return val;
320 }
322 EVT_WDF_DRIVER_DEVICE_ADD XenUsb_EvtDriverDeviceAdd;
324 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenUsb_EvtChildListCreateDevice;
325 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenUsb_EvtChildListScanForChildren;
327 VOID
328 XenUsb_EnumeratePorts(WDFDEVICE device);
330 EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB;
331 EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
333 #define URB_DECODE_UNKNOWN 0 /* URB is unknown */
334 #define URB_DECODE_COMPLETE 1 /* URB is decoded and no further work should be required */
335 #define URB_DECODE_INCOMPLETE 2 /* URB is decoded but further work is required */
336 #define URB_DECODE_NOT_CONTROL 3 /* URB is known but not a control packet */
338 typedef struct {
339 char *urb_function_name;
340 PULONG length;
341 PVOID buffer;
342 PVOID mdl;
343 ULONG transfer_flags;
344 union {
345 USB_DEFAULT_PIPE_SETUP_PACKET default_pipe_setup_packet;
346 UCHAR raw[8];
347 } setup_packet;
348 } urb_decode_t;
350 ULONG
351 XenUsb_DecodeControlUrb(PURB urb, urb_decode_t *decode_data);
353 VOID
354 XenUsbHub_ProcessHubInterruptEvent(xenusb_endpoint_t *endpoint);
356 #endif