win-pvdrivers

view xenusb/xenusb.h @ 965:63bdd096d8d1

Fix KeInitializeCrashDumpHeader - buffer was too small under newer systems
author James Harper <james.harper@bendigoit.com.au>
date Tue Jan 10 12:11:30 2012 +1100 (2012-01-10)
parents 19d7c9dd9f5c
children 1306945ecc59
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 */
28 #define EISCONN 127
30 #include <ntifs.h>
31 #include <ntddk.h>
33 #define DDKAPI
34 //#include <wdm.h>
35 #include <wdf.h>
36 #include <initguid.h>
37 #include <wdmguid.h>
38 #include <errno.h>
39 #define NTSTRSAFE_LIB
40 #include <ntstrsafe.h>
42 #define __DRIVER_NAME "XenUSB"
44 #include <xen_windows.h>
45 #include <io/ring.h>
46 #include <io/usbif.h>
47 #include <io/xenbus.h>
48 #include <usb.h>
49 #include <usbioctl.h>
50 #include <usbdlib.h>
51 #include <hubbusif.h>
52 #include <usbbusif.h>
54 #define C_HUB_LOCAL_POWER 0
55 #define C_HUB_OVER_CURRENT 1
56 #define PORT_CONNECTION 0
57 #define PORT_ENABLE 1
58 #define PORT_SUSPEND 2
59 #define PORT_OVER_CURRENT 3
60 #define PORT_RESET 4
61 #define PORT_POWER 8
62 #define PORT_LOW_SPEED 9
63 #define PORT_HIGH_SPEED 10
64 #define C_PORT_CONNECTION 16
65 #define C_PORT_ENABLE 17
66 #define C_PORT_SUSPEND 18
67 #define C_PORT_OVER_CURRENT 19
68 #define C_PORT_RESET 20
69 #define PORT_TEST 21
70 #define PORT_INDICATOR 22
72 #define XENUSB_POOL_TAG (ULONG)'XenU'
74 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
76 #define CHILD_STATE_EMPTY 0
77 #define CHILD_STATE_DELETED 1
78 #define CHILD_STATE_ADDED 2
80 #define LINUX_PIPE_DIRECTION_OUT 0x00000000
81 #define LINUX_PIPE_DIRECTION_IN 0x00000080
83 /* these are linux definitions - different to usb standard */
84 #define LINUX_PIPE_TYPE_ISOC 0x00000000
85 #define LINUX_PIPE_TYPE_INTR 0x40000000
86 #define LINUX_PIPE_TYPE_CTRL 0x80000000
87 #define LINUX_PIPE_TYPE_BULK 0xC0000000
89 /*
90 * urb->transfer_flags:
91 */
92 #define LINUX_URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
93 #define LINUX_URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
94 #define LINUX_URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
95 #define LINUX_URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
96 #define LINUX_URB_NO_FSBR 0x0020 /* UHCI-specific */
97 #define LINUX_URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
98 #define LINUX_URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
100 #define PRE_DECLARE_TYPE_TYPEDEF(x) struct _##x; typedef struct _##x x##_t
102 #if 0
103 struct _usbif_shadow;
104 typedef struct _usbif_shadow usbif_shadow_t;
105 #endif
107 PRE_DECLARE_TYPE_TYPEDEF(usbif_shadow);
109 struct _usbif_shadow {
110 uint16_t id;
111 union
112 {
113 struct {
114 WDFREQUEST request;
115 PURB urb;
116 };
117 KEVENT event;
118 };
119 //WDFDMATRANSACTION dma_transaction;
120 PMDL mdl;
121 ULONG total_length;
122 /* called at DISPATCH_LEVEL */
123 VOID (*callback)(usbif_shadow_t *);
124 usbif_urb_request_t req;
125 usbif_urb_response_t rsp;
126 usbif_shadow_t *next; /* for gathering shadows from the ring for callback */
127 };
129 #define MAX_SHADOW_ENTRIES 64
130 #define SHADOW_ENTRIES min(MAX_SHADOW_ENTRIES, USB_URB_RING_SIZE)
132 struct _xenusb_endpoint_t;
133 struct _xenusb_interface_t;
134 struct _xenusb_config_t;
135 struct _xenusb_device_t;
136 typedef struct _xenusb_endpoint_t xenusb_endpoint_t, *pxenusb_endpoint_t;
137 typedef struct _xenusb_interface_t xenusb_interface_t;
138 typedef struct _xenusb_config_t xenusb_config_t;
139 typedef struct _xenusb_device_t xenusb_device_t;
141 typedef struct _xenusb_endpoint_t {
142 xenusb_interface_t *interface;
143 ULONG pipe_value;
144 //WDFTIMER interrupt_timer;
145 WDFQUEUE queue;
146 WDFSPINLOCK lock;
147 USB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
148 };
149 //WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pxenusb_endpoint_t, GetEndpoint)
151 typedef struct _xenusb_interface_t {
152 //ULONG pipe_value;
153 xenusb_config_t *config;
154 USB_INTERFACE_DESCRIPTOR interface_descriptor;
155 xenusb_endpoint_t *endpoints[0];
156 } xenusb_interface_t;
158 typedef struct _xenusb_config_t {
159 xenusb_device_t *device;
160 USB_CONFIGURATION_DESCRIPTOR config_descriptor;
161 PUCHAR config_descriptor_all;
162 xenusb_interface_t *interfaces[0];
163 } xenusb_config_t;
165 typedef struct _xenusb_device_t {
166 WDFDEVICE pdo_device;
167 UCHAR address;
168 USB_DEVICE_DESCRIPTOR device_descriptor;
169 ULONG port_number;
170 WDFQUEUE urb_queue;
171 USB_DEVICE_SPEED device_speed;
172 USB_DEVICE_TYPE device_type;
173 xenusb_config_t *active_config;
174 xenusb_interface_t *active_interface;
175 xenusb_config_t **configs; /* pointer to an array of configs */
176 } xenusb_device_t;
178 #define USB_PORT_TYPE_NOT_CONNECTED 0
179 #define USB_PORT_TYPE_LOW_SPEED 1
180 #define USB_PORT_TYPE_FULL_SPEED 2
181 #define USB_PORT_TYPE_HIGH_SPEED 3
183 typedef struct
184 {
185 ULONG port_number;
186 ULONG port_type;
187 USHORT port_status;
188 USHORT port_change;
189 ULONG reset_counter;
190 } xenusb_port_t;
192 /*
193 TODO: this driver crashes under checked build of windows (or probably just checked usbhub.sys)
194 Needs a magic number of (ULONG)'HUBx' at the start of BusContext
195 Other magic numbers (ULONG)'BStx' at offset 0x4C of some structure
196 and (ULONG)'HUB ' somewhere in an FDO extension(?)
197 */
199 typedef struct {
200 ULONG magic; /* (ULONG)'HUBx' */
201 /* other magic numbers are (ULONG)'BStx' at offset 0x4C and (ULONG)'HUB ' somewhere in an FDO extension(?) */
202 BOOLEAN XenBus_ShuttingDown;
203 WDFQUEUE io_queue;
204 WDFCHILDLIST child_list;
206 WDFDEVICE root_hub_device;
208 usbif_shadow_t shadows[MAX_SHADOW_ENTRIES];
209 USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
210 USHORT shadow_free;
212 PUCHAR config_page;
214 /* protected by conn_ring_lock */
215 ULONG num_ports;
216 xenusb_port_t ports[32];
218 KSPIN_LOCK urb_ring_lock;
219 usbif_urb_sring_t *urb_sring;
220 usbif_urb_front_ring_t urb_ring;
222 KSPIN_LOCK conn_ring_lock;
223 usbif_conn_sring_t *conn_sring;
224 usbif_conn_front_ring_t conn_ring;
226 evtchn_port_t event_channel;
228 XENPCI_VECTORS vectors;
229 PXENPCI_DEVICE_STATE device_state;
231 } XENUSB_DEVICE_DATA, *PXENUSB_DEVICE_DATA;
233 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENUSB_DEVICE_DATA, GetXudd)
235 typedef struct {
236 WDFDEVICE wdf_device;
237 WDFDEVICE wdf_device_bus_fdo;
238 WDFQUEUE io_queue;
239 WDFQUEUE urb_queue;
240 ULONG device_number;
241 //ULONG port_number;
242 //ULONG port_type;
243 xenusb_device_t *usb_device;
244 PVOID BusCallbackContext;
245 PRH_INIT_CALLBACK BusCallbackFunction;
247 } XENUSB_PDO_DEVICE_DATA, *PXENUSB_PDO_DEVICE_DATA;
249 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENUSB_PDO_DEVICE_DATA, GetXupdd)
251 #if 0
252 typedef struct {
253 UCHAR usb_class;
254 UCHAR usb_subclass;
255 UCHAR usb_protocol;
256 } xenusb_compatible_id_details_t;
257 #endif
259 typedef struct {
260 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
261 ULONG device_number;
262 //ULONG port_number;
263 //ULONG port_type;
264 //USHORT vendor_id;
265 //USHORT product_id;
266 //xenusb_compatible_id_details_t xucid[1];
267 } XENUSB_PDO_IDENTIFICATION_DESCRIPTION, *PXENUSB_PDO_IDENTIFICATION_DESCRIPTION;
269 static usbif_shadow_t *
270 get_shadow_from_freelist(PXENUSB_DEVICE_DATA xudd)
271 {
272 if (xudd->shadow_free == 0)
273 {
274 KdPrint((__DRIVER_NAME " No more shadow entries\n"));
275 return NULL;
276 }
277 xudd->shadow_free--;
278 return &xudd->shadows[xudd->shadow_free_list[xudd->shadow_free]];
279 }
281 static VOID
282 put_shadow_on_freelist(PXENUSB_DEVICE_DATA xudd, usbif_shadow_t *shadow)
283 {
284 xudd->shadow_free_list[xudd->shadow_free] = (USHORT)shadow->id;
285 shadow->request = NULL;
286 xudd->shadow_free++;
287 }
289 static
290 ULONGLONG parse_numeric_string(PCHAR string)
291 {
292 ULONGLONG val = 0;
293 while (*string != 0)
294 {
295 val = val * 10 + (*string - '0');
296 string++;
297 }
298 return val;
299 }
301 #if 0
302 static VOID
303 XenUsb_PutRequest(PXENVBD_DEVICE_DATA xudd, usbif_request_t *req)
304 {
305 *RING_GET_REQUEST(&xudd->ring, xudd->ring.req_prod_pvt) = *req;
306 xudd->ring.req_prod_pvt++;
307 }
309 static usbif_request_t *
310 XenUsb_GetResponse(PXENVBD_DEVICE_DATA xudd, ULONG i)
311 {
312 return RING_GET_RESPONSE(&xvdd->ring, i);
313 }
314 #endif
317 /*
318 EVT_WDF_DEVICE_PREPARE_HARDWARE XenUsb_EvtDevicePrepareHardware;
319 EVT_WDF_DEVICE_RELEASE_HARDWARE XenUsb_EvtDeviceReleaseHardware;
320 EVT_WDF_DEVICE_D0_ENTRY XenUsb_EvtDeviceD0Entry;
321 EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
322 EVT_WDF_DEVICE_D0_EXIT XenUsb_EvtDeviceD0Exit;
323 EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
324 EVT_WDF_DEVICE_QUERY_REMOVE XenUsb_EvtDeviceQueryRemove;
325 */
327 EVT_WDF_DRIVER_DEVICE_ADD XenUsb_EvtDriverDeviceAdd;
329 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenUsb_EvtChildListCreateDevice;
330 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenUsb_EvtChildListScanForChildren;
332 VOID
333 XenUsb_EnumeratePorts(WDFDEVICE device);
335 EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB;
336 EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
338 NTSTATUS
339 XenUsb_ExecuteRequest(
340 PXENUSB_DEVICE_DATA xudd,
341 usbif_shadow_t *shadow,
342 PVOID transfer_buffer,
343 PMDL transfer_buffer_mdl,
344 ULONG transfer_buffer_length);
346 #define URB_DECODE_UNKNOWN 0 /* URB is unknown */
347 #define URB_DECODE_COMPLETE 1 /* URB is decoded and no further work should be required */
348 #define URB_DECODE_INCOMPLETE 2 /* URB is decoded but further work is required */
349 #define URB_DECODE_NOT_CONTROL 3 /* URB is known but not a control packet */
351 typedef struct {
352 char *urb_function_name;
353 PULONG length;
354 PVOID buffer;
355 PVOID mdl;
356 ULONG transfer_flags;
357 union {
358 USB_DEFAULT_PIPE_SETUP_PACKET default_pipe_setup_packet;
359 UCHAR raw[8];
360 } setup_packet;
361 } urb_decode_t;
363 ULONG
364 XenUsb_DecodeControlUrb(PURB urb, urb_decode_t *decode_data);
366 VOID
367 XenUsbHub_ProcessHubInterruptEvent(xenusb_endpoint_t *endpoint);
369 #endif