win-pvdrivers

changeset 655:cfaec940d3bb

Very beta pvusb support. It works with at least one flash usb stick plugged into port 1 of the virtual hub. This breaks free build as it has warnings. Many many warnings.
author James Harper <james.harper@bendigoit.com.au>
date Fri Sep 11 22:44:11 2009 +1000 (2009-09-11)
parents 76b5aefeb46c
children 43a106f19847
files dirs xenusb/sources xenusb/xenusb.c xenusb/xenusb.h xenusb/xenusb_devurb.c xenusb/xenusb_fdo.c xenusb/xenusb_hub.c xenusb/xenusb_huburb.c
line diff
     1.1 --- a/dirs	Fri Sep 11 22:21:00 2009 +1000
     1.2 +++ b/dirs	Fri Sep 11 22:44:11 2009 +1000
     1.3 @@ -1,2 +1,2 @@
     1.4  
     1.5 -DIRS=xenpci xenvbd xennet xenscsi copyconfig shutdownmon coinst
     1.6 \ No newline at end of file
     1.7 +DIRS=xenpci xenvbd xennet xenscsi xenusb copyconfig shutdownmon coinst
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xenusb/sources	Fri Sep 11 22:44:11 2009 +1000
     2.3 @@ -0,0 +1,8 @@
     2.4 +!INCLUDE ..\common.inc
     2.5 +TARGETNAME=xenusb
     2.6 +TARGETTYPE=DRIVER
     2.7 +KMDF_VERSION_MAJOR=1
     2.8 +NTTARGETFILES=$(NTTARGETFILES) $(OBJ_PATH)\$(O)\$(TARGETNAME).inf
     2.9 +#TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib $(DDK_LIB_PATH)\Rtlver.lib $(DDK_LIB_PATH)\..\..\wlh\*\aux_klib.lib
    2.10 +TARGETLIBS=$(TARGETLIBS) $(DDK_LIB_PATH)\wdmsec.lib $(DDK_LIB_PATH)\Rtlver.lib $(DDK_LIB_PATH)\..\..\wlh\*\aux_klib.lib
    2.11 +SOURCES=xenusb.c xenusb_fdo.c xenusb_hub.c xenusb_huburb.c xenusb_devurb.c
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xenusb/xenusb.c	Fri Sep 11 22:44:11 2009 +1000
     3.3 @@ -0,0 +1,49 @@
     3.4 +/*
     3.5 +PV Drivers for Windows Xen HVM Domains
     3.6 +Copyright (C) 2009 James Harper
     3.7 +
     3.8 +This program is free software; you can redistribute it and/or
     3.9 +modify it under the terms of the GNU General Public License
    3.10 +as published by the Free Software Foundation; either version 2
    3.11 +of the License, or (at your option) any later version.
    3.12 +
    3.13 +This program is distributed in the hope that it will be useful,
    3.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.16 +GNU General Public License for more details.
    3.17 +
    3.18 +You should have received a copy of the GNU General Public License
    3.19 +along with this program; if not, write to the Free Software
    3.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    3.21 +*/
    3.22 +
    3.23 +#define INITGUID
    3.24 +#include "xenusb.h"
    3.25 +#include <stdlib.h>
    3.26 +
    3.27 +NTSTATUS
    3.28 +DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    3.29 +{
    3.30 +  NTSTATUS status = STATUS_SUCCESS;
    3.31 +  PVOID driver_extension;
    3.32 +  PUCHAR ptr;
    3.33 +  WDF_DRIVER_CONFIG config;
    3.34 +  WDFDRIVER driver;
    3.35 +
    3.36 +  FUNCTION_ENTER();
    3.37 +
    3.38 +  IoAllocateDriverObjectExtension(DriverObject, UlongToPtr(XEN_INIT_DRIVER_EXTENSION_MAGIC), PAGE_SIZE, &driver_extension);
    3.39 +  ptr = driver_extension;
    3.40 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
    3.41 +    
    3.42 +  WDF_DRIVER_CONFIG_INIT(&config, XenUsb_EvtDriverDeviceAdd);
    3.43 +  status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
    3.44 +
    3.45 +  if (!NT_SUCCESS(status)) {
    3.46 +    KdPrint((__DRIVER_NAME "     WdfDriverCreate failed with status 0x%x\n", status));
    3.47 +  }
    3.48 +
    3.49 +  FUNCTION_EXIT();
    3.50 +
    3.51 +  return status;
    3.52 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xenusb/xenusb.h	Fri Sep 11 22:44:11 2009 +1000
     4.3 @@ -0,0 +1,343 @@
     4.4 +/*
     4.5 +PV Drivers for Windows Xen HVM Domains
     4.6 +Copyright (C) 2007 James Harper
     4.7 +
     4.8 +This program is free software; you can redistribute it and/or
     4.9 +modify it under the terms of the GNU General Public License
    4.10 +as published by the Free Software Foundation; either version 2
    4.11 +of the License, or (at your option) any later version.
    4.12 +
    4.13 +This program is distributed in the hope that it will be useful,
    4.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.16 +GNU General Public License for more details.
    4.17 +
    4.18 +You should have received a copy of the GNU General Public License
    4.19 +along with this program; if not, write to the Free Software
    4.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    4.21 +*/
    4.22 +
    4.23 +#pragma warning(disable: 4127)
    4.24 +
    4.25 +#pragma warning(disable : 4200) // zero-sized array
    4.26 +
    4.27 +#if !defined(_XENUSB_H_)
    4.28 +#define _XENUSB_H_
    4.29 +
    4.30 +#define __attribute__(arg) /* empty */
    4.31 +#define EISCONN 127
    4.32 +
    4.33 +#include <ntifs.h>
    4.34 +#include <ntddk.h>
    4.35 +
    4.36 +#define DDKAPI
    4.37 +//#include <wdm.h>
    4.38 +#include <wdf.h>
    4.39 +#include <initguid.h>
    4.40 +#include <wdmguid.h>
    4.41 +#include <errno.h>
    4.42 +#define NTSTRSAFE_LIB
    4.43 +#include <ntstrsafe.h>
    4.44 +
    4.45 +#define __DRIVER_NAME "XenUSB"
    4.46 +
    4.47 +#include <xen_windows.h>
    4.48 +#include <io/ring.h>
    4.49 +#include <io/usbif.h>
    4.50 +#include <usb.h>
    4.51 +#include <usbioctl.h>
    4.52 +#include <usbdlib.h>
    4.53 +#include <hubbusif.h>
    4.54 +#include <usbbusif.h>
    4.55 +
    4.56 +#define C_HUB_LOCAL_POWER   0
    4.57 +#define C_HUB_OVER_CURRENT  1
    4.58 +#define PORT_CONNECTION     0
    4.59 +#define PORT_ENABLE         1
    4.60 +#define PORT_SUSPEND        2
    4.61 +#define PORT_OVER_CURRENT   3
    4.62 +#define PORT_RESET          4
    4.63 +#define PORT_POWER          8
    4.64 +#define PORT_LOW_SPEED      9
    4.65 +#define PORT_HIGH_SPEED     9
    4.66 +#define C_PORT_CONNECTION   16
    4.67 +#define C_PORT_ENABLE       17
    4.68 +#define C_PORT_SUSPEND      18
    4.69 +#define C_PORT_OVER_CURRENT 19
    4.70 +#define C_PORT_RESET        20
    4.71 +#define PORT_TEST           21
    4.72 +#define PORT_INDICATOR      22
    4.73 +
    4.74 +#define XENUSB_POOL_TAG (ULONG)'XenU'
    4.75 +
    4.76 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    4.77 +
    4.78 +#define CHILD_STATE_EMPTY 0
    4.79 +#define CHILD_STATE_DELETED 1
    4.80 +#define CHILD_STATE_ADDED 2
    4.81 +
    4.82 +#define LINUX_PIPE_DIRECTION_OUT 0x00000000
    4.83 +#define LINUX_PIPE_DIRECTION_IN  0x00000080
    4.84 +
    4.85 +/* these are linux definitions - different to usb standard */
    4.86 +#define LINUX_PIPE_TYPE_ISOC     0x00000000
    4.87 +#define LINUX_PIPE_TYPE_INTR     0x40000000
    4.88 +#define LINUX_PIPE_TYPE_CTRL     0x80000000
    4.89 +#define LINUX_PIPE_TYPE_BULK     0xC0000000
    4.90 +
    4.91 +/*
    4.92 + * urb->transfer_flags:
    4.93 + */
    4.94 +#define LINUX_URB_SHORT_NOT_OK        0x0001  /* report short reads as errors */
    4.95 +#define LINUX_URB_ISO_ASAP            0x0002  /* iso-only, urb->start_frame ignored */
    4.96 +#define LINUX_URB_NO_TRANSFER_DMA_MAP 0x0004  /* urb->transfer_dma valid on submit */
    4.97 +#define LINUX_URB_NO_SETUP_DMA_MAP    0x0008  /* urb->setup_dma valid on submit */
    4.98 +#define LINUX_URB_NO_FSBR             0x0020  /* UHCI-specific */
    4.99 +#define LINUX_URB_ZERO_PACKET         0x0040  /* Finish bulk OUT with short packet */
   4.100 +#define LINUX_URB_NO_INTERRUPT        0x0080  /* HINT: no non-error interrupt needed */
   4.101 +
   4.102 +
   4.103 +
   4.104 +struct _usbif_shadow;
   4.105 +typedef struct _usbif_shadow usbif_shadow_t;
   4.106 +
   4.107 +struct _usbif_shadow {
   4.108 +  uint16_t id;
   4.109 +  union
   4.110 +  {
   4.111 +    struct {
   4.112 +      WDFREQUEST request;
   4.113 +      PURB urb;
   4.114 +    };
   4.115 +    KEVENT event;
   4.116 +  };
   4.117 +  WDFDMATRANSACTION dma_transaction;
   4.118 +  PMDL mdl;
   4.119 +  ULONG total_length;
   4.120 +  /* called at DISPATCH_LEVEL */
   4.121 +  VOID (*callback)(usbif_shadow_t *);
   4.122 +  usbif_request_t req;
   4.123 +  usbif_response_t rsp;
   4.124 +  usbif_shadow_t *next; /* for gathering shadows from the ring for callback */
   4.125 +  ULONGLONG submit_time;
   4.126 +};
   4.127 +
   4.128 +#define MAX_SHADOW_ENTRIES 64
   4.129 +#define SHADOW_ENTRIES min(MAX_SHADOW_ENTRIES, USB_RING_SIZE)
   4.130 +
   4.131 +struct _xenusb_endpoint_t;
   4.132 +struct _xenusb_interface_t;
   4.133 +struct _xenusb_config_t;
   4.134 +struct _xenusb_device_t;
   4.135 +typedef struct _xenusb_endpoint_t xenusb_endpoint_t, *pxenusb_endpoint_t;
   4.136 +typedef struct _xenusb_interface_t xenusb_interface_t;
   4.137 +typedef struct _xenusb_config_t xenusb_config_t;
   4.138 +typedef struct _xenusb_device_t xenusb_device_t;
   4.139 +
   4.140 +typedef struct _xenusb_endpoint_t {
   4.141 +  xenusb_interface_t *interface;
   4.142 +  ULONG pipe_value;
   4.143 +  WDFTIMER interrupt_timer;
   4.144 +  WDFQUEUE interrupt_queue;
   4.145 +  WDFSPINLOCK interrupt_lock;
   4.146 +  USB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
   4.147 +};
   4.148 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pxenusb_endpoint_t, GetEndpoint)
   4.149 +
   4.150 +typedef struct _xenusb_interface_t {
   4.151 +  //ULONG pipe_value;
   4.152 +  xenusb_config_t *config;
   4.153 +  USB_INTERFACE_DESCRIPTOR interface_descriptor;
   4.154 +  xenusb_endpoint_t *endpoints[0];
   4.155 +} xenusb_interface_t;
   4.156 +
   4.157 +typedef struct _xenusb_config_t {
   4.158 +  xenusb_device_t *device;
   4.159 +  USB_CONFIGURATION_DESCRIPTOR config_descriptor;
   4.160 +  xenusb_interface_t *interfaces[0];
   4.161 +} xenusb_config_t;
   4.162 +
   4.163 +typedef struct _xenusb_device_t {
   4.164 +  WDFDEVICE pdo_device;
   4.165 +  UCHAR address;
   4.166 +  USB_DEVICE_DESCRIPTOR device_descriptor;
   4.167 +  ULONG port_number;
   4.168 +  WDFQUEUE urb_queue;
   4.169 +  xenusb_config_t *active_config;
   4.170 +  xenusb_config_t **configs; /* pointer to an array of configs */
   4.171 +} xenusb_device_t;
   4.172 +
   4.173 +#define USB_PORT_TYPE_NOT_CONNECTED 0
   4.174 +#define USB_PORT_TYPE_LOW_SPEED     1
   4.175 +#define USB_PORT_TYPE_FULL_SPEED    2
   4.176 +#define USB_PORT_TYPE_HIGH_SPEED    3
   4.177 +
   4.178 +typedef struct
   4.179 +{
   4.180 +  ULONG port_number;
   4.181 +  ULONG port_type;
   4.182 +  USHORT port_status;
   4.183 +  USHORT port_change;
   4.184 +} xenusb_port_t;
   4.185 +
   4.186 +typedef struct {  
   4.187 +  BOOLEAN XenBus_ShuttingDown;
   4.188 +  WDFQUEUE io_queue;
   4.189 +  WDFDMAENABLER dma_enabler;
   4.190 +  
   4.191 +  WDFCHILDLIST child_list;
   4.192 +  
   4.193 +  WDFDEVICE root_hub_device;
   4.194 +
   4.195 +  usbif_shadow_t shadows[MAX_SHADOW_ENTRIES];
   4.196 +  USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
   4.197 +  USHORT shadow_free;
   4.198 +
   4.199 +  PUCHAR config_page;
   4.200 +  
   4.201 +  KSPIN_LOCK port_lock;
   4.202 +  ULONG num_ports;
   4.203 +  xenusb_port_t ports[32];
   4.204 +
   4.205 +  KSPIN_LOCK ring_lock;
   4.206 +  usbif_sring_t *sring;
   4.207 +  usbif_front_ring_t ring;
   4.208 +  evtchn_port_t event_channel;
   4.209 +
   4.210 +  BOOLEAN inactive;
   4.211 +  XENPCI_VECTORS vectors;
   4.212 +  PXENPCI_DEVICE_STATE device_state;
   4.213 +
   4.214 +} XENUSB_DEVICE_DATA, *PXENUSB_DEVICE_DATA;
   4.215 +
   4.216 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENUSB_DEVICE_DATA, GetXudd)
   4.217 +
   4.218 +typedef struct {  
   4.219 +  WDFDEVICE wdf_device;
   4.220 +  WDFDEVICE wdf_device_bus_fdo;
   4.221 +  WDFQUEUE io_queue;
   4.222 +  WDFQUEUE urb_queue;
   4.223 +  ULONG device_number;
   4.224 +  //ULONG port_number;
   4.225 +  //ULONG port_type;
   4.226 +  xenusb_device_t *usb_device;
   4.227 +  PVOID BusCallbackContext;
   4.228 +  PRH_INIT_CALLBACK BusCallbackFunction;
   4.229 +
   4.230 +} XENUSB_PDO_DEVICE_DATA, *PXENUSB_PDO_DEVICE_DATA;
   4.231 +
   4.232 +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENUSB_PDO_DEVICE_DATA, GetXupdd)
   4.233 +
   4.234 +#if 0
   4.235 +typedef struct {
   4.236 +  UCHAR usb_class;
   4.237 +  UCHAR usb_subclass;
   4.238 +  UCHAR usb_protocol;
   4.239 +} xenusb_compatible_id_details_t;
   4.240 +#endif
   4.241 +
   4.242 +typedef struct {
   4.243 +  WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
   4.244 +  ULONG device_number;
   4.245 +  //ULONG port_number;
   4.246 +  //ULONG port_type;
   4.247 +  //USHORT vendor_id;
   4.248 +  //USHORT product_id;
   4.249 +  //xenusb_compatible_id_details_t xucid[1];
   4.250 +} XENUSB_PDO_IDENTIFICATION_DESCRIPTION, *PXENUSB_PDO_IDENTIFICATION_DESCRIPTION;
   4.251 +
   4.252 +static usbif_shadow_t *
   4.253 +get_shadow_from_freelist(PXENUSB_DEVICE_DATA xudd)
   4.254 +{
   4.255 +  if (xudd->shadow_free == 0)
   4.256 +  {
   4.257 +    KdPrint((__DRIVER_NAME "     No more shadow entries\n"));
   4.258 +    return NULL;
   4.259 +  }
   4.260 +  xudd->shadow_free--;
   4.261 +  return &xudd->shadows[xudd->shadow_free_list[xudd->shadow_free]];
   4.262 +}
   4.263 +
   4.264 +static VOID
   4.265 +put_shadow_on_freelist(PXENUSB_DEVICE_DATA xudd, usbif_shadow_t *shadow)
   4.266 +{
   4.267 +  xudd->shadow_free_list[xudd->shadow_free] = (USHORT)shadow->id;
   4.268 +  shadow->request = NULL;
   4.269 +  xudd->shadow_free++;
   4.270 +}
   4.271 +
   4.272 +static
   4.273 +ULONGLONG parse_numeric_string(PCHAR string)
   4.274 +{
   4.275 +  ULONGLONG val = 0;
   4.276 +  while (*string != 0)
   4.277 +  {
   4.278 +    val = val * 10 + (*string - '0');
   4.279 +    string++;
   4.280 +  }
   4.281 +  return val;
   4.282 +}
   4.283 +
   4.284 +#if 0
   4.285 +static VOID
   4.286 +XenUsb_PutRequest(PXENVBD_DEVICE_DATA xudd, usbif_request_t *req)
   4.287 +{
   4.288 +  *RING_GET_REQUEST(&xudd->ring, xudd->ring.req_prod_pvt) = *req;
   4.289 +  xudd->ring.req_prod_pvt++;
   4.290 +}
   4.291 +
   4.292 +static usbif_request_t *
   4.293 +XenUsb_GetResponse(PXENVBD_DEVICE_DATA xudd, ULONG i)
   4.294 +{
   4.295 +  return RING_GET_RESPONSE(&xvdd->ring, i);
   4.296 +}
   4.297 +#endif
   4.298 +
   4.299 +
   4.300 +/*
   4.301 +EVT_WDF_DEVICE_PREPARE_HARDWARE XenUsb_EvtDevicePrepareHardware;
   4.302 +EVT_WDF_DEVICE_RELEASE_HARDWARE XenUsb_EvtDeviceReleaseHardware;
   4.303 +EVT_WDF_DEVICE_D0_ENTRY XenUsb_EvtDeviceD0Entry;
   4.304 +EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
   4.305 +EVT_WDF_DEVICE_D0_EXIT XenUsb_EvtDeviceD0Exit;
   4.306 +EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
   4.307 +EVT_WDF_DEVICE_QUERY_REMOVE XenUsb_EvtDeviceQueryRemove;
   4.308 +*/
   4.309 +
   4.310 +//PFN_WDF_DRIVER_DEVICE_ADD XenUsb_EvtDriverDeviceAdd;
   4.311 +NTSTATUS
   4.312 +XenUsb_EvtDriverDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init);
   4.313 +
   4.314 +NTSTATUS
   4.315 +XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER description_header, PWDFDEVICE_INIT child_init);
   4.316 +VOID
   4.317 +XenUsb_EvtChildListScanForChildren(WDFCHILDLIST child_list);
   4.318 +
   4.319 +VOID
   4.320 +XenUsb_EnumeratePorts(WDFDEVICE device);
   4.321 +
   4.322 +VOID
   4.323 +XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB(
   4.324 +  WDFQUEUE queue,
   4.325 +  WDFREQUEST request,
   4.326 +  size_t output_buffer_length,
   4.327 +  size_t input_buffer_length,
   4.328 +  ULONG io_control_code);
   4.329 +
   4.330 +VOID
   4.331 +XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB(
   4.332 +  WDFQUEUE queue,
   4.333 +  WDFREQUEST request,
   4.334 +  size_t output_buffer_length,
   4.335 +  size_t input_buffer_length,
   4.336 +  ULONG io_control_code);
   4.337 +
   4.338 +NTSTATUS
   4.339 +XenUsb_ExecuteRequest(
   4.340 +  PXENUSB_DEVICE_DATA xudd,
   4.341 +  usbif_shadow_t *shadow,
   4.342 +  PVOID transfer_buffer,
   4.343 +  PMDL transfer_buffer_mdl,
   4.344 +  ULONG transfer_buffer_length);
   4.345 + 
   4.346 +#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xenusb/xenusb_devurb.c	Fri Sep 11 22:44:11 2009 +1000
     5.3 @@ -0,0 +1,860 @@
     5.4 +/*
     5.5 +PV Drivers for Windows Xen HVM Domains
     5.6 +Copyright (C) 2007 James Harper
     5.7 +
     5.8 +This program is free software; you can redistribute it and/or
     5.9 +modify it under the terms of the GNU General Public License
    5.10 +as published by the Free Software Foundation; either version 2
    5.11 +of the License, or (at your option) any later version.
    5.12 +
    5.13 +This program is distributed in the hope that it will be useful,
    5.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.16 +GNU General Public License for more details.
    5.17 +
    5.18 +You should have received a copy of the GNU General Public License
    5.19 +along with this program; if not, write to the Free Software
    5.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    5.21 +*/
    5.22 +
    5.23 +#include "xenusb.h"
    5.24 +
    5.25 +#define EPROTO          71      /* Protocol error */
    5.26 +
    5.27 +typedef struct {
    5.28 +  ULONG elapsed_ms;
    5.29 +  PVOID PipeHandle;
    5.30 +  ULONG TransferFlags;
    5.31 +  ULONG TransferBufferLength;
    5.32 +  PVOID TransferBuffer;
    5.33 +  PMDL TransferBufferMdl;
    5.34 +  ULONG pipe_value;
    5.35 +  ULONG id;
    5.36 +  ULONG start_frame;
    5.37 +  ULONG status;
    5.38 +  ULONG actual_length;
    5.39 +  ULONG error_count;
    5.40 +  ULONG total_length;
    5.41 +} w00t_t;
    5.42 +
    5.43 +w00t_t w00t;
    5.44 +
    5.45 +static VOID
    5.46 +XenUsb_UrbCallback(usbif_shadow_t *shadow)
    5.47 +{
    5.48 +  NTSTATUS status;
    5.49 +  BOOLEAN dma_complete;
    5.50 +  WDFQUEUE queue;
    5.51 +  WDFDEVICE device;
    5.52 +  PXENUSB_PDO_DEVICE_DATA xupdd;
    5.53 +  PXENUSB_DEVICE_DATA xudd;
    5.54 +  //ULONG i;
    5.55 +
    5.56 +  //FUNCTION_ENTER();
    5.57 +
    5.58 +  ASSERT(shadow->request);
    5.59 +  queue = WdfRequestGetIoQueue(shadow->request);
    5.60 +  ASSERT(queue);
    5.61 +  device = WdfIoQueueGetDevice(queue);
    5.62 +  ASSERT(device);
    5.63 +  xupdd = GetXupdd(device);
    5.64 +  xudd = GetXudd(xupdd->wdf_device_bus_fdo);
    5.65 +
    5.66 +  switch (shadow->urb->UrbHeader.Function)
    5.67 +  {
    5.68 +  case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
    5.69 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
    5.70 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
    5.71 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
    5.72 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
    5.73 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
    5.74 +    KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
    5.75 +  //case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
    5.76 +  //case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
    5.77 +  //case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
    5.78 +  //case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
    5.79 +  //case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
    5.80 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"));
    5.81 +    shadow->urb->UrbControlDescriptorRequest.TransferBufferLength = shadow->total_length;
    5.82 +#if 0
    5.83 +{
    5.84 +  PUCHAR addr = shadow->urb->UrbControlDescriptorRequest.TransferBuffer;
    5.85 +  if (!addr)
    5.86 +    addr = MmGetSystemAddressForMdlSafe(shadow->urb->UrbControlDescriptorRequest.TransferBufferMDL, HighPagePriority);
    5.87 +  for (i = 0; i < min(shadow->urb->UrbControlDescriptorRequest.TransferBufferLength, 16); i++)
    5.88 +    KdPrint((__DRIVER_NAME "      UrbControlDescriptorRequest[%02x] = %02x\n", i, addr[i]));
    5.89 +}
    5.90 +#endif
    5.91 +    break;
    5.92 +  case URB_FUNCTION_SELECT_CONFIGURATION:
    5.93 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
    5.94 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
    5.95 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
    5.96 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
    5.97 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
    5.98 +    KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
    5.99 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SELECT_CONFIGURATION\n"));
   5.100 +    break;
   5.101 +  case URB_FUNCTION_SELECT_INTERFACE:
   5.102 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   5.103 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   5.104 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   5.105 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   5.106 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   5.107 +    KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
   5.108 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SELECT_INTERFACE\n"));
   5.109 +    break;
   5.110 +  case URB_FUNCTION_CLASS_INTERFACE:
   5.111 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   5.112 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   5.113 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   5.114 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   5.115 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   5.116 +    KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
   5.117 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_INTERFACE\n"));
   5.118 +    shadow->urb->UrbControlVendorClassRequest.TransferBufferLength = shadow->total_length;
   5.119 +    break;
   5.120 +  case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
   5.121 +  {
   5.122 +    xenusb_endpoint_t *endpoint;
   5.123 +    ULONGLONG current_time;
   5.124 +    ULONG elapsed_ms;
   5.125 +    
   5.126 +    KeQuerySystemTime((PLARGE_INTEGER)&current_time);
   5.127 +    
   5.128 +    elapsed_ms = (ULONG)((current_time - shadow->submit_time) / 10 / 1000);
   5.129 +    endpoint = shadow->urb->UrbBulkOrInterruptTransfer.PipeHandle;    
   5.130 +
   5.131 +    if (shadow->rsp.status || elapsed_ms > 5000)
   5.132 +    {
   5.133 +      KdPrint((__DRIVER_NAME "     URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n"));
   5.134 +      KdPrint((__DRIVER_NAME "      elapsed_ms = %d\n", w00t.elapsed_ms));
   5.135 +      KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", w00t.PipeHandle));
   5.136 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", w00t.TransferFlags));
   5.137 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", w00t.TransferBufferLength));
   5.138 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", w00t.TransferBuffer));
   5.139 +      KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", w00t.TransferBufferMdl));
   5.140 +      KdPrint((__DRIVER_NAME "      pipe_value = %08x\n", w00t.pipe_value));
   5.141 +      KdPrint((__DRIVER_NAME "     rsp id = %d\n", w00t.id));
   5.142 +      KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", w00t.start_frame));
   5.143 +      KdPrint((__DRIVER_NAME "     rsp status = %d\n", w00t.status));
   5.144 +      KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", w00t.actual_length));
   5.145 +      KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", w00t.error_count));
   5.146 +      KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
   5.147 +
   5.148 +      KdPrint((__DRIVER_NAME "     URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n"));
   5.149 +      KdPrint((__DRIVER_NAME "      elapsed_ms = %d\n", elapsed_ms));
   5.150 +      KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", shadow->urb->UrbBulkOrInterruptTransfer.PipeHandle));
   5.151 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", shadow->urb->UrbBulkOrInterruptTransfer.TransferFlags));
   5.152 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferLength));
   5.153 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", shadow->urb->UrbBulkOrInterruptTransfer.TransferBuffer));
   5.154 +      KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferMDL));
   5.155 +      KdPrint((__DRIVER_NAME "      UrbLink = %p\n", shadow->urb->UrbBulkOrInterruptTransfer.UrbLink));
   5.156 +      KdPrint((__DRIVER_NAME "      pipe_value = %08x\n", endpoint->pipe_value));
   5.157 +      KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   5.158 +      KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   5.159 +      KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   5.160 +      KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   5.161 +      KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   5.162 +      KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
   5.163 +  }
   5.164 +    w00t.elapsed_ms = elapsed_ms;
   5.165 +    w00t.PipeHandle = shadow->urb->UrbBulkOrInterruptTransfer.PipeHandle;
   5.166 +    w00t.TransferFlags = shadow->urb->UrbBulkOrInterruptTransfer.TransferFlags;
   5.167 +    w00t.TransferBufferLength = shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
   5.168 +    w00t.TransferBuffer = shadow->urb->UrbBulkOrInterruptTransfer.TransferBuffer;
   5.169 +    w00t.TransferBufferMdl = shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
   5.170 +    w00t.pipe_value = endpoint->pipe_value;
   5.171 +    w00t.id = shadow->rsp.id;
   5.172 +    w00t.start_frame = shadow->rsp.start_frame;
   5.173 +    w00t.status = shadow->rsp.status;
   5.174 +    w00t.actual_length = shadow->rsp.actual_length;
   5.175 +    w00t.error_count = shadow->rsp.error_count;
   5.176 +    w00t.total_length = shadow->total_length;
   5.177 +  }
   5.178 +    shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferLength = shadow->total_length;
   5.179 +#if 0
   5.180 +{
   5.181 +  PUCHAR addr = shadow->urb->UrbBulkOrInterruptTransfer.TransferBuffer;
   5.182 +  if (!addr)
   5.183 +    addr = MmGetSystemAddressForMdlSafe(shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferMDL, HighPagePriority);
   5.184 +  for (i = 0; i < min(shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferLength, 16); i++)
   5.185 +    KdPrint((__DRIVER_NAME "      UrbBulkOrInterruptTransfer[%02x] = %02x\n", i, addr[i]));
   5.186 +}
   5.187 +#endif
   5.188 +    break;
   5.189 +  default:
   5.190 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   5.191 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   5.192 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   5.193 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   5.194 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   5.195 +    KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
   5.196 +    KdPrint((__DRIVER_NAME "     Unknown function %x\n", shadow->urb->UrbHeader.Function));
   5.197 +    break;
   5.198 +  }
   5.199 +  switch (shadow->rsp.status)
   5.200 +  {
   5.201 +  case 0:
   5.202 +    shadow->urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.203 +    break;
   5.204 +  case -EPROTO:
   5.205 +    shadow->urb->UrbHeader.Status = USBD_STATUS_CRC;
   5.206 +    break;
   5.207 +#if 0
   5.208 +  case -EPIPE:
   5.209 +    shadow->urb->UrbHeader.Status USBD_STATUS_ENDPOINT_HALTED;
   5.210 +    break;
   5.211 +  case -EOVERFLOW:
   5.212 +    shadow->urb->UrbHeader.Status USBD_STATUS_DATA_OVERRUN;
   5.213 +    break;
   5.214 +  case -EREMOTEIO:
   5.215 +    shadow->urb->UrbHeader.Status USBD_STATUS_ERROR_SHORT_TRANSFER;
   5.216 +    break;
   5.217 +#endif
   5.218 +  default:
   5.219 +    //shadow->urb->UrbHeader.Status = USBD_STATUS_ENDPOINT_HALTED;
   5.220 +    shadow->urb->UrbHeader.Status = USBD_STATUS_INTERNAL_HC_ERROR;
   5.221 +    break;
   5.222 +  }
   5.223 +  WdfRequestComplete(shadow->request, STATUS_SUCCESS);
   5.224 +  put_shadow_on_freelist(xudd, shadow);
   5.225 +
   5.226 +  //FUNCTION_EXIT();
   5.227 +}
   5.228 +
   5.229 +VOID
   5.230 +XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB(
   5.231 +  WDFQUEUE queue,
   5.232 +  WDFREQUEST request,
   5.233 +  size_t output_buffer_length,
   5.234 +  size_t input_buffer_length,
   5.235 +  ULONG io_control_code)
   5.236 +{
   5.237 +  NTSTATUS status;
   5.238 +  WDFDEVICE device = WdfIoQueueGetDevice(queue);
   5.239 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
   5.240 +  PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
   5.241 +  WDF_REQUEST_PARAMETERS wrp;
   5.242 +  PURB urb;
   5.243 +  usbif_shadow_t *shadow;
   5.244 +  PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
   5.245 +  //PMDL mdl;
   5.246 +  PUSBD_INTERFACE_INFORMATION interface_information;
   5.247 +  ULONG i, j;
   5.248 +  xenusb_device_t *usb_device;
   5.249 +  //PUSB_HUB_DESCRIPTOR uhd;
   5.250 +  xenusb_endpoint_t *endpoint;
   5.251 +
   5.252 +  UNREFERENCED_PARAMETER(input_buffer_length);
   5.253 +  UNREFERENCED_PARAMETER(output_buffer_length);
   5.254 +
   5.255 +  //FUNCTION_ENTER();
   5.256 +
   5.257 +  ASSERT(io_control_code == IOCTL_INTERNAL_USB_SUBMIT_URB);
   5.258 +
   5.259 +  status = STATUS_UNSUCCESSFUL;
   5.260 +
   5.261 +  WDF_REQUEST_PARAMETERS_INIT(&wrp);
   5.262 +  WdfRequestGetParameters(request, &wrp);
   5.263 +
   5.264 +  urb = (PURB)wrp.Parameters.Others.Arg1;
   5.265 +  ASSERT(urb);
   5.266 +#if 0
   5.267 +  KdPrint((__DRIVER_NAME "     urb = %p\n", urb));
   5.268 +  KdPrint((__DRIVER_NAME "      Length = %d\n", urb->UrbHeader.Length));
   5.269 +  KdPrint((__DRIVER_NAME "      Function = %d\n", urb->UrbHeader.Function));
   5.270 +  KdPrint((__DRIVER_NAME "      Status = %d\n", urb->UrbHeader.Status));
   5.271 +  KdPrint((__DRIVER_NAME "      UsbdDeviceHandle = %p\n", urb->UrbHeader.UsbdDeviceHandle));
   5.272 +  KdPrint((__DRIVER_NAME "      UsbdFlags = %08x\n", urb->UrbHeader.UsbdFlags));
   5.273 +#endif
   5.274 +  usb_device = urb->UrbHeader.UsbdDeviceHandle;
   5.275 +
   5.276 +  ASSERT(usb_device);
   5.277 +  
   5.278 +  if (!usb_device)
   5.279 +    usb_device = xupdd->usb_device;
   5.280 +
   5.281 +  switch(urb->UrbHeader.Function)
   5.282 +  {
   5.283 +  case URB_FUNCTION_SELECT_CONFIGURATION:
   5.284 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SELECT_CONFIGURATION\n"));
   5.285 +    KdPrint((__DRIVER_NAME "      ConfigurationDescriptor = %p\n", urb->UrbSelectConfiguration.ConfigurationDescriptor));
   5.286 +    if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
   5.287 +    {
   5.288 +      KdPrint((__DRIVER_NAME "       bLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength));
   5.289 +      KdPrint((__DRIVER_NAME "       bDescriptorType = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType));
   5.290 +      KdPrint((__DRIVER_NAME "       wTotalLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength));
   5.291 +      KdPrint((__DRIVER_NAME "       bNumInterfaces = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces));
   5.292 +      KdPrint((__DRIVER_NAME "       bConfigurationValue = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue));
   5.293 +      KdPrint((__DRIVER_NAME "       iConfiguration = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration));
   5.294 +      KdPrint((__DRIVER_NAME "       bmAttributes = %04x\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes));
   5.295 +      KdPrint((__DRIVER_NAME "       MaxPower = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower));
   5.296 +    }
   5.297 +    if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
   5.298 +    {
   5.299 +      xenusb_config_t *usb_config = NULL;
   5.300 +      for (i = 0; i < usb_device->device_descriptor.bNumConfigurations; i++)
   5.301 +      {
   5.302 +        if (usb_device->configs[i]->config_descriptor.bConfigurationValue == urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue)
   5.303 +          usb_config = usb_device->configs[i];
   5.304 +      }
   5.305 +      urb->UrbSelectConfiguration.ConfigurationHandle = usb_config;
   5.306 +      interface_information = &urb->UrbSelectConfiguration.Interface;
   5.307 +      /* configuration is fully populated */
   5.308 +      for (i = 0; i < urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; i++)
   5.309 +      {
   5.310 +        /* i think we need to pay attention to the alt setting here .. */
   5.311 +        xenusb_interface_t *usb_interface = usb_config->interfaces[i];
   5.312 +        interface_information->InterfaceNumber = usb_interface->interface_descriptor.bInterfaceNumber;
   5.313 +        interface_information->AlternateSetting = usb_interface->interface_descriptor.bAlternateSetting;
   5.314 +        interface_information->Class = usb_interface->interface_descriptor.bInterfaceClass;
   5.315 +        interface_information->SubClass = usb_interface->interface_descriptor.bInterfaceSubClass;
   5.316 +        interface_information->Protocol = usb_interface->interface_descriptor.bInterfaceProtocol;
   5.317 +        interface_information->InterfaceHandle = usb_interface;
   5.318 +        KdPrint((__DRIVER_NAME "     InterfaceInformation[%d]\n", i));
   5.319 +        KdPrint((__DRIVER_NAME "      Length = %d\n", interface_information->Length));
   5.320 +        KdPrint((__DRIVER_NAME "      InterfaceNumber = %d\n", interface_information->InterfaceNumber));
   5.321 +        KdPrint((__DRIVER_NAME "      AlternateSetting = %d\n", interface_information->AlternateSetting));
   5.322 +        KdPrint((__DRIVER_NAME "      Class = %02x\n", (ULONG)interface_information->Class));
   5.323 +        KdPrint((__DRIVER_NAME "      SubClass = %02x\n", (ULONG)interface_information->SubClass));
   5.324 +        KdPrint((__DRIVER_NAME "      Protocol = %02x\n", (ULONG)interface_information->Protocol));
   5.325 +        KdPrint((__DRIVER_NAME "      InterfaceHandle = %p\n", interface_information->InterfaceHandle));
   5.326 +        KdPrint((__DRIVER_NAME "      NumberOfPipes = %d\n", interface_information->NumberOfPipes));
   5.327 +        for (j = 0; j < interface_information->NumberOfPipes; j++)
   5.328 +        {
   5.329 +          xenusb_endpoint_t *usb_endpoint = usb_interface->endpoints[j];
   5.330 +          KdPrint((__DRIVER_NAME "      Pipe[%d] (before)\n", j));
   5.331 +          KdPrint((__DRIVER_NAME "       MaximumPacketSize = %d\n", interface_information->Pipes[j].MaximumPacketSize));
   5.332 +          KdPrint((__DRIVER_NAME "       EndpointAddress = %d\n", interface_information->Pipes[j].EndpointAddress));
   5.333 +          KdPrint((__DRIVER_NAME "       Interval = %d\n", interface_information->Pipes[j].Interval));
   5.334 +          KdPrint((__DRIVER_NAME "       PipeType = %d\n", interface_information->Pipes[j].PipeType));
   5.335 +          KdPrint((__DRIVER_NAME "       PipeHandle = %p\n", interface_information->Pipes[j].PipeHandle));
   5.336 +          KdPrint((__DRIVER_NAME "       MaximumTransferSize = %d\n", interface_information->Pipes[j].MaximumTransferSize));
   5.337 +          KdPrint((__DRIVER_NAME "       PipeFlags = %08x\n", interface_information->Pipes[j].PipeFlags));
   5.338 +          interface_information->Pipes[j].MaximumPacketSize = usb_endpoint->endpoint_descriptor.wMaxPacketSize;
   5.339 +          interface_information->Pipes[j].EndpointAddress = usb_endpoint->endpoint_descriptor.bEndpointAddress;
   5.340 +          interface_information->Pipes[j].Interval = usb_endpoint->endpoint_descriptor.bInterval;
   5.341 +          switch (usb_endpoint->endpoint_descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK)
   5.342 +          {
   5.343 +          case USB_ENDPOINT_TYPE_CONTROL:
   5.344 +            interface_information->Pipes[j].PipeType = UsbdPipeTypeControl;
   5.345 +            break;
   5.346 +          case USB_ENDPOINT_TYPE_ISOCHRONOUS:
   5.347 +            interface_information->Pipes[j].PipeType = UsbdPipeTypeIsochronous;
   5.348 +            break;
   5.349 +          case USB_ENDPOINT_TYPE_BULK:
   5.350 +            interface_information->Pipes[j].PipeType = UsbdPipeTypeBulk;
   5.351 +            break;
   5.352 +          case USB_ENDPOINT_TYPE_INTERRUPT:
   5.353 +            interface_information->Pipes[j].PipeType = UsbdPipeTypeInterrupt;
   5.354 +            break;
   5.355 +          }
   5.356 +          interface_information->Pipes[j].PipeHandle = usb_endpoint;
   5.357 +          KdPrint((__DRIVER_NAME "      Pipe[%d] (after)\n", j));
   5.358 +          KdPrint((__DRIVER_NAME "       MaximumPacketSize = %d\n", interface_information->Pipes[j].MaximumPacketSize));
   5.359 +          KdPrint((__DRIVER_NAME "       EndpointAddress = %d\n", interface_information->Pipes[j].EndpointAddress));
   5.360 +          KdPrint((__DRIVER_NAME "       Interval = %d\n", interface_information->Pipes[j].Interval));
   5.361 +          KdPrint((__DRIVER_NAME "       PipeType = %d\n", interface_information->Pipes[j].PipeType));
   5.362 +          KdPrint((__DRIVER_NAME "       PipeHandle = %p\n", interface_information->Pipes[j].PipeHandle));
   5.363 +          KdPrint((__DRIVER_NAME "       MaximumTransferSize = %d\n", interface_information->Pipes[j].MaximumTransferSize));
   5.364 +          KdPrint((__DRIVER_NAME "       PipeFlags = %08x\n", interface_information->Pipes[j].PipeFlags));
   5.365 +        }
   5.366 +        interface_information = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)interface_information + interface_information->Length);
   5.367 +      }
   5.368 +    }
   5.369 +    else
   5.370 +    {
   5.371 +      // ? unconfigure device here
   5.372 +    }
   5.373 +    shadow = get_shadow_from_freelist(xudd);
   5.374 +    shadow->request = request;
   5.375 +    shadow->urb = urb;
   5.376 +    shadow->mdl = NULL;
   5.377 +    shadow->dma_transaction = NULL;
   5.378 +    shadow->callback = XenUsb_UrbCallback;
   5.379 +    shadow->req.id = shadow->id;
   5.380 +    shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   5.381 +    shadow->req.transfer_flags = 0;
   5.382 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   5.383 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   5.384 +    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   5.385 +    setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   5.386 +    setup_packet->bRequest = USB_REQUEST_SET_CONFIGURATION;
   5.387 +    setup_packet->wLength = 0;
   5.388 +    setup_packet->wValue.W = urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
   5.389 +    setup_packet->wIndex.W = 0;
   5.390 +    status = XenUsb_ExecuteRequest(xudd, shadow, NULL, NULL, 0);
   5.391 +    if (!NT_SUCCESS(status))
   5.392 +    {
   5.393 +      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   5.394 +    }
   5.395 +    break;
   5.396 +  case URB_FUNCTION_SELECT_INTERFACE:
   5.397 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SELECT_INTERFACE\n"));
   5.398 +    interface_information = &urb->UrbSelectInterface.Interface;
   5.399 +    KdPrint((__DRIVER_NAME "     InterfaceInformation\n"));
   5.400 +    KdPrint((__DRIVER_NAME "      Length = %d\n", interface_information->Length));
   5.401 +    KdPrint((__DRIVER_NAME "      InterfaceNumber = %d\n", interface_information->InterfaceNumber));
   5.402 +    KdPrint((__DRIVER_NAME "      AlternateSetting = %d\n", interface_information->AlternateSetting));
   5.403 +    KdPrint((__DRIVER_NAME "      Class = %02x\n", (ULONG)interface_information->Class));
   5.404 +    KdPrint((__DRIVER_NAME "      SubClass = %02x\n", (ULONG)interface_information->SubClass));
   5.405 +    KdPrint((__DRIVER_NAME "      Protocol = %02x\n", (ULONG)interface_information->Protocol));
   5.406 +    KdPrint((__DRIVER_NAME "      Reserved = %02x\n", (ULONG)interface_information->Reserved));
   5.407 +    KdPrint((__DRIVER_NAME "      InterfaceHandle = %p\n", interface_information->InterfaceHandle));
   5.408 +    KdPrint((__DRIVER_NAME "      NumberOfPipes = %d\n", interface_information->NumberOfPipes));
   5.409 +    for (i = 0; i < interface_information->NumberOfPipes; i++)
   5.410 +    {
   5.411 +      KdPrint((__DRIVER_NAME "      Pipe[%d]\n", i));
   5.412 +      KdPrint((__DRIVER_NAME "       MaximumPacketSize = %d\n", interface_information->Pipes[i].MaximumPacketSize));
   5.413 +      KdPrint((__DRIVER_NAME "       EndpointAddress = %d\n", interface_information->Pipes[i].EndpointAddress));
   5.414 +      KdPrint((__DRIVER_NAME "       Interval = %d\n", interface_information->Pipes[i].Interval));
   5.415 +      KdPrint((__DRIVER_NAME "       PipeType = %d\n", interface_information->Pipes[i].PipeType));
   5.416 +      KdPrint((__DRIVER_NAME "       PipeHandle = %p\n", interface_information->Pipes[i].PipeHandle));
   5.417 +      KdPrint((__DRIVER_NAME "       MaximumTransferSize = %d\n", interface_information->Pipes[i].MaximumTransferSize));
   5.418 +      KdPrint((__DRIVER_NAME "       PipeFlags = %08x\n", interface_information->Pipes[i].PipeFlags));
   5.419 +    }
   5.420 +
   5.421 +    shadow = get_shadow_from_freelist(xudd);
   5.422 +    shadow->request = request;
   5.423 +    shadow->urb = urb;
   5.424 +    shadow->mdl = NULL;
   5.425 +    shadow->dma_transaction = NULL;
   5.426 +    shadow->callback = XenUsb_UrbCallback;
   5.427 +    shadow->req.id = shadow->id;
   5.428 +    shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   5.429 +    shadow->req.transfer_flags = 0;
   5.430 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   5.431 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
   5.432 +    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   5.433 +    setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   5.434 +    setup_packet->bRequest = USB_REQUEST_SET_INTERFACE;
   5.435 +    setup_packet->wLength = 0;
   5.436 +    setup_packet->wValue.W = urb->UrbSelectInterface.Interface.AlternateSetting;
   5.437 +    setup_packet->wIndex.W = urb->UrbSelectInterface.Interface.InterfaceNumber;
   5.438 +    status = XenUsb_ExecuteRequest(xudd, shadow, NULL, NULL, 0);
   5.439 +    if (!NT_SUCCESS(status))
   5.440 +    {
   5.441 +      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   5.442 +    }
   5.443 +    break;
   5.444 +  case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
   5.445 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"));
   5.446 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength));
   5.447 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlDescriptorRequest.TransferBuffer));
   5.448 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlDescriptorRequest.TransferBufferMDL));
   5.449 +    KdPrint((__DRIVER_NAME "      Index = %d\n", (int)urb->UrbControlDescriptorRequest.Index));
   5.450 +    KdPrint((__DRIVER_NAME "      DescriptorType = %d\n", (int)urb->UrbControlDescriptorRequest.DescriptorType));
   5.451 +    KdPrint((__DRIVER_NAME "      LanguageId = %04x\n", urb->UrbControlDescriptorRequest.LanguageId));
   5.452 +#if 0
   5.453 +{
   5.454 +  PUCHAR addr = urb->UrbControlDescriptorRequest.TransferBuffer;
   5.455 +  if (!addr)
   5.456 +    addr = MmGetSystemAddressForMdlSafe(urb->UrbControlDescriptorRequest.TransferBufferMDL, HighPagePriority);
   5.457 +  for (i = 0; i < min(urb->UrbControlDescriptorRequest.TransferBufferLength, 16); i++)
   5.458 +    KdPrint((__DRIVER_NAME "      UrbControlDescriptorRequest[%02x] = %02x\n", i, addr[i]));
   5.459 +}
   5.460 +#endif
   5.461 +    shadow = get_shadow_from_freelist(xudd);
   5.462 +    shadow->request = request;
   5.463 +    shadow->urb = urb;
   5.464 +    shadow->callback = XenUsb_UrbCallback;
   5.465 +    shadow->req.id = shadow->id;
   5.466 +    shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   5.467 +    shadow->req.transfer_flags = 0; 
   5.468 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   5.469 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   5.470 +    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   5.471 +    setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   5.472 +    setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
   5.473 +    setup_packet->wValue.LowByte = urb->UrbControlDescriptorRequest.Index;
   5.474 +    setup_packet->wValue.HiByte = urb->UrbControlDescriptorRequest.DescriptorType;
   5.475 +    switch(urb->UrbControlDescriptorRequest.DescriptorType)
   5.476 +    {
   5.477 +    case USB_STRING_DESCRIPTOR_TYPE:
   5.478 +      setup_packet->wIndex.W = urb->UrbControlDescriptorRequest.LanguageId;
   5.479 +      break;
   5.480 +    default:
   5.481 +      setup_packet->wIndex.W = 0;
   5.482 +      break;
   5.483 +    }
   5.484 +    setup_packet->wLength = urb->UrbControlDescriptorRequest.TransferBufferLength;
   5.485 +    status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbControlDescriptorRequest.TransferBuffer, urb->UrbControlDescriptorRequest.TransferBufferMDL, urb->UrbControlDescriptorRequest.TransferBufferLength);
   5.486 +    if (!NT_SUCCESS(status))
   5.487 +    {
   5.488 +      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   5.489 +    }
   5.490 +    break;
   5.491 +  case URB_FUNCTION_CLASS_INTERFACE:
   5.492 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_INTERFACE\n"));
   5.493 +    KdPrint((__DRIVER_NAME "      TransferFlags  = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   5.494 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.495 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.496 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.497 +    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.498 +    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.499 +    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.500 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.501 +
   5.502 +    shadow = get_shadow_from_freelist(xudd);
   5.503 +    shadow->request = request;
   5.504 +    shadow->urb = urb;
   5.505 +    shadow->callback = XenUsb_UrbCallback;
   5.506 +    shadow->req.id = shadow->id;
   5.507 +    shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   5.508 +    shadow->req.transfer_flags = 0;
   5.509 +    if (!(urb->UrbControlVendorClassRequest.TransferFlags & USBD_SHORT_TRANSFER_OK))
   5.510 +      shadow->req.transfer_flags |= LINUX_URB_SHORT_NOT_OK;
   5.511 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   5.512 +    setup_packet->bmRequestType.B = urb->UrbControlVendorClassRequest.RequestTypeReservedBits;
   5.513 +    if (urb->UrbControlVendorClassRequest.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   5.514 +    {      
   5.515 +      setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   5.516 +      shadow->req.pipe |= LINUX_PIPE_DIRECTION_IN;
   5.517 +    }
   5.518 +    else
   5.519 +    {
   5.520 +      setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   5.521 +      shadow->req.pipe |= LINUX_PIPE_DIRECTION_OUT;
   5.522 +    }
   5.523 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
   5.524 +    setup_packet->bmRequestType.Type = BMREQUEST_CLASS;
   5.525 +    setup_packet->bRequest = urb->UrbControlVendorClassRequest.Request;
   5.526 +    setup_packet->wValue.W = urb->UrbControlVendorClassRequest.Value;
   5.527 +    setup_packet->wIndex.W = urb->UrbControlVendorClassRequest.Index;
   5.528 +    status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbControlVendorClassRequest.TransferBuffer, urb->UrbControlVendorClassRequest.TransferBufferMDL, urb->UrbControlVendorClassRequest.TransferBufferLength);
   5.529 +    if (!NT_SUCCESS(status))
   5.530 +    {
   5.531 +      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   5.532 +    }
   5.533 +    break;
   5.534 +#if 0
   5.535 +  case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
   5.536 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_STATUS_FROM_DEVICE\n"));
   5.537 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlGetStatusRequest.TransferBufferLength));
   5.538 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlGetStatusRequest.TransferBuffer));
   5.539 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlGetStatusRequest.TransferBufferMDL));
   5.540 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlGetStatusRequest.Index));
   5.541 +    if (urb->UrbControlGetStatusRequest.Index == 0)
   5.542 +    {
   5.543 +      urb->UrbControlGetStatusRequest.TransferBufferLength = 2;
   5.544 +      *(PUSHORT)urb->UrbControlGetStatusRequest.TransferBuffer = 0x0003;
   5.545 +      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.546 +      WdfRequestComplete(request, STATUS_SUCCESS);
   5.547 +    }
   5.548 +    else
   5.549 +    {
   5.550 +      KdPrint((__DRIVER_NAME "     Unknown Index\n"));
   5.551 +      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   5.552 +      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   5.553 +    }    
   5.554 +    break;
   5.555 +  case URB_FUNCTION_CLASS_DEVICE:
   5.556 +#if 0
   5.557 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_DEVICE\n"));
   5.558 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.559 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.560 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.561 +    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.562 +    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.563 +    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.564 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.565 +#endif
   5.566 +    switch (urb->UrbControlVendorClassRequest.Request)
   5.567 +    {
   5.568 +    case USB_REQUEST_GET_DESCRIPTOR:
   5.569 +      KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_DEVICE\n"));
   5.570 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.571 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.572 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.573 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.574 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.575 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.576 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.577 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_DESCRIPTOR\n"));
   5.578 +      switch (urb->UrbControlVendorClassRequest.Value >> 8)
   5.579 +      {
   5.580 +      case 0x00:
   5.581 +#if 0      
   5.582 +        memcpy(urb->UrbControlVendorClassRequest.TransferBuffer, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
   5.583 +        urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
   5.584 +        urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.585 +        WdfRequestComplete(request, STATUS_SUCCESS);
   5.586 +        break;
   5.587 +#endif
   5.588 +      case 0x29: // Hub Descriptor
   5.589 +        KdPrint((__DRIVER_NAME "       HUB_DESCRIPTOR\n"));
   5.590 +        uhd = urb->UrbControlVendorClassRequest.TransferBuffer;
   5.591 +        urb->UrbControlVendorClassRequest.TransferBufferLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask[0]) + 2 + 1;
   5.592 +        uhd->bDescriptorLength = (UCHAR)urb->UrbControlVendorClassRequest.TransferBufferLength;
   5.593 +        uhd->bDescriptorType = 0x29;
   5.594 +        uhd->bNumberOfPorts = 8;
   5.595 +        uhd->wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
   5.596 +        uhd->bPowerOnToPowerGood = 1; // 2ms units
   5.597 +        uhd->bHubControlCurrent = 0;
   5.598 +        // DeviceRemovable bits (includes an extra bit at the start)
   5.599 +        uhd->bRemoveAndPowerMask[0] = 0;
   5.600 +        uhd->bRemoveAndPowerMask[1] = 0;
   5.601 +        // PortPwrCtrlMask
   5.602 +        uhd->bRemoveAndPowerMask[2] = 0xFF;
   5.603 +        urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.604 +        WdfRequestComplete(request, STATUS_SUCCESS);
   5.605 +        break;
   5.606 +      default:
   5.607 +        KdPrint((__DRIVER_NAME "       Unknown Value %02x\n", urb->UrbControlVendorClassRequest.Value >> 8));
   5.608 +        urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   5.609 +        WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   5.610 +        break;
   5.611 +      }
   5.612 +      break;
   5.613 +    case USB_REQUEST_GET_STATUS:
   5.614 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   5.615 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.616 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.617 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.618 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.619 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.620 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.621 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.622 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_STATUS\n"));
   5.623 +      // Check that RequestTypeReservedBits == 0xA0
   5.624 +      KdPrint((__DRIVER_NAME "       GetHubStatus\n"));
   5.625 +      /* hub status */
   5.626 +      // shoud be able to get this field from somewhere else...
   5.627 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0x0000;
   5.628 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[1] = 0x0000; /* no change occurred */
   5.629 +      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.630 +      WdfRequestComplete(request, STATUS_SUCCESS);
   5.631 +      break;
   5.632 +    case USB_REQUEST_CLEAR_FEATURE:
   5.633 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   5.634 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.635 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.636 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.637 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.638 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.639 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.640 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.641 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_CLEAR_FEATURE\n"));
   5.642 +      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.643 +      WdfRequestComplete(request, STATUS_SUCCESS);
   5.644 +      break;
   5.645 +    default:
   5.646 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   5.647 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.648 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.649 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.650 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.651 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.652 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.653 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.654 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_%02x\n", urb->UrbControlVendorClassRequest.Request));
   5.655 +      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   5.656 +      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   5.657 +      break;
   5.658 +    }
   5.659 +#if 0
   5.660 +    shadow = get_shadow_from_freelist(xudd);
   5.661 +    shadow->request = request;
   5.662 +    shadow->urb = urb;
   5.663 +    shadow->callback = XenUsb_UrbCallback;
   5.664 +    shadow->req.id = shadow->id;
   5.665 +    shadow->req.pipe = PIPE_TYPE_CTRL | (1 << 8) | usb_device->port_number;
   5.666 +    if (urb->UrbControlVendorClassRequest.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   5.667 +      shadow->req.pipe |= PIPE_DIRECTION_IN;
   5.668 +#if 0
   5.669 +    if (urb->UrbControlVendorClassRequest.TransferFlags & USBD_SHORT_TRANSFER_OK)
   5.670 +      shadow->req.transfer_flags = ;
   5.671 +#endif
   5.672 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   5.673 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   5.674 +    setup_packet->bmRequestType.Type = BMREQUEST_CLASS;
   5.675 +    if (urb->UrbControlVendorClassRequest.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   5.676 +      setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   5.677 +    else
   5.678 +      setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   5.679 +    setup_packet->bmRequestType.B |= urb->UrbControlVendorClassRequest.RequestTypeReservedBits;
   5.680 +    setup_packet->bRequest = urb->UrbControlVendorClassRequest.Request;
   5.681 +    setup_packet->wValue.W = urb->UrbControlVendorClassRequest.Value;
   5.682 +    setup_packet->wIndex.W = urb->UrbControlVendorClassRequest.Index;
   5.683 +    setup_packet->wLength = shadow->req.buffer_lengthxxx;
   5.684 +    if (!urb->UrbControlVendorClassRequest.TransferBufferMDL)
   5.685 +    {
   5.686 +      mdl = IoAllocateMdl(urb->UrbControlVendorClassRequest.TransferBuffer, urb->UrbControlVendorClassRequest.TransferBufferLength, FALSE, FALSE, NULL);
   5.687 +      MmBuildMdlForNonPagedPool(mdl);
   5.688 +      shadow->mdl = mdl;
   5.689 +    }
   5.690 +    else
   5.691 +    {
   5.692 +      mdl = urb->UrbControlVendorClassRequest.TransferBufferMDL;
   5.693 +      shadow->mdl = NULL;
   5.694 +    }
   5.695 +    KdPrint((__DRIVER_NAME "     VA = %p\n", MmGetMdlVirtualAddress(mdl)));
   5.696 +    KdPrint((__DRIVER_NAME "     phys = %08x\n", MmGetPhysicalAddress(urb->UrbControlVendorClassRequest.TransferBuffer).LowPart));
   5.697 +    KdPrint((__DRIVER_NAME "     PFN[0] = %08x\n", MmGetMdlPfnArray(mdl)[0]));
   5.698 +
   5.699 +    status = WdfDmaTransactionCreate(xudd->dma_enabler, WDF_NO_OBJECT_ATTRIBUTES, &shadow->dma_transaction);
   5.700 +    if (!status)
   5.701 +    {
   5.702 +      KdPrint((__DRIVER_NAME "     WdfDmaTransactionCreate status = %08x\n", status));
   5.703 +    }
   5.704 +    status = WdfDmaTransactionInitialize(
   5.705 +      shadow->dma_transaction,
   5.706 +      XenUsb_FillShadowSegs,
   5.707 +      (shadow->req.pipe & PIPE_DIRECTION_IN)?WdfDmaDirectionReadFromDevice:WdfDmaDirectionWriteToDevice,
   5.708 +      mdl,
   5.709 +      MmGetMdlVirtualAddress(mdl),
   5.710 +      urb->UrbControlVendorClassRequest.TransferBufferLength);
   5.711 +    if (!status)
   5.712 +    {
   5.713 +      KdPrint((__DRIVER_NAME "     WdfDmaTransactionInitialize status = %08x\n", status));
   5.714 +    }
   5.715 +    status = WdfDmaTransactionExecute(shadow->dma_transaction, shadow);
   5.716 +    if (!status)
   5.717 +    {
   5.718 +      KdPrint((__DRIVER_NAME "     WdfDmaTransactionExecute status = %08x\n", status));
   5.719 +    }
   5.720 +#endif
   5.721 +    break;
   5.722 +  case URB_FUNCTION_CLASS_OTHER:
   5.723 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_OTHER\n"));
   5.724 +    KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   5.725 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   5.726 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   5.727 +    KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   5.728 +    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   5.729 +    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   5.730 +    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   5.731 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   5.732 +    switch (urb->UrbControlVendorClassRequest.Request)
   5.733 +    {
   5.734 +    case USB_REQUEST_GET_STATUS:
   5.735 +      /* port status - 11.24.2.7.1 */
   5.736 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_STATUS\n"));
   5.737 +      KdPrint((__DRIVER_NAME "       GetHubStatus\n"));
   5.738 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[0] = xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status;
   5.739 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[1] = xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change;
   5.740 +      break;
   5.741 +    case USB_REQUEST_SET_FEATURE:
   5.742 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_SET_FEATURE\n"));
   5.743 +      KdPrint((__DRIVER_NAME "       SetPortFeature\n"));
   5.744 +      switch (urb->UrbControlVendorClassRequest.Value)
   5.745 +      {
   5.746 +      case PORT_ENABLE:
   5.747 +        KdPrint((__DRIVER_NAME "        PORT_ENABLE\n"));
   5.748 +        /* do something here */
   5.749 +        break;
   5.750 +      case PORT_RESET:
   5.751 +        KdPrint((__DRIVER_NAME "        PORT_RESET\n"));
   5.752 +        /* just fake the reset */
   5.753 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change |= (1 << PORT_RESET);
   5.754 +        break;
   5.755 +      default:
   5.756 +        KdPrint((__DRIVER_NAME "        Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value));
   5.757 +        break;
   5.758 +      }
   5.759 +      KdPrint((__DRIVER_NAME "        status = %04x, change = %04x\n",
   5.760 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   5.761 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   5.762 +      break;
   5.763 +    case USB_REQUEST_CLEAR_FEATURE:
   5.764 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_CLEAR_FEATURE\n"));
   5.765 +      KdPrint((__DRIVER_NAME "       ClearPortFeature\n"));
   5.766 +      switch (urb->UrbControlVendorClassRequest.Value)
   5.767 +      {
   5.768 +      case C_PORT_CONNECTION:
   5.769 +        KdPrint((__DRIVER_NAME "        C_PORT_CONNECTION\n"));
   5.770 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change &= ~(1 << PORT_CONNECTION);
   5.771 +        break;
   5.772 +      case C_PORT_RESET:
   5.773 +        KdPrint((__DRIVER_NAME "        C_PORT_RESET\n"));
   5.774 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change &= ~(1 << PORT_RESET);
   5.775 +        break;
   5.776 +      default:
   5.777 +        KdPrint((__DRIVER_NAME "        Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value));
   5.778 +        break;
   5.779 +      }
   5.780 +      KdPrint((__DRIVER_NAME "        status = %04x, change = %04x\n",
   5.781 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   5.782 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   5.783 +      break;
   5.784 +    default:
   5.785 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_%02x\n", urb->UrbControlVendorClassRequest.Request));
   5.786 +      break;
   5.787 +    }
   5.788 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.789 +    WdfRequestComplete(request, STATUS_SUCCESS);
   5.790 +    //urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   5.791 +    //WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   5.792 +    break;
   5.793 +#endif
   5.794 +  case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
   5.795 +#if 0
   5.796 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n"));
   5.797 +    KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbBulkOrInterruptTransfer.PipeHandle));
   5.798 +#endif
   5.799 +//    KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags));
   5.800 +//    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbBulkOrInterruptTransfer.TransferBufferLength));
   5.801 +#if 0
   5.802 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBuffer));
   5.803 +    KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBufferMDL));
   5.804 +    KdPrint((__DRIVER_NAME "      UrbLink = %p\n", urb->UrbBulkOrInterruptTransfer.UrbLink));
   5.805 +#endif
   5.806 +#if 0
   5.807 +{
   5.808 +  PUCHAR addr = urb->UrbBulkOrInterruptTransfer.TransferBuffer;
   5.809 +  if (!addr)
   5.810 +    addr = MmGetSystemAddressForMdlSafe(urb->UrbBulkOrInterruptTransfer.TransferBufferMDL, HighPagePriority);
   5.811 +  for (i = 0; i < min(urb->UrbBulkOrInterruptTransfer.TransferBufferLength, 16); i++)
   5.812 +    KdPrint((__DRIVER_NAME "      UrbBulkOrInterruptTransfer[%02x] = %02x\n", i, addr[i]));
   5.813 +}
   5.814 +#endif
   5.815 +    endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;    
   5.816 +//    KdPrint((__DRIVER_NAME "      pipe_value = %08x\n", endpoint->pipe_value));
   5.817 +    shadow = get_shadow_from_freelist(xudd);
   5.818 +    //KdPrint((__DRIVER_NAME "      id = %d\n", shadow->id));
   5.819 +    shadow->request = request;
   5.820 +    shadow->urb = urb;
   5.821 +    shadow->callback = XenUsb_UrbCallback;
   5.822 +    shadow->req.id = shadow->id;
   5.823 +    shadow->req.pipe = endpoint->pipe_value;
   5.824 +    shadow->req.transfer_flags = 0;
   5.825 +    if (!(urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK) && (endpoint->pipe_value & LINUX_PIPE_DIRECTION_IN))
   5.826 +      shadow->req.transfer_flags |= LINUX_URB_SHORT_NOT_OK;
   5.827 +    switch(endpoint->endpoint_descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK)
   5.828 +    {
   5.829 +    case USB_ENDPOINT_TYPE_BULK:
   5.830 +      //KdPrint((__DRIVER_NAME "      USB_ENDPOINT_TYPE_BULK\n"));
   5.831 +      break;
   5.832 +    case USB_ENDPOINT_TYPE_INTERRUPT:
   5.833 +      //KdPrint((__DRIVER_NAME "      USB_ENDPOINT_TYPE_INTERRUPT\n"));
   5.834 +      break;
   5.835 +    default:
   5.836 +      KdPrint((__DRIVER_NAME "      USB_ENDPOINT_TYPE_%d\n", endpoint->endpoint_descriptor.bmAttributes));
   5.837 +      break;
   5.838 +    }
   5.839 +    KeQuerySystemTime((PLARGE_INTEGER)&shadow->submit_time);
   5.840 +    status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferMDL, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
   5.841 +    if (!NT_SUCCESS(status))
   5.842 +    {
   5.843 +      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   5.844 +    }
   5.845 +    break;
   5.846 +#if 0
   5.847 +  case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
   5.848 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n"));
   5.849 +    KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
   5.850 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   5.851 +    WdfRequestComplete(request, STATUS_SUCCESS);
   5.852 +    break;
   5.853 +#endif
   5.854 +  default:
   5.855 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_%04x\n", urb->UrbHeader.Function));
   5.856 +    KdPrint((__DRIVER_NAME "     Calling WdfRequestCompletestatus with status = %08x\n", status));
   5.857 +    urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   5.858 +    WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   5.859 +    break;
   5.860 +  }
   5.861 +  //FUNCTION_EXIT();
   5.862 +}
   5.863 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xenusb/xenusb_fdo.c	Fri Sep 11 22:44:11 2009 +1000
     6.3 @@ -0,0 +1,865 @@
     6.4 +/*
     6.5 +PV Drivers for Windows Xen HVM Domains
     6.6 +Copyright (C) 2007 James Harper
     6.7 +
     6.8 +This program is free software; you can redistribute it and/or
     6.9 +modify it under the terms of the GNU General Public License
    6.10 +as published by the Free Software Foundation; either version 2
    6.11 +of the License, or (at your option) any later version.
    6.12 +
    6.13 +This program is distributed in the hope that it will be useful,
    6.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 +GNU General Public License for more details.
    6.17 +
    6.18 +You should have received a copy of the GNU General Public License
    6.19 +along with this program; if not, write to the Free Software
    6.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    6.21 +*/
    6.22 +
    6.23 +#include "xenusb.h"
    6.24 +
    6.25 +static BOOLEAN
    6.26 +XenUsb_ExecuteRequestCallback(
    6.27 +  WDFDMATRANSACTION dma_transaction,
    6.28 +  WDFDEVICE device,
    6.29 +  PVOID context,
    6.30 +  WDF_DMA_DIRECTION direction,
    6.31 +  PSCATTER_GATHER_LIST sg_list)
    6.32 +{
    6.33 +  usbif_shadow_t *shadow = context;
    6.34 +  PXENUSB_DEVICE_DATA xudd = GetXudd(device);
    6.35 +  ULONG i;
    6.36 +  int notify;
    6.37 +  KIRQL old_irql;
    6.38 +
    6.39 +  UNREFERENCED_PARAMETER(direction);
    6.40 +  UNREFERENCED_PARAMETER(dma_transaction);
    6.41 +
    6.42 +  //FUNCTION_ENTER();
    6.43 +
    6.44 +  shadow->req.buffer_length = 0;
    6.45 +  for (i = 0; i < sg_list->NumberOfElements; i++)
    6.46 +  {
    6.47 +    shadow->req.seg[i].gref = (grant_ref_t)(sg_list->Elements->Address.QuadPart >> PAGE_SHIFT);
    6.48 +    shadow->req.seg[i].offset = (USHORT)sg_list->Elements->Address.LowPart & (PAGE_SIZE - 1);
    6.49 +    shadow->req.seg[i].length = (USHORT)sg_list->Elements->Length;
    6.50 +    shadow->req.buffer_length += sg_list->Elements->Length;
    6.51 +  }
    6.52 +  shadow->req.nr_buffer_segs = (USHORT)sg_list->NumberOfElements;
    6.53 +  //KdPrint((__DRIVER_NAME "     buffer_length = %d\n", shadow->req.buffer_length));
    6.54 +  //KdPrint((__DRIVER_NAME "     nr_buffer_segs = %d\n", shadow->req.nr_buffer_segs));
    6.55 +
    6.56 +  KeAcquireSpinLock(&xudd->ring_lock, &old_irql);
    6.57 +  *RING_GET_REQUEST(&xudd->ring, xudd->ring.req_prod_pvt) = shadow->req;
    6.58 +  xudd->ring.req_prod_pvt++;
    6.59 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->ring, notify);
    6.60 +  if (notify)
    6.61 +  {
    6.62 +    //KdPrint((__DRIVER_NAME "     Notifying\n"));
    6.63 +    xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
    6.64 +  }
    6.65 +  KeReleaseSpinLock(&xudd->ring_lock, old_irql);
    6.66 +
    6.67 +  //FUNCTION_EXIT();
    6.68 +  
    6.69 +  return TRUE;
    6.70 +}
    6.71 +
    6.72 +NTSTATUS
    6.73 +XenUsb_ExecuteRequest(
    6.74 + PXENUSB_DEVICE_DATA xudd,
    6.75 + usbif_shadow_t *shadow,
    6.76 + PVOID transfer_buffer,
    6.77 + PMDL transfer_buffer_mdl,
    6.78 + ULONG transfer_buffer_length)
    6.79 +{
    6.80 +  NTSTATUS status;
    6.81 +  KIRQL old_irql;
    6.82 +  PMDL mdl;
    6.83 +  int notify;
    6.84 +  
    6.85 +  //FUNCTION_ENTER();
    6.86 +  
    6.87 +  //KdPrint((__DRIVER_NAME "     transfer_buffer_length = %d\n", transfer_buffer_length));
    6.88 +  shadow->total_length = 0;
    6.89 +  if (!transfer_buffer_length)
    6.90 +  {
    6.91 +    shadow->mdl = NULL;
    6.92 +    shadow->dma_transaction = NULL;
    6.93 +    shadow->req.nr_buffer_segs = 0;
    6.94 +    shadow->req.buffer_length = 0;
    6.95 +
    6.96 +    KeAcquireSpinLock(&xudd->ring_lock, &old_irql);
    6.97 +    *RING_GET_REQUEST(&xudd->ring, xudd->ring.req_prod_pvt) = shadow->req;
    6.98 +    xudd->ring.req_prod_pvt++;
    6.99 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xudd->ring, notify);
   6.100 +    if (notify)
   6.101 +    {
   6.102 +      //KdPrint((__DRIVER_NAME "     Notifying\n"));
   6.103 +      xudd->vectors.EvtChn_Notify(xudd->vectors.context, xudd->event_channel);
   6.104 +    }
   6.105 +    KeReleaseSpinLock(&xudd->ring_lock, old_irql);
   6.106 +    //FUNCTION_EXIT();
   6.107 +    return STATUS_SUCCESS;
   6.108 +  }
   6.109 +  ASSERT(transfer_buffer || transfer_buffer_mdl);
   6.110 +  if (transfer_buffer)
   6.111 +  {
   6.112 +    mdl = IoAllocateMdl(transfer_buffer, transfer_buffer_length, FALSE, FALSE, NULL);
   6.113 +    ASSERT(mdl);
   6.114 +    MmBuildMdlForNonPagedPool(mdl);
   6.115 +    shadow->mdl = mdl;
   6.116 +  }
   6.117 +  else
   6.118 +  {
   6.119 +    if (!MmGetMdlVirtualAddress(transfer_buffer_mdl))
   6.120 +    {
   6.121 +      /* WdfDmaTransactionInitialize has a bug where it crashes on VirtualAddress == 0 */
   6.122 +      PVOID addr = MmGetSystemAddressForMdlSafe(transfer_buffer_mdl, LowPagePriority);
   6.123 +      //KdPrint((__DRIVER_NAME "     Mapping MDL with NULL VA to work around bug in WdfDmaTransactionInitialize\n"));
   6.124 +      if (!addr)
   6.125 +      {
   6.126 +        KdPrint((__DRIVER_NAME "     Could not map MDL\n"));
   6.127 +        return STATUS_INSUFFICIENT_RESOURCES;
   6.128 +      }
   6.129 +      mdl = IoAllocateMdl(addr, transfer_buffer_length, FALSE, FALSE, NULL);
   6.130 +      ASSERT(mdl);
   6.131 +      MmBuildMdlForNonPagedPool(mdl);
   6.132 +      shadow->mdl = mdl;
   6.133 +    }
   6.134 +    else
   6.135 +    {
   6.136 +      mdl = transfer_buffer_mdl;
   6.137 +      shadow->mdl = NULL;
   6.138 +    }
   6.139 +  }
   6.140 +  status = WdfDmaTransactionCreate(xudd->dma_enabler, WDF_NO_OBJECT_ATTRIBUTES, &shadow->dma_transaction);
   6.141 +  if (!NT_SUCCESS(status))
   6.142 +  {
   6.143 +    KdPrint((__DRIVER_NAME "     WdfDmaTransactionCreate status = %08x\n", status));
   6.144 +    if (shadow->mdl)
   6.145 +    {
   6.146 +      IoFreeMdl(shadow->mdl);
   6.147 +    }
   6.148 +    FUNCTION_EXIT();
   6.149 +    return status;
   6.150 +  }
   6.151 +
   6.152 +  ASSERT(shadow->dma_transaction);  
   6.153 +  ASSERT(mdl);
   6.154 +  ASSERT(transfer_buffer_length);
   6.155 +
   6.156 +  status = WdfDmaTransactionInitialize(
   6.157 +    shadow->dma_transaction,
   6.158 +    XenUsb_ExecuteRequestCallback,
   6.159 +    (shadow->req.pipe & LINUX_PIPE_DIRECTION_IN)?WdfDmaDirectionReadFromDevice:WdfDmaDirectionWriteToDevice,
   6.160 +    mdl,
   6.161 +    MmGetMdlVirtualAddress(mdl),
   6.162 +    transfer_buffer_length);
   6.163 +  if (!NT_SUCCESS(status))
   6.164 +  {
   6.165 +    KdPrint((__DRIVER_NAME "     WdfDmaTransactionInitialize status = %08x\n", status));
   6.166 +    WdfObjectDelete(shadow->dma_transaction);
   6.167 +    if (shadow->mdl)
   6.168 +    {
   6.169 +      IoFreeMdl(shadow->mdl);
   6.170 +    }
   6.171 +    //FUNCTION_EXIT();
   6.172 +    return status;
   6.173 +  }
   6.174 +  WdfDmaTransactionSetMaximumLength(shadow->dma_transaction, 512);
   6.175 +  status = WdfDmaTransactionExecute(shadow->dma_transaction, shadow);
   6.176 +  if (!NT_SUCCESS(status))
   6.177 +  {
   6.178 +    KdPrint((__DRIVER_NAME "     WdfDmaTransactionExecute status = %08x\n", status));
   6.179 +    WdfObjectDelete(shadow->dma_transaction);
   6.180 +    if (shadow->mdl)
   6.181 +    {
   6.182 +      IoFreeMdl(shadow->mdl);
   6.183 +    }
   6.184 +    //FUNCTION_EXIT();
   6.185 +    return status;
   6.186 +  }
   6.187 +  //FUNCTION_EXIT();
   6.188 +  return status;
   6.189 +}
   6.190 +
   6.191 +NTSTATUS
   6.192 +XenUsb_EvtDeviceQueryRemove(WDFDEVICE device)
   6.193 +{
   6.194 +  //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
   6.195 +  NTSTATUS status = STATUS_SUCCESS;
   6.196 +
   6.197 +  UNREFERENCED_PARAMETER(device);
   6.198 +  
   6.199 +  FUNCTION_ENTER();
   6.200 +  FUNCTION_EXIT();
   6.201 +  return status;
   6.202 +}
   6.203 +
   6.204 +static NTSTATUS
   6.205 +XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE(WDFDEVICE device, PIRP irp)
   6.206 +{
   6.207 +  PIO_STACK_LOCATION stack;
   6.208 + 
   6.209 +  FUNCTION_ENTER();
   6.210 + 
   6.211 +  stack = IoGetCurrentIrpStackLocation(irp);
   6.212 +
   6.213 +  if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID, sizeof(GUID)) == 0)
   6.214 +    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_GUID\n"));
   6.215 +  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID, sizeof(GUID)) == 0)
   6.216 +    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_USBDI_GUID\n"));
   6.217 +  else
   6.218 +    KdPrint((__DRIVER_NAME "     GUID = %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
   6.219 +      stack->Parameters.QueryInterface.InterfaceType->Data1,
   6.220 +      stack->Parameters.QueryInterface.InterfaceType->Data2,
   6.221 +      stack->Parameters.QueryInterface.InterfaceType->Data3,
   6.222 +      (stack->Parameters.QueryInterface.InterfaceType->Data4[0] << 8) |
   6.223 +       stack->Parameters.QueryInterface.InterfaceType->Data4[1],
   6.224 +      stack->Parameters.QueryInterface.InterfaceType->Data4[2],
   6.225 +      stack->Parameters.QueryInterface.InterfaceType->Data4[3],
   6.226 +      stack->Parameters.QueryInterface.InterfaceType->Data4[4],
   6.227 +      stack->Parameters.QueryInterface.InterfaceType->Data4[5],
   6.228 +      stack->Parameters.QueryInterface.InterfaceType->Data4[6],
   6.229 +      stack->Parameters.QueryInterface.InterfaceType->Data4[7]));
   6.230 +
   6.231 +  KdPrint((__DRIVER_NAME "     Size = %d\n", stack->Parameters.QueryInterface.Size));
   6.232 +  KdPrint((__DRIVER_NAME "     Version = %d\n", stack->Parameters.QueryInterface.Version));
   6.233 +  KdPrint((__DRIVER_NAME "     Interface = %p\n", stack->Parameters.QueryInterface.Interface));
   6.234 +
   6.235 +
   6.236 +  IoSkipCurrentIrpStackLocation(irp);
   6.237 +  
   6.238 +  FUNCTION_EXIT();
   6.239 +
   6.240 +  return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
   6.241 +}
   6.242 +
   6.243 +/* called at DISPATCH_LEVEL */
   6.244 +static BOOLEAN
   6.245 +XenUsb_HandleEvent(PVOID context)
   6.246 +{
   6.247 +  PXENUSB_DEVICE_DATA xudd = context;
   6.248 +  RING_IDX i, prod, cons;
   6.249 +  usbif_response_t *rsp;
   6.250 +  int more_to_do = TRUE;
   6.251 +  usbif_shadow_t *complete_head = NULL, *complete_tail = NULL;
   6.252 +  usbif_shadow_t *shadow;
   6.253 +
   6.254 +  //FUNCTION_ENTER();
   6.255 +
   6.256 +  KeAcquireSpinLockAtDpcLevel(&xudd->ring_lock);
   6.257 +  while (more_to_do)
   6.258 +  {
   6.259 +    prod = xudd->ring.sring->rsp_prod;
   6.260 +    KeMemoryBarrier();
   6.261 +    for (cons = xudd->ring.rsp_cons; cons != prod; cons++)
   6.262 +    {
   6.263 +      rsp = RING_GET_RESPONSE(&xudd->ring, cons);
   6.264 +      shadow = &xudd->shadows[rsp->id];
   6.265 +      ASSERT(shadow->callback);
   6.266 +      shadow->rsp = *rsp;
   6.267 +      shadow->next = NULL;
   6.268 +      shadow->total_length += rsp->actual_length;
   6.269 +#if 0
   6.270 +      KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   6.271 +      KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   6.272 +      KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   6.273 +      KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   6.274 +      KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   6.275 +      KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
   6.276 +#endif
   6.277 +      if (complete_tail)
   6.278 +      {
   6.279 +        complete_tail->next = shadow;
   6.280 +      }
   6.281 +      else
   6.282 +      {
   6.283 +        complete_head = shadow;
   6.284 +      }
   6.285 +      complete_tail = shadow;
   6.286 +    }
   6.287 +
   6.288 +    xudd->ring.rsp_cons = cons;
   6.289 +    if (cons != xudd->ring.req_prod_pvt)
   6.290 +    {
   6.291 +      RING_FINAL_CHECK_FOR_RESPONSES(&xudd->ring, more_to_do);
   6.292 +    }
   6.293 +    else
   6.294 +    {
   6.295 +      xudd->ring.sring->rsp_event = cons + 1;
   6.296 +      more_to_do = FALSE;
   6.297 +    }
   6.298 +  }
   6.299 +  KeReleaseSpinLockFromDpcLevel(&xudd->ring_lock);
   6.300 +
   6.301 +  shadow = complete_head;
   6.302 +  while (shadow != NULL)
   6.303 +  {
   6.304 +    if (shadow->dma_transaction)
   6.305 +    {
   6.306 +      NTSTATUS status;
   6.307 +      BOOLEAN dma_complete;
   6.308 +      if (shadow->rsp.status != 0 || shadow->rsp.actual_length != shadow->req.buffer_length)
   6.309 +      {
   6.310 +        WdfDmaTransactionDmaCompletedFinal(shadow->dma_transaction, shadow->total_length, &status);
   6.311 +        WdfObjectDelete(shadow->dma_transaction);
   6.312 +        if (shadow->mdl)
   6.313 +        {
   6.314 +          IoFreeMdl(shadow->mdl);
   6.315 +        }
   6.316 +        shadow->callback(shadow);
   6.317 +      }
   6.318 +      else
   6.319 +      {
   6.320 +        dma_complete = WdfDmaTransactionDmaCompleted(shadow->dma_transaction, &status);
   6.321 +        if (dma_complete)
   6.322 +        {
   6.323 +          WdfObjectDelete(shadow->dma_transaction);
   6.324 +          if (shadow->mdl)
   6.325 +          {
   6.326 +            IoFreeMdl(shadow->mdl);
   6.327 +          }
   6.328 +          shadow->callback(shadow);
   6.329 +        }
   6.330 +      }
   6.331 +    }
   6.332 +    else
   6.333 +    {
   6.334 +      shadow->callback(shadow);
   6.335 +    }
   6.336 +    shadow = shadow->next;
   6.337 +  }
   6.338 +  //FUNCTION_EXIT();
   6.339 +
   6.340 +  return TRUE;
   6.341 +}
   6.342 +
   6.343 +static NTSTATUS
   6.344 +XenUsb_StartXenbusInit(PXENUSB_DEVICE_DATA xudd)
   6.345 +{
   6.346 +  PUCHAR ptr;
   6.347 +  USHORT type;
   6.348 +  PCHAR setting, value, value2;
   6.349 +
   6.350 +  xudd->sring = NULL;
   6.351 +  xudd->event_channel = 0;
   6.352 +
   6.353 +  xudd->inactive = TRUE;
   6.354 +  ptr = xudd->config_page;
   6.355 +  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   6.356 +  {
   6.357 +    switch(type)
   6.358 +    {
   6.359 +    case XEN_INIT_TYPE_READ_STRING_BACK:
   6.360 +    case XEN_INIT_TYPE_READ_STRING_FRONT:
   6.361 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   6.362 +      break;
   6.363 +    case XEN_INIT_TYPE_VECTORS:
   6.364 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
   6.365 +      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
   6.366 +        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
   6.367 +      {
   6.368 +        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
   6.369 +          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
   6.370 +        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.371 +        return STATUS_UNSUCCESSFUL;
   6.372 +      }
   6.373 +      else
   6.374 +        memcpy(&xudd->vectors, value, sizeof(XENPCI_VECTORS));
   6.375 +      break;
   6.376 +    case XEN_INIT_TYPE_STATE_PTR:
   6.377 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
   6.378 +      xudd->device_state = (PXENPCI_DEVICE_STATE)value;
   6.379 +      break;
   6.380 +    case XEN_INIT_TYPE_ACTIVE:
   6.381 +      xudd->inactive = FALSE;
   6.382 +      break;
   6.383 +#if 0
   6.384 +    case XEN_INIT_TYPE_GRANT_ENTRIES:
   6.385 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_GRANT_ENTRIES - entries = %d\n", PtrToUlong(setting)));
   6.386 +      memcpy(xudd->dump_grant_refs, value, PtrToUlong(setting) * sizeof(grant_ref_t));
   6.387 +      break;
   6.388 +#endif
   6.389 +    default:
   6.390 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   6.391 +      break;
   6.392 +    }
   6.393 +  }
   6.394 +
   6.395 +  return STATUS_SUCCESS;
   6.396 +}
   6.397 +
   6.398 +static NTSTATUS
   6.399 +XenUsb_CompleteXenbusInit(PXENUSB_DEVICE_DATA xudd)
   6.400 +{
   6.401 +  PUCHAR ptr;
   6.402 +  USHORT type;
   6.403 +  PCHAR setting, value, value2;
   6.404 +
   6.405 +  ptr = xudd->config_page;
   6.406 +  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
   6.407 +  {
   6.408 +    switch(type)
   6.409 +    {
   6.410 +    case XEN_INIT_TYPE_RING: /* frontend ring */
   6.411 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_RING - %s = %p\n", setting, value));
   6.412 +      if (strcmp(setting, "ring-ref") == 0)
   6.413 +      {
   6.414 +        xudd->sring = (usbif_sring_t *)value;
   6.415 +        FRONT_RING_INIT(&xudd->ring, xudd->sring, PAGE_SIZE);
   6.416 +      }
   6.417 +      break;
   6.418 +    case XEN_INIT_TYPE_EVENT_CHANNEL_DPC: /* frontend event channel */
   6.419 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_EVENT_CHANNEL_DPC - %s = %d\n", setting, PtrToUlong(value) & 0x3FFFFFFF));
   6.420 +      if (strcmp(setting, "event-channel") == 0)
   6.421 +      {
   6.422 +        xudd->event_channel = PtrToUlong(value);
   6.423 +      }
   6.424 +      break;
   6.425 +    case XEN_INIT_TYPE_READ_STRING_BACK:
   6.426 +    case XEN_INIT_TYPE_READ_STRING_FRONT:
   6.427 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_READ_STRING - %s = %s\n", setting, value));
   6.428 +      break;
   6.429 +    default:
   6.430 +      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
   6.431 +      break;
   6.432 +    }
   6.433 +  }
   6.434 +  if (!xudd->inactive && (xudd->sring == NULL || xudd->event_channel == 0))
   6.435 +  {
   6.436 +    KdPrint((__DRIVER_NAME "     Missing settings\n"));
   6.437 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.438 +    return STATUS_UNSUCCESSFUL;
   6.439 +  }
   6.440 +  
   6.441 +  if (xudd->inactive)
   6.442 +  {
   6.443 +    KdPrint((__DRIVER_NAME "     Device is inactive\n"));
   6.444 +  }
   6.445 +  else
   6.446 +  {
   6.447 +    ULONG i;
   6.448 +    xudd->shadow_free = 0;
   6.449 +    memset(xudd->shadows, 0, sizeof(usbif_shadow_t) * SHADOW_ENTRIES);
   6.450 +    for (i = 0; i < SHADOW_ENTRIES; i++)
   6.451 +    {
   6.452 +      xudd->shadows[i].id = (uint16_t)i;
   6.453 +      put_shadow_on_freelist(xudd, &xudd->shadows[i]);
   6.454 +    }
   6.455 +  }
   6.456 +  
   6.457 +  return STATUS_SUCCESS;
   6.458 +}
   6.459 +
   6.460 +NTSTATUS
   6.461 +XenUsb_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
   6.462 +{
   6.463 +  NTSTATUS status = STATUS_SUCCESS;
   6.464 +  PXENUSB_DEVICE_DATA xudd = GetXudd(device);
   6.465 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR raw_descriptor, translated_descriptor;
   6.466 +  ULONG i;
   6.467 +  PUCHAR ptr;
   6.468 +
   6.469 +  FUNCTION_ENTER();
   6.470 +  
   6.471 +  ASSERT(WdfCmResourceListGetCount(resources_raw) == WdfCmResourceListGetCount(resources_translated));
   6.472 +  
   6.473 +  for (i = 0; i < WdfCmResourceListGetCount(resources_raw); i++)
   6.474 +  {
   6.475 +    raw_descriptor = WdfCmResourceListGetDescriptor(resources_raw, i);
   6.476 +    translated_descriptor = WdfCmResourceListGetDescriptor(resources_translated, i);
   6.477 +    switch (raw_descriptor->Type) {
   6.478 +    case CmResourceTypePort:
   6.479 +      KdPrint((__DRIVER_NAME "     IoPort Address(%x) Length: %d\n", translated_descriptor->u.Port.Start.LowPart, translated_descriptor->u.Port.Length));
   6.480 +      break;
   6.481 +    case CmResourceTypeMemory:
   6.482 +      KdPrint((__DRIVER_NAME "     Memory (%x:%x) Length:(%d)\n", translated_descriptor->u.Memory.Start.LowPart, translated_descriptor->u.Memory.Start.HighPart, translated_descriptor->u.Memory.Length));
   6.483 +      KdPrint((__DRIVER_NAME "     Memory flags = %04X\n", translated_descriptor->Flags));
   6.484 +      xudd->config_page = MmMapIoSpace(translated_descriptor->u.Memory.Start, translated_descriptor->u.Memory.Length, MmNonCached);
   6.485 +      KdPrint((__DRIVER_NAME "     Memory mapped to %p\n", xudd->config_page));
   6.486 +      break;
   6.487 +    case CmResourceTypeInterrupt:
   6.488 +      KdPrint((__DRIVER_NAME "     irq_number = %03x\n", raw_descriptor->u.Interrupt.Vector));
   6.489 +      KdPrint((__DRIVER_NAME "     irq_vector = %03x\n", translated_descriptor->u.Interrupt.Vector));
   6.490 +      KdPrint((__DRIVER_NAME "     irq_level = %03x\n", translated_descriptor->u.Interrupt.Level));
   6.491 +      break;
   6.492 +    case CmResourceTypeDevicePrivate:
   6.493 +      KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", translated_descriptor->u.DevicePrivate.Data[0], translated_descriptor->u.DevicePrivate.Data[1], translated_descriptor->u.DevicePrivate.Data[2]));
   6.494 +      break;
   6.495 +    default:
   6.496 +      KdPrint((__DRIVER_NAME "     Unhandled resource type (0x%x)\n", translated_descriptor->Type));
   6.497 +      break;
   6.498 +    }
   6.499 +  }
   6.500 +
   6.501 +  status = XenUsb_StartXenbusInit(xudd);
   6.502 +
   6.503 +  ptr = xudd->config_page;
   6.504 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RUN, NULL, NULL, NULL);
   6.505 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_RING, "ring-ref", NULL, NULL);
   6.506 +  #pragma warning(suppress:4054)
   6.507 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_EVENT_CHANNEL_DPC, "event-channel", (PVOID)XenUsb_HandleEvent, xudd);
   6.508 +  ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
   6.509 +  status = xudd->vectors.XenPci_XenConfigDevice(xudd->vectors.context);
   6.510 +
   6.511 +  status = XenUsb_CompleteXenbusInit(xudd);
   6.512 +  
   6.513 +  FUNCTION_EXIT();
   6.514 +
   6.515 +  return status;
   6.516 +}
   6.517 +
   6.518 +NTSTATUS
   6.519 +XenUsb_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
   6.520 +{
   6.521 +  NTSTATUS status = STATUS_SUCCESS;
   6.522 +  //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
   6.523 +
   6.524 +  UNREFERENCED_PARAMETER(device);
   6.525 +
   6.526 +  FUNCTION_ENTER();
   6.527 +
   6.528 +  switch (previous_state)
   6.529 +  {
   6.530 +  case WdfPowerDeviceD0:
   6.531 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   6.532 +    break;
   6.533 +  case WdfPowerDeviceD1:
   6.534 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   6.535 +    break;
   6.536 +  case WdfPowerDeviceD2:
   6.537 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD2\n"));
   6.538 +    break;
   6.539 +  case WdfPowerDeviceD3:
   6.540 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3\n"));
   6.541 +    break;
   6.542 +  case WdfPowerDeviceD3Final:
   6.543 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3Final\n"));
   6.544 +    break;
   6.545 +  case WdfPowerDevicePrepareForHibernation:
   6.546 +    KdPrint((__DRIVER_NAME "     WdfPowerDevicePrepareForHibernation\n"));
   6.547 +    break;  
   6.548 +  default:
   6.549 +    KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", previous_state));
   6.550 +    break;  
   6.551 +  }
   6.552 +
   6.553 +  FUNCTION_EXIT();
   6.554 +
   6.555 +  return status;
   6.556 +}
   6.557 +
   6.558 +NTSTATUS
   6.559 +XenUsb_EvtDeviceD0EntryPostInterruptsEnabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
   6.560 +{
   6.561 +  NTSTATUS status = STATUS_SUCCESS;
   6.562 +  //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
   6.563 +
   6.564 +  UNREFERENCED_PARAMETER(device);
   6.565 +  UNREFERENCED_PARAMETER(previous_state);
   6.566 +
   6.567 +  FUNCTION_ENTER();
   6.568 +  
   6.569 +  FUNCTION_EXIT();
   6.570 +  
   6.571 +  return status;
   6.572 +}
   6.573 +
   6.574 +NTSTATUS
   6.575 +XenUsb_EvtDeviceD0ExitPreInterruptsDisabled(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
   6.576 +{
   6.577 +  NTSTATUS status = STATUS_SUCCESS;
   6.578 +  
   6.579 +  UNREFERENCED_PARAMETER(device);
   6.580 +  
   6.581 +  FUNCTION_ENTER();
   6.582 +  
   6.583 +  switch (target_state)
   6.584 +  {
   6.585 +  case WdfPowerDeviceD0:
   6.586 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   6.587 +    break;
   6.588 +  case WdfPowerDeviceD1:
   6.589 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   6.590 +    break;
   6.591 +  case WdfPowerDeviceD2:
   6.592 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD2\n"));
   6.593 +    break;
   6.594 +  case WdfPowerDeviceD3:
   6.595 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3\n"));
   6.596 +    break;
   6.597 +  case WdfPowerDeviceD3Final:
   6.598 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3Final\n"));
   6.599 +    break;
   6.600 +  case WdfPowerDevicePrepareForHibernation:
   6.601 +    KdPrint((__DRIVER_NAME "     WdfPowerDevicePrepareForHibernation\n"));
   6.602 +    break;
   6.603 +  default:
   6.604 +    KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", target_state));
   6.605 +    break;  
   6.606 +  }
   6.607 +  
   6.608 +  FUNCTION_EXIT();
   6.609 +  
   6.610 +  return status;
   6.611 +}
   6.612 +
   6.613 +NTSTATUS
   6.614 +XenUsb_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
   6.615 +{
   6.616 +  NTSTATUS status = STATUS_SUCCESS;
   6.617 +  //PXENUSB_DEVICE_DATA xudd = GetXudd(device);
   6.618 +  
   6.619 +  FUNCTION_ENTER();
   6.620 +
   6.621 +  UNREFERENCED_PARAMETER(device);
   6.622 +
   6.623 +  switch (target_state)
   6.624 +  {
   6.625 +  case WdfPowerDeviceD0:
   6.626 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   6.627 +    break;
   6.628 +  case WdfPowerDeviceD1:
   6.629 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   6.630 +    break;
   6.631 +  case WdfPowerDeviceD2:
   6.632 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD2\n"));
   6.633 +    break;
   6.634 +  case WdfPowerDeviceD3:
   6.635 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3\n"));
   6.636 +    break;
   6.637 +  case WdfPowerDeviceD3Final:
   6.638 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3Final\n"));
   6.639 +    break;
   6.640 +  case WdfPowerDevicePrepareForHibernation:
   6.641 +    KdPrint((__DRIVER_NAME "     WdfPowerDevicePrepareForHibernation\n"));
   6.642 +    break;  
   6.643 +  default:
   6.644 +    KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", target_state));
   6.645 +    break;  
   6.646 +  }
   6.647 +  
   6.648 +  FUNCTION_EXIT();
   6.649 +  
   6.650 +  return status;
   6.651 +}
   6.652 +
   6.653 +NTSTATUS
   6.654 +XenUsb_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
   6.655 +{
   6.656 +  NTSTATUS status = STATUS_SUCCESS;
   6.657 +  
   6.658 +  UNREFERENCED_PARAMETER(device);
   6.659 +  UNREFERENCED_PARAMETER(resources_translated);
   6.660 +  
   6.661 +  FUNCTION_ENTER();
   6.662 +  FUNCTION_EXIT();
   6.663 +  
   6.664 +  return status;
   6.665 +}
   6.666 +
   6.667 +#if 0
   6.668 +VOID
   6.669 +XenUsb_PrepareShadow(usbif_shadow_t *shadow, PVOID setup_packet, ULONG data_length)
   6.670 +{
   6.671 +}
   6.672 +#endif
   6.673 +
   6.674 +VOID
   6.675 +XenUsb_EvtChildListScanForChildren(WDFCHILDLIST child_list)
   6.676 +{
   6.677 +  NTSTATUS status;
   6.678 +  PXENUSB_DEVICE_DATA xudd = GetXudd(WdfChildListGetDevice(child_list));
   6.679 +  XENUSB_PDO_IDENTIFICATION_DESCRIPTION child_description;
   6.680 +  CHAR path[128];
   6.681 +  PCHAR err;
   6.682 +  PCHAR value;
   6.683 +  ULONG i;
   6.684 +  usbif_shadow_t *shadow;
   6.685 +  PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
   6.686 +  int notify;
   6.687 +
   6.688 +  FUNCTION_ENTER();
   6.689 +
   6.690 +  WdfChildListBeginScan(child_list);
   6.691 +
   6.692 +  // hold the queue on each device and set each device to a pending state
   6.693 +  // read backend/num_ports
   6.694 +  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/num-ports", xudd->vectors.backend_path);
   6.695 +  err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
   6.696 +  if (err)
   6.697 +  {
   6.698 +    XenPci_FreeMem(err);
   6.699 +    WdfChildListEndScan(child_list);
   6.700 +    KdPrint((__DRIVER_NAME "     Failed to read num-ports\n"));
   6.701 +    return;
   6.702 +  }
   6.703 +  xudd->num_ports = (ULONG)parse_numeric_string(value);  
   6.704 +  XenPci_FreeMem(value);
   6.705 +  KdPrint((__DRIVER_NAME "     num-ports = %d\n", xudd->num_ports));
   6.706 +
   6.707 +  for (i = 0; i < 8; i++)
   6.708 +  {
   6.709 +    xudd->ports[i].port_number = i + 1;
   6.710 +    xudd->ports[i].port_type = USB_PORT_TYPE_NOT_CONNECTED;
   6.711 +    xudd->ports[i].port_status = 0x0002;
   6.712 +    xudd->ports[i].port_change = 0x0000;
   6.713 +  }  
   6.714 +
   6.715 +  /* only a single root hub is enumerated */
   6.716 +  WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&child_description.header, sizeof(child_description));
   6.717 +
   6.718 +  child_description.device_number = 0; //TODO: get the proper index from parent
   6.719 +
   6.720 +  status = WdfChildListAddOrUpdateChildDescriptionAsPresent(child_list, &child_description.header, NULL);
   6.721 +  if (!NT_SUCCESS(status))
   6.722 +  {
   6.723 +    KdPrint((__DRIVER_NAME "     WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status 0x%08x\n", status));
   6.724 +  }
   6.725 +
   6.726 +  WdfChildListEndScan(child_list);
   6.727 +  
   6.728 +  FUNCTION_EXIT();
   6.729 +}
   6.730 +
   6.731 +static VOID
   6.732 +XenUsb_EvtIoInternalDeviceControl(
   6.733 +  WDFQUEUE queue,
   6.734 +  WDFREQUEST request,
   6.735 +  size_t output_buffer_length,
   6.736 +  size_t input_buffer_length,
   6.737 +  ULONG io_control_code)
   6.738 +{
   6.739 +  WDFDEVICE device = WdfIoQueueGetDevice(queue);
   6.740 +  PXENUSB_DEVICE_DATA xudd = GetXudd(device);
   6.741 +
   6.742 +  UNREFERENCED_PARAMETER(input_buffer_length);
   6.743 +  UNREFERENCED_PARAMETER(output_buffer_length);
   6.744 +
   6.745 +  FUNCTION_ENTER();
   6.746 +
   6.747 +  switch(io_control_code)
   6.748 +  {
   6.749 +  case IOCTL_XEN_RECONFIGURE:
   6.750 +    KdPrint((__DRIVER_NAME "     IOCTL_XEN_RECONFIGURE\n"));
   6.751 +    // TODO: Only enumerate once the root hub callback has been called...
   6.752 +    XenUsb_EnumeratePorts(xudd->root_hub_device);
   6.753 +    KdPrint((__DRIVER_NAME "     Completing\n"));
   6.754 +    WdfRequestComplete(request, STATUS_SUCCESS);
   6.755 +    break;
   6.756 +  default:
   6.757 +    KdPrint((__DRIVER_NAME "     Unknown IOCTL %08x\n", io_control_code));
   6.758 +    WdfRequestComplete(request, WdfRequestGetStatus(request));
   6.759 +    break;
   6.760 +  }
   6.761 +
   6.762 +  FUNCTION_EXIT();
   6.763 +}
   6.764 +
   6.765 +NTSTATUS
   6.766 +XenUsb_EvtDriverDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init)
   6.767 +{
   6.768 +  NTSTATUS status;
   6.769 +  WDF_CHILD_LIST_CONFIG child_list_config;
   6.770 +  WDFDEVICE device;
   6.771 +  PXENUSB_DEVICE_DATA xudd;
   6.772 +  //UNICODE_STRING reference;
   6.773 +  WDF_OBJECT_ATTRIBUTES device_attributes;
   6.774 +  PNP_BUS_INFORMATION pbi;
   6.775 +  WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks;
   6.776 +  WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
   6.777 +  WDF_IO_QUEUE_CONFIG queue_config;
   6.778 +  WDF_DMA_ENABLER_CONFIG dma_config;
   6.779 +  UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
   6.780 +  
   6.781 +  UNREFERENCED_PARAMETER(driver);
   6.782 +
   6.783 +  FUNCTION_ENTER();
   6.784 +
   6.785 +  WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
   6.786 +  pnp_power_callbacks.EvtDeviceD0Entry = XenUsb_EvtDeviceD0Entry;
   6.787 +  pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenUsb_EvtDeviceD0EntryPostInterruptsEnabled;
   6.788 +  pnp_power_callbacks.EvtDeviceD0Exit = XenUsb_EvtDeviceD0Exit;
   6.789 +  pnp_power_callbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenUsb_EvtDeviceD0ExitPreInterruptsDisabled;
   6.790 +  pnp_power_callbacks.EvtDevicePrepareHardware = XenUsb_EvtDevicePrepareHardware;
   6.791 +  pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsb_EvtDeviceReleaseHardware;
   6.792 +  pnp_power_callbacks.EvtDeviceQueryRemove = XenUsb_EvtDeviceQueryRemove;
   6.793 +  //pnp_power_callbacks.EvtDeviceUsageNotification = XenUsb_EvtDeviceUsageNotification;
   6.794 +
   6.795 +  WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks);
   6.796 +
   6.797 +  status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE,
   6.798 +    IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions));
   6.799 +  if (!NT_SUCCESS(status))
   6.800 +  {
   6.801 +    return status;
   6.802 +  }
   6.803 +
   6.804 +  WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_BUS_EXTENDER);
   6.805 +  WdfDeviceInitSetExclusive(device_init, FALSE);
   6.806 +
   6.807 +  WDF_CHILD_LIST_CONFIG_INIT(&child_list_config, sizeof(XENUSB_PDO_IDENTIFICATION_DESCRIPTION), XenUsb_EvtChildListCreateDevice);
   6.808 +  child_list_config.EvtChildListScanForChildren = XenUsb_EvtChildListScanForChildren;
   6.809 +  WdfFdoInitSetDefaultChildListConfig(device_init, &child_list_config, WDF_NO_OBJECT_ATTRIBUTES);
   6.810 +
   6.811 +  WdfDeviceInitSetIoType(device_init, WdfDeviceIoBuffered);
   6.812 +
   6.813 +  WdfDeviceInitSetPowerNotPageable(device_init);
   6.814 +  
   6.815 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENUSB_DEVICE_DATA);
   6.816 +  status = WdfDeviceCreate(&device_init, &device_attributes, &device);
   6.817 +  if (!NT_SUCCESS(status))
   6.818 +  {
   6.819 +    KdPrint(("Error creating device %08x\n", status));
   6.820 +    return status;
   6.821 +  }
   6.822 +
   6.823 +  xudd = GetXudd(device);
   6.824 +  xudd->child_list = WdfFdoGetDefaultChildList(device);
   6.825 +
   6.826 +  KeInitializeSpinLock(&xudd->ring_lock);
   6.827 +  
   6.828 +  WdfDeviceSetAlignmentRequirement(device, 0);
   6.829 +  WDF_DMA_ENABLER_CONFIG_INIT(&dma_config, WdfDmaProfileScatterGather64Duplex, PAGE_SIZE);
   6.830 +  status = WdfDmaEnablerCreate(device, &dma_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->dma_enabler);
   6.831 +  if (!NT_SUCCESS(status))
   6.832 +  {
   6.833 +    KdPrint(("Error creating DMA enabler %08x\n", status));
   6.834 +    return status;
   6.835 +  }
   6.836 +
   6.837 +  WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
   6.838 +  queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl;
   6.839 +  status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->io_queue);
   6.840 +  if (!NT_SUCCESS(status)) {
   6.841 +      KdPrint((__DRIVER_NAME "     Error creating io_queue 0x%x\n", status));
   6.842 +      return status;
   6.843 +  }
   6.844 +
   6.845 +  WDF_DEVICE_POWER_CAPABILITIES_INIT(&power_capabilities);
   6.846 +  power_capabilities.DeviceD1 = WdfTrue;
   6.847 +  power_capabilities.WakeFromD1 = WdfTrue;
   6.848 +  power_capabilities.DeviceWake = PowerDeviceD1;
   6.849 +  power_capabilities.DeviceState[PowerSystemWorking]   = PowerDeviceD1;
   6.850 +  power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
   6.851 +  power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
   6.852 +  power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
   6.853 +  power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
   6.854 +  power_capabilities.DeviceState[PowerSystemShutdown]  = PowerDeviceD3;
   6.855 +  WdfDeviceSetPowerCapabilities(device, &power_capabilities);  
   6.856 +
   6.857 +  WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE);
   6.858 +  WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE);
   6.859 +  WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE);
   6.860 +  
   6.861 +  pbi.BusTypeGuid = GUID_BUS_TYPE_XEN;
   6.862 +  pbi.LegacyBusType = PNPBus;
   6.863 +  pbi.BusNumber = 0;
   6.864 +  WdfDeviceSetBusInformationForChildren(device, &pbi);
   6.865 +
   6.866 +  FUNCTION_EXIT();
   6.867 +  return status;
   6.868 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xenusb/xenusb_hub.c	Fri Sep 11 22:44:11 2009 +1000
     7.3 @@ -0,0 +1,1407 @@
     7.4 +/*
     7.5 +PV Drivers for Windows Xen HVM Domains
     7.6 +Copyright (C) 2007 James Harper
     7.7 +
     7.8 +This program is free software; you can redistribute it and/or
     7.9 +modify it under the terms of the GNU General Public License
    7.10 +as published by the Free Software Foundation; either version 2
    7.11 +of the License, or (at your option) any later version.
    7.12 +
    7.13 +This program is distributed in the hope that it will be useful,
    7.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.16 +GNU General Public License for more details.
    7.17 +
    7.18 +You should have received a copy of the GNU General Public License
    7.19 +along with this program; if not, write to the Free Software
    7.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    7.21 +*/
    7.22 +
    7.23 +#include "xenusb.h"
    7.24 +#include <stdlib.h>
    7.25 +
    7.26 +#pragma warning(disable: 4127) // conditional expression is constant
    7.27 +
    7.28 +static VOID
    7.29 +XenUsbHub_EvtIoDefault(
    7.30 +  WDFQUEUE queue,
    7.31 +  WDFREQUEST request)
    7.32 +{
    7.33 +  NTSTATUS status;
    7.34 +  WDF_REQUEST_PARAMETERS parameters;
    7.35 +
    7.36 +  FUNCTION_ENTER();
    7.37 +
    7.38 +  UNREFERENCED_PARAMETER(queue);
    7.39 +
    7.40 +  status = STATUS_UNSUCCESSFUL;
    7.41 +
    7.42 +  WDF_REQUEST_PARAMETERS_INIT(&parameters);
    7.43 +  WdfRequestGetParameters(request, &parameters);
    7.44 +
    7.45 +  switch (parameters.Type)
    7.46 +  {
    7.47 +  case WdfRequestTypeCreate:
    7.48 +    KdPrint((__DRIVER_NAME "     WdfRequestTypeCreate\n"));
    7.49 +    break;
    7.50 +  case WdfRequestTypeClose:
    7.51 +    KdPrint((__DRIVER_NAME "     WdfRequestTypeClose\n"));
    7.52 +    break;
    7.53 +  case WdfRequestTypeRead:
    7.54 +    KdPrint((__DRIVER_NAME "     WdfRequestTypeRead\n"));
    7.55 +    break;
    7.56 +  case WdfRequestTypeWrite:
    7.57 +    KdPrint((__DRIVER_NAME "     WdfRequestTypeWrite\n"));
    7.58 +    break;
    7.59 +  case WdfRequestTypeDeviceControl:
    7.60 +    KdPrint((__DRIVER_NAME "     WdfRequestTypeDeviceControl\n"));
    7.61 +    break;
    7.62 +  case WdfRequestTypeDeviceControlInternal:
    7.63 +    KdPrint((__DRIVER_NAME "     WdfRequestTypeDeviceControlInternal\n"));
    7.64 +    break;
    7.65 +  default:
    7.66 +    KdPrint((__DRIVER_NAME "     Unknown type %x\n", parameters.Type));
    7.67 +    break;
    7.68 +  }
    7.69 +  WdfRequestComplete(request, status);  
    7.70 +
    7.71 +  FUNCTION_EXIT();
    7.72 +}
    7.73 +
    7.74 +
    7.75 +static NTSTATUS
    7.76 +XenUsbHub_BusIrpCompletionRoutine(
    7.77 +  PDEVICE_OBJECT device_object,
    7.78 +  PIRP irp,
    7.79 +  PVOID context)
    7.80 +{
    7.81 +  WDFREQUEST request = context;
    7.82 +
    7.83 +  UNREFERENCED_PARAMETER(device_object);
    7.84 +
    7.85 +  FUNCTION_ENTER();
    7.86 +
    7.87 +  WdfRequestCompleteWithInformation(request, irp->IoStatus.Status, irp->IoStatus.Information);
    7.88 +  IoFreeIrp(irp);
    7.89 +
    7.90 +  FUNCTION_EXIT();
    7.91 +
    7.92 +  return STATUS_MORE_PROCESSING_REQUIRED;
    7.93 +}
    7.94 +
    7.95 +static VOID
    7.96 +XenUsbHub_EvtIoInternalDeviceControl(
    7.97 +  WDFQUEUE queue,
    7.98 +  WDFREQUEST request,
    7.99 +  size_t output_buffer_length,
   7.100 +  size_t input_buffer_length,
   7.101 +  ULONG io_control_code)
   7.102 +{
   7.103 +  NTSTATUS status;
   7.104 +  WDFDEVICE device = WdfIoQueueGetDevice(queue);
   7.105 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
   7.106 +  PDEVICE_OBJECT fdo;
   7.107 +  PIRP irp;
   7.108 +  WDF_REQUEST_PARAMETERS wrp;
   7.109 +  PURB urb;
   7.110 +  xenusb_device_t *usb_device;
   7.111 +
   7.112 +  UNREFERENCED_PARAMETER(input_buffer_length);
   7.113 +  UNREFERENCED_PARAMETER(output_buffer_length);
   7.114 +
   7.115 +  //FUNCTION_ENTER();
   7.116 +
   7.117 +  status = STATUS_UNSUCCESSFUL;
   7.118 +
   7.119 +  WDF_REQUEST_PARAMETERS_INIT(&wrp);
   7.120 +  WdfRequestGetParameters(request, &wrp);
   7.121 +
   7.122 +  // these are in api\usbioctl.h
   7.123 +  switch(io_control_code)
   7.124 +  {
   7.125 +  case IOCTL_INTERNAL_USB_CYCLE_PORT:
   7.126 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_CYCLE_PORT\n"));
   7.127 +    break;
   7.128 +  case IOCTL_INTERNAL_USB_ENABLE_PORT:
   7.129 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_ENABLE_PORT\n"));
   7.130 +    break;
   7.131 +  case IOCTL_INTERNAL_USB_GET_BUS_INFO:
   7.132 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_BUS_INFO\n"));
   7.133 +    break;
   7.134 +  case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
   7.135 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n"));
   7.136 +    break;
   7.137 +  case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
   7.138 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_HUB_COUNT\n"));
   7.139 +    KdPrint((__DRIVER_NAME "     Count before increment = %p\n", *(PULONG)wrp.Parameters.Others.Arg1));
   7.140 +    (*(PULONG)wrp.Parameters.Others.Arg1)++;
   7.141 +    status = STATUS_SUCCESS;
   7.142 +    break;
   7.143 +  case IOCTL_INTERNAL_USB_GET_HUB_NAME:
   7.144 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_HUB_NAME\n"));
   7.145 +    break;
   7.146 +  case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
   7.147 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_PORT_STATUS\n"));
   7.148 +    *(PULONG)wrp.Parameters.Others.Arg1 = USBD_PORT_ENABLED | USBD_PORT_CONNECTED; /* enabled and connected */
   7.149 +    status = STATUS_SUCCESS;
   7.150 +    break;
   7.151 +  case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
   7.152 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n"));
   7.153 +    KdPrint((__DRIVER_NAME "     WdfDeviceWdmGetPhysicalDevice(device) = %p\n", WdfDeviceWdmGetPhysicalDevice(device)));
   7.154 +    KdPrint((__DRIVER_NAME "     WdfDeviceWdmGetDeviceObject(device) = %p\n", WdfDeviceWdmGetDeviceObject(device)));
   7.155 +    KdPrint((__DRIVER_NAME "     WdfDeviceWdmGetAttachedDevice(device) = %p\n", WdfDeviceWdmGetAttachedDevice(device)));
   7.156 +    KdPrint((__DRIVER_NAME "     IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device)) = %p\n", IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device))));
   7.157 +    *(PVOID *)wrp.Parameters.Others.Arg1 = WdfDeviceWdmGetPhysicalDevice(device);
   7.158 +    *(PVOID *)wrp.Parameters.Others.Arg2 = IoGetAttachedDevice(WdfDeviceWdmGetDeviceObject(device));
   7.159 +    status = STATUS_SUCCESS;
   7.160 +    break;
   7.161 +  case IOCTL_INTERNAL_USB_RESET_PORT:
   7.162 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_RESET_PORT\n"));
   7.163 +    break;
   7.164 +  case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
   7.165 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n"));
   7.166 +    break;
   7.167 +  case IOCTL_INTERNAL_USB_SUBMIT_URB:
   7.168 +    urb = (PURB)wrp.Parameters.Others.Arg1;
   7.169 +    ASSERT(urb);
   7.170 +    usb_device = urb->UrbHeader.UsbdDeviceHandle;
   7.171 +    if (!usb_device)
   7.172 +      usb_device = xupdd->usb_device;
   7.173 +    WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
   7.174 +    return;
   7.175 +  case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
   7.176 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE (returning %p)\n", xupdd->usb_device));
   7.177 +    *(PVOID *)wrp.Parameters.Others.Arg1 = xupdd->usb_device;
   7.178 +    status = STATUS_SUCCESS;
   7.179 +    break;
   7.180 +  default:
   7.181 +    KdPrint((__DRIVER_NAME "     Unknown IOCTL %08x\n", io_control_code));
   7.182 +    break;
   7.183 +  }  
   7.184 +
   7.185 +  KdPrint((__DRIVER_NAME "     Calling WdfRequestComplete with status = %08x\n", status));
   7.186 +  WdfRequestComplete(request, status);
   7.187 +
   7.188 +  //FUNCTION_EXIT();
   7.189 +}
   7.190 +
   7.191 +NTSTATUS
   7.192 +XenUsbHub_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
   7.193 +{
   7.194 +  NTSTATUS status = STATUS_SUCCESS;
   7.195 +  
   7.196 +  UNREFERENCED_PARAMETER(device);
   7.197 +
   7.198 +  FUNCTION_ENTER();
   7.199 +
   7.200 +  switch (previous_state)
   7.201 +  {
   7.202 +  case WdfPowerDeviceD0:
   7.203 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   7.204 +    break;
   7.205 +  case WdfPowerDeviceD1:
   7.206 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   7.207 +    break;
   7.208 +  case WdfPowerDeviceD2:
   7.209 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD2\n"));
   7.210 +    break;
   7.211 +  case WdfPowerDeviceD3:
   7.212 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3\n"));
   7.213 +    break;
   7.214 +  case WdfPowerDeviceD3Final:
   7.215 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3Final\n"));
   7.216 +    break;
   7.217 +  case WdfPowerDevicePrepareForHibernation:
   7.218 +    KdPrint((__DRIVER_NAME "     WdfPowerDevicePrepareForHibernation\n"));
   7.219 +    break;  
   7.220 +  default:
   7.221 +    KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", previous_state));
   7.222 +    break;  
   7.223 +  }
   7.224 +  
   7.225 +  FUNCTION_EXIT();
   7.226 +  
   7.227 +  return status;
   7.228 +}
   7.229 +
   7.230 +NTSTATUS
   7.231 +XenUsbHub_EvtDeviceD0Exit(WDFDEVICE device, WDF_POWER_DEVICE_STATE target_state)
   7.232 +{
   7.233 +  NTSTATUS status = STATUS_SUCCESS;
   7.234 +  //PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
   7.235 +  //PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
   7.236 +
   7.237 +  UNREFERENCED_PARAMETER(device);
   7.238 +  
   7.239 +  FUNCTION_ENTER();
   7.240 +  
   7.241 +  switch (target_state)
   7.242 +  {
   7.243 +  case WdfPowerDeviceD0:
   7.244 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   7.245 +    break;
   7.246 +  case WdfPowerDeviceD1:
   7.247 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD1\n"));
   7.248 +    break;
   7.249 +  case WdfPowerDeviceD2:
   7.250 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD2\n"));
   7.251 +    break;
   7.252 +  case WdfPowerDeviceD3:
   7.253 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3\n"));
   7.254 +    break;
   7.255 +  case WdfPowerDeviceD3Final:
   7.256 +    KdPrint((__DRIVER_NAME "     WdfPowerDeviceD3Final\n"));
   7.257 +    break;
   7.258 +  case WdfPowerDevicePrepareForHibernation:
   7.259 +    KdPrint((__DRIVER_NAME "     WdfPowerDevicePrepareForHibernation\n"));
   7.260 +    break;  
   7.261 +  default:
   7.262 +    KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", target_state));
   7.263 +    break;  
   7.264 +  }
   7.265 +  
   7.266 +  FUNCTION_EXIT();
   7.267 +  
   7.268 +  return status;
   7.269 +}
   7.270 +
   7.271 +NTSTATUS
   7.272 +XenUsbHub_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
   7.273 +{
   7.274 +  NTSTATUS status = STATUS_SUCCESS;
   7.275 +
   7.276 +  UNREFERENCED_PARAMETER(device);
   7.277 +  UNREFERENCED_PARAMETER(resources_raw);
   7.278 +  UNREFERENCED_PARAMETER(resources_translated);
   7.279 +  
   7.280 +  FUNCTION_ENTER();
   7.281 +  FUNCTION_EXIT();
   7.282 +  
   7.283 +  return status;
   7.284 +}
   7.285 +
   7.286 +NTSTATUS
   7.287 +XenUsbHub_EvtDeviceReleaseHardware(WDFDEVICE device, WDFCMRESLIST resources_translated)
   7.288 +{
   7.289 +  NTSTATUS status = STATUS_SUCCESS;
   7.290 +  
   7.291 +  UNREFERENCED_PARAMETER(device);
   7.292 +  UNREFERENCED_PARAMETER(resources_translated);
   7.293 +  
   7.294 +  FUNCTION_ENTER();
   7.295 +  FUNCTION_EXIT();
   7.296 +  
   7.297 +  return status;
   7.298 +}
   7.299 +
   7.300 +static VOID
   7.301 +XenUsbHub_EvtDeviceUsageNotification(WDFDEVICE device, WDF_SPECIAL_FILE_TYPE notification_type, BOOLEAN is_in_notification_path)
   7.302 +{
   7.303 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
   7.304 +
   7.305 +  UNREFERENCED_PARAMETER(xupdd);
   7.306 +
   7.307 +  FUNCTION_ENTER();
   7.308 +  
   7.309 +  switch (notification_type)
   7.310 +  {
   7.311 +  case WdfSpecialFilePaging:
   7.312 +    KdPrint((__DRIVER_NAME "     notification_type = Paging, flag = %d\n", is_in_notification_path));
   7.313 +    break;
   7.314 +  case WdfSpecialFileHibernation:
   7.315 +    KdPrint((__DRIVER_NAME "     notification_type = Hibernation, flag = %d\n", is_in_notification_path));
   7.316 +    break;
   7.317 +  case WdfSpecialFileDump:
   7.318 +    KdPrint((__DRIVER_NAME "     notification_type = Dump, flag = %d\n", is_in_notification_path));
   7.319 +    break;
   7.320 +  default:
   7.321 +    KdPrint((__DRIVER_NAME "     notification_type = %d, flag = %d\n", notification_type, is_in_notification_path));
   7.322 +    break;
   7.323 +  }
   7.324 +
   7.325 +  FUNCTION_EXIT();  
   7.326 +}
   7.327 +
   7.328 +static NTSTATUS
   7.329 +XenUsb_SubmitCompletionRoutine(
   7.330 +  PDEVICE_OBJECT device_object,
   7.331 +  PIRP irp,
   7.332 +  PVOID context)
   7.333 +{
   7.334 +  UNREFERENCED_PARAMETER(device_object);
   7.335 +
   7.336 +  FUNCTION_ENTER();
   7.337 +  
   7.338 +  if (irp->PendingReturned)
   7.339 +  {
   7.340 +    KeSetEvent ((PKEVENT)context, IO_NO_INCREMENT, FALSE);
   7.341 +  }
   7.342 +
   7.343 +  FUNCTION_EXIT();
   7.344 +
   7.345 +  return STATUS_MORE_PROCESSING_REQUIRED;
   7.346 +}
   7.347 +
   7.348 +static NTSTATUS
   7.349 +XenPciPdo_UBIH_CreateUsbDevice(
   7.350 +  PVOID BusContext,
   7.351 +  PUSB_DEVICE_HANDLE *DeviceHandle,
   7.352 +  PUSB_DEVICE_HANDLE *HubDeviceHandle,
   7.353 +  USHORT PortStatus,
   7.354 +  USHORT PortNumber)
   7.355 +{
   7.356 +  NTSTATUS status = STATUS_SUCCESS;
   7.357 +  WDFDEVICE device = BusContext;
   7.358 +  FUNCTION_ENTER();
   7.359 +
   7.360 +  KdPrint((__DRIVER_NAME "     device = %p\n", device));
   7.361 +  KdPrint((__DRIVER_NAME "     DeviceHandle = %p\n", DeviceHandle));
   7.362 +  KdPrint((__DRIVER_NAME "     *DeviceHandle = %p\n", *DeviceHandle));
   7.363 +  KdPrint((__DRIVER_NAME "     HubDeviceHandle = %p\n", HubDeviceHandle));
   7.364 +  KdPrint((__DRIVER_NAME "     *HubDeviceHandle = %p\n", *HubDeviceHandle));
   7.365 +  KdPrint((__DRIVER_NAME "     PortStatus = %04X\n", PortStatus));
   7.366 +  KdPrint((__DRIVER_NAME "     PortNumber = %d\n", PortNumber));
   7.367 +  *DeviceHandle = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
   7.368 +  
   7.369 +  FUNCTION_EXIT();
   7.370 +  return status;
   7.371 +}
   7.372 +
   7.373 +static VOID
   7.374 +XenUsb_SetEventCallback(usbif_shadow_t *shadow)
   7.375 +{
   7.376 +  FUNCTION_ENTER();
   7.377 +  KeSetEvent(&shadow->event, IO_NO_INCREMENT, FALSE);
   7.378 +  FUNCTION_EXIT();
   7.379 +}
   7.380 +
   7.381 +static NTSTATUS
   7.382 +XenPciPdo_UBIH_InitializeUsbDevice(
   7.383 + PVOID BusContext,
   7.384 + PUSB_DEVICE_HANDLE DeviceHandle)
   7.385 +{
   7.386 +  NTSTATUS status = STATUS_SUCCESS;
   7.387 +  WDFDEVICE device = BusContext;
   7.388 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
   7.389 +  PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
   7.390 +  WDF_IO_QUEUE_CONFIG queue_config;
   7.391 +  xenusb_device_t *usb_device = DeviceHandle;
   7.392 +  PDEVICE_OBJECT fdo;
   7.393 +  KEVENT irp_complete_event;
   7.394 +  PIRP irp;
   7.395 +  URB urb;
   7.396 +  PIO_STACK_LOCATION stack;
   7.397 +  PUCHAR ptr;
   7.398 +  PVOID buf;
   7.399 +  PMDL mdl;
   7.400 +  usbif_shadow_t *shadow;
   7.401 +  PUSB_DEVICE_DESCRIPTOR device_descriptor;
   7.402 +  PUSB_CONFIGURATION_DESCRIPTOR config_descriptor;
   7.403 +  PUSB_INTERFACE_DESCRIPTOR interface_descriptor;
   7.404 +  PUSB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
   7.405 +  int i, j, k;
   7.406 +  PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
   7.407 +  
   7.408 +  FUNCTION_ENTER();
   7.409 +
   7.410 +  KdPrint((__DRIVER_NAME "     device = %p\n", device));
   7.411 +  KdPrint((__DRIVER_NAME "     usb_device = %p\n", usb_device));
   7.412 +  usb_device->pdo_device = BusContext;
   7.413 +  
   7.414 +  // get address from freelist and assign it to the device...
   7.415 +  usb_device->address = 2;
   7.416 +  usb_device->port_number = 1;
   7.417 +
   7.418 +  buf = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
   7.419 +  mdl = IoAllocateMdl(buf, PAGE_SIZE, FALSE, FALSE, NULL);
   7.420 +  MmBuildMdlForNonPagedPool(mdl);
   7.421 +  shadow = get_shadow_from_freelist(xudd);
   7.422 +
   7.423 +  /* set the address */
   7.424 +  KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
   7.425 +  shadow->callback = XenUsb_SetEventCallback;
   7.426 +  shadow->req.id = shadow->id;
   7.427 +  shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | usb_device->port_number;
   7.428 +  shadow->req.transfer_flags = 0; 
   7.429 +  shadow->req.buffer_length = 0;
   7.430 +  setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   7.431 +  setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   7.432 +  setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   7.433 +  setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   7.434 +  setup_packet->bRequest = USB_REQUEST_SET_ADDRESS;
   7.435 +  setup_packet->wValue.W = usb_device->address;
   7.436 +  setup_packet->wIndex.W = 0;
   7.437 +  setup_packet->wLength = shadow->req.buffer_length;
   7.438 +  status = XenUsb_ExecuteRequest(xudd, shadow, NULL, NULL, 0);
   7.439 +  //TODO: Handle failure here
   7.440 +  KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
   7.441 +  KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   7.442 +  KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   7.443 +  KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   7.444 +  KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   7.445 +  KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   7.446 +
   7.447 +  /* get the device descriptor */
   7.448 +  KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
   7.449 +  shadow->callback = XenUsb_SetEventCallback;
   7.450 +  shadow->req.id = shadow->id;
   7.451 +  shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   7.452 +  shadow->req.transfer_flags = 0; 
   7.453 +  shadow->req.buffer_length = PAGE_SIZE;
   7.454 +  setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   7.455 +  setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   7.456 +  setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   7.457 +  setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   7.458 +  setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
   7.459 +  setup_packet->wValue.LowByte = 0;
   7.460 +  setup_packet->wValue.HiByte = USB_DEVICE_DESCRIPTOR_TYPE; //device descriptor
   7.461 +  setup_packet->wIndex.W = 0;
   7.462 +  setup_packet->wLength = shadow->req.buffer_length;
   7.463 +  status = XenUsb_ExecuteRequest(xudd, shadow, NULL, mdl, PAGE_SIZE);
   7.464 +  //TODO: Handle failure here
   7.465 +  KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
   7.466 +  KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   7.467 +  KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   7.468 +  KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   7.469 +  KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   7.470 +  KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   7.471 +  ptr = buf;
   7.472 +  device_descriptor = (PUSB_DEVICE_DESCRIPTOR)ptr;
   7.473 +  KdPrint((__DRIVER_NAME "     bLength = %d\n", device_descriptor->bLength));
   7.474 +  KdPrint((__DRIVER_NAME "     bNumConfigurations = %d\n", device_descriptor->bNumConfigurations));
   7.475 +  memcpy(&usb_device->device_descriptor, device_descriptor, device_descriptor->bLength);
   7.476 +  usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * device_descriptor->bNumConfigurations, XENUSB_POOL_TAG);
   7.477 +  KdPrint((__DRIVER_NAME "     bLength = %d\n", device_descriptor->bLength));
   7.478 +  KdPrint((__DRIVER_NAME "     bDescriptorType = %d\n", device_descriptor->bDescriptorType));
   7.479 +  KdPrint((__DRIVER_NAME "     bcdUSB = %04x\n", device_descriptor->bcdUSB));
   7.480 +  KdPrint((__DRIVER_NAME "     bDeviceClass = %02x\n", device_descriptor->bDeviceClass));
   7.481 +  KdPrint((__DRIVER_NAME "     bDeviceSubClass = %02x\n", device_descriptor->bDeviceSubClass));
   7.482 +  KdPrint((__DRIVER_NAME "     bDeviceProtocol = %02x\n", device_descriptor->bDeviceProtocol));
   7.483 +  KdPrint((__DRIVER_NAME "     idVendor = %04x\n", device_descriptor->idVendor));
   7.484 +  KdPrint((__DRIVER_NAME "     idProduct = %04x\n", device_descriptor->idProduct));
   7.485 +  KdPrint((__DRIVER_NAME "     bcdDevice = %04x\n", device_descriptor->bcdDevice));
   7.486 +  KdPrint((__DRIVER_NAME "     bNumConfigurations = %04x\n", device_descriptor->bNumConfigurations));
   7.487 +
   7.488 +  /* get the config descriptor */
   7.489 +  for (i = 0; i < device_descriptor->bNumConfigurations; i++)
   7.490 +  {
   7.491 +    KeInitializeEvent(&shadow->event, NotificationEvent, FALSE);
   7.492 +    shadow->callback = XenUsb_SetEventCallback;
   7.493 +    shadow->req.id = shadow->id;
   7.494 +    shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   7.495 +    shadow->req.transfer_flags = 0; 
   7.496 +    shadow->req.buffer_length = PAGE_SIZE;
   7.497 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   7.498 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   7.499 +    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   7.500 +    setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   7.501 +    setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
   7.502 +    setup_packet->wValue.LowByte = i+1;
   7.503 +    setup_packet->wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; //device descriptor
   7.504 +    setup_packet->wIndex.W = 0;
   7.505 +    setup_packet->wLength = shadow->req.buffer_length;
   7.506 +    status = XenUsb_ExecuteRequest(xudd, shadow, buf, NULL, PAGE_SIZE);
   7.507 +    //TODO: Handle failure here
   7.508 +    KeWaitForSingleObject(&shadow->event, Executive, KernelMode, FALSE, NULL);
   7.509 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
   7.510 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
   7.511 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
   7.512 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
   7.513 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
   7.514 +    ptr = buf;
   7.515 +    config_descriptor = ptr;
   7.516 +    KdPrint((__DRIVER_NAME "     Config %d\n", i));
   7.517 +    KdPrint((__DRIVER_NAME "      bLength = %d\n", config_descriptor->bLength));
   7.518 +    KdPrint((__DRIVER_NAME "      bDescriptorType = %d\n", config_descriptor->bDescriptorType));
   7.519 +    KdPrint((__DRIVER_NAME "      wTotalLength = %d\n", config_descriptor->wTotalLength));
   7.520 +    KdPrint((__DRIVER_NAME "      bNumInterfaces = %d\n", config_descriptor->bNumInterfaces));
   7.521 +    KdPrint((__DRIVER_NAME "      iConfiguration = %d\n", config_descriptor->iConfiguration));
   7.522 +    KdPrint((__DRIVER_NAME "      bConfigurationValue = %d\n", config_descriptor->bConfigurationValue));
   7.523 +    KdPrint((__DRIVER_NAME "      bmAttributes = %02x\n", config_descriptor->bmAttributes));
   7.524 +    KdPrint((__DRIVER_NAME "      MaxPower = %d\n", config_descriptor->MaxPower));
   7.525 +    usb_device->configs[i] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * config_descriptor->bNumInterfaces, XENUSB_POOL_TAG);
   7.526 +    usb_device->configs[i]->device = usb_device;
   7.527 +    memcpy(&usb_device->configs[i]->config_descriptor, config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
   7.528 +    ptr += config_descriptor->bLength;
   7.529 +    for (j = 0; j < config_descriptor->bNumInterfaces; j++)
   7.530 +    {
   7.531 +      interface_descriptor = ptr;
   7.532 +      KdPrint((__DRIVER_NAME "       Interface %d\n", j));
   7.533 +      KdPrint((__DRIVER_NAME "        bLength = %d\n", interface_descriptor->bLength));
   7.534 +      KdPrint((__DRIVER_NAME "        bDescriptorType = %d\n", interface_descriptor->bDescriptorType));
   7.535 +      KdPrint((__DRIVER_NAME "        bInterfaceNumber = %d\n", interface_descriptor->bInterfaceNumber));
   7.536 +      KdPrint((__DRIVER_NAME "        bAlternateSetting = %d\n", interface_descriptor->bAlternateSetting));
   7.537 +      KdPrint((__DRIVER_NAME "        bNumEndpoints = %d\n", interface_descriptor->bNumEndpoints));
   7.538 +      KdPrint((__DRIVER_NAME "        bInterfaceClass = %d\n", interface_descriptor->bInterfaceClass));
   7.539 +      KdPrint((__DRIVER_NAME "        bInterfaceSubClass = %d\n", interface_descriptor->bInterfaceSubClass));
   7.540 +      KdPrint((__DRIVER_NAME "        bInterfaceProtocol = %d\n", interface_descriptor->bInterfaceProtocol));
   7.541 +      KdPrint((__DRIVER_NAME "        iInterface = %d\n", interface_descriptor->iInterface));
   7.542 +      ptr += interface_descriptor->bLength;
   7.543 +      usb_device->configs[i]->interfaces[j] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * interface_descriptor->bNumEndpoints, XENUSB_POOL_TAG);
   7.544 +      usb_device->configs[i]->interfaces[j]->config = usb_device->configs[i];
   7.545 +      memcpy(&usb_device->configs[i]->interfaces[j]->interface_descriptor, interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
   7.546 +      for (k = 0; k < interface_descriptor->bNumEndpoints; k++)
   7.547 +      {
   7.548 +        endpoint_descriptor = ptr;
   7.549 +        KdPrint((__DRIVER_NAME "        Endpoint %d\n", k));
   7.550 +        KdPrint((__DRIVER_NAME "         bLength = %d\n", endpoint_descriptor->bLength));
   7.551 +        KdPrint((__DRIVER_NAME "         bDescriptorType = %d\n", endpoint_descriptor->bDescriptorType));
   7.552 +        KdPrint((__DRIVER_NAME "         bEndpointAddress = %02x\n", endpoint_descriptor->bEndpointAddress));
   7.553 +        KdPrint((__DRIVER_NAME "         bmAttributes = %02x\n", endpoint_descriptor->bmAttributes));
   7.554 +        KdPrint((__DRIVER_NAME "         wMaxPacketSize = %d\n", endpoint_descriptor->wMaxPacketSize));
   7.555 +        KdPrint((__DRIVER_NAME "         bInterval = %d\n", endpoint_descriptor->bInterval));
   7.556 +        ptr += endpoint_descriptor->bLength;
   7.557 +        usb_device->configs[i]->interfaces[j]->endpoints[k] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
   7.558 +        usb_device->configs[i]->interfaces[j]->endpoints[k]->interface = usb_device->configs[i]->interfaces[j];
   7.559 +        usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value = (usb_device->address << 8) | usb_device->port_number;
   7.560 +        /* linux uses nonstandard endpoint type identifiers... */
   7.561 +        switch(endpoint_descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
   7.562 +        {
   7.563 +        case USB_ENDPOINT_TYPE_CONTROL:
   7.564 +          usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_CTRL;
   7.565 +          break;
   7.566 +        case USB_ENDPOINT_TYPE_ISOCHRONOUS:
   7.567 +          usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_ISOC;
   7.568 +          break;
   7.569 +        case USB_ENDPOINT_TYPE_BULK:
   7.570 +          usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_BULK;
   7.571 +          break;
   7.572 +        case USB_ENDPOINT_TYPE_INTERRUPT:
   7.573 +          usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= LINUX_PIPE_TYPE_INTR;
   7.574 +          break;
   7.575 +        }
   7.576 +        usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x80);
   7.577 +        usb_device->configs[i]->interfaces[j]->endpoints[k]->pipe_value |= (endpoint_descriptor->bEndpointAddress & 0x0F) << 15;
   7.578 +        memcpy(&usb_device->configs[i]->interfaces[j]->endpoints[k]->endpoint_descriptor, endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
   7.579 +      }
   7.580 +    }
   7.581 +  }
   7.582 +
   7.583 +#if 0
   7.584 +  WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_lock);
   7.585 +  WDF_TIMER_CONFIG_INIT(&timer_config, XenUsbHub_HubInterruptTimer);  
   7.586 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timer_attributes, pxenusb_endpoint_t);
   7.587 +  timer_attributes.ParentObject = child_device;
   7.588 +  status = WdfTimerCreate(&timer_config, &timer_attributes, &usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer);
   7.589 +  if (!NT_SUCCESS(status)) {
   7.590 +      KdPrint((__DRIVER_NAME "     Error creating timer 0x%x\n", status));
   7.591 +      return status;
   7.592 +  }
   7.593 +  *GetEndpoint(usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer) = usb_device->configs[0]->interfaces[0]->endpoints[0];
   7.594 +  WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
   7.595 +  //queue_config.PowerManaged = TRUE;
   7.596 +  status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES,
   7.597 +    &usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_queue);
   7.598 +  if (!NT_SUCCESS(status)) {
   7.599 +      KdPrint((__DRIVER_NAME "     Error creating timer io_queue 0x%x\n", status));
   7.600 +      return status;
   7.601 +  }
   7.602 +#endif
   7.603 +  
   7.604 +  WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
   7.605 +  queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_DEVICE_SUBMIT_URB;
   7.606 +  queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
   7.607 +  status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &usb_device->urb_queue);
   7.608 +  if (!NT_SUCCESS(status)) {
   7.609 +      KdPrint((__DRIVER_NAME "     Error creating urb_queue 0x%x\n", status));
   7.610 +      return status;
   7.611 +  }
   7.612 +
   7.613 +  put_shadow_on_freelist(xudd, shadow);
   7.614 +
   7.615 +  FUNCTION_EXIT();
   7.616 +  return status;
   7.617 +}
   7.618 +
   7.619 +static NTSTATUS
   7.620 +XenPciPdo_UBIH_GetUsbDescriptors(
   7.621 +  PVOID BusContext,
   7.622 +  PUSB_DEVICE_HANDLE DeviceHandle,
   7.623 +  PUCHAR DeviceDescriptorBuffer,
   7.624 +  PULONG DeviceDescriptorBufferLength,
   7.625 +  PUCHAR ConfigDescriptorBuffer,
   7.626 +  PULONG ConfigDescriptorBufferLength
   7.627 +  )
   7.628 +{
   7.629 +  NTSTATUS status = STATUS_SUCCESS;
   7.630 +  WDFDEVICE device = BusContext;
   7.631 +  xenusb_device_t *usb_device = DeviceHandle;
   7.632 +  xenusb_config_t *usb_config;
   7.633 +  int i, j;
   7.634 +  PUCHAR ptr;
   7.635 +
   7.636 +  FUNCTION_ENTER();
   7.637 +
   7.638 +  KdPrint((__DRIVER_NAME "     device = %p\n", device));
   7.639 +  KdPrint((__DRIVER_NAME "     DeviceHandle = %p\n", DeviceHandle));
   7.640 +  KdPrint((__DRIVER_NAME "     DeviceDescriptorBuffer = %p\n", DeviceDescriptorBuffer));
   7.641 +  KdPrint((__DRIVER_NAME "     DeviceDescriptorBufferLength = %d\n", *DeviceDescriptorBufferLength));
   7.642 +  KdPrint((__DRIVER_NAME "     ConfigDescriptorBuffer = %p\n", ConfigDescriptorBuffer));
   7.643 +  KdPrint((__DRIVER_NAME "     ConfigDescriptorBufferLength = %d\n", *ConfigDescriptorBufferLength));
   7.644 +  
   7.645 +  memcpy(DeviceDescriptorBuffer, &usb_device->device_descriptor, usb_device->device_descriptor.bLength);
   7.646 +  *DeviceDescriptorBufferLength = usb_device->device_descriptor.bLength;
   7.647 +  
   7.648 +  usb_config = usb_device->active_config;
   7.649 +  ptr = ConfigDescriptorBuffer;
   7.650 +  KdPrint((__DRIVER_NAME "     memcpy(%p, %p, %d)\n", ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)));
   7.651 +  memcpy(ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
   7.652 +  ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
   7.653 +#if 0
   7.654 +  for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
   7.655 +  {
   7.656 +    memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
   7.657 +    ptr += sizeof(USB_INTERFACE_DESCRIPTOR);
   7.658 +    ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_INTERFACE_DESCRIPTOR);
   7.659 +    for (j = 0; j < usb_config->interfaces[i]->interface_descriptor.bNumEndpoints; j++)
   7.660 +    {
   7.661 +      memcpy(ptr, &usb_config->interfaces[i]->endpoints[j]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
   7.662 +      ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
   7.663 +      ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
   7.664 +    }
   7.665 +  }
   7.666 +#endif
   7.667 +  *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); //((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
   7.668 +  
   7.669 +  FUNCTION_EXIT();
   7.670 +  return status;
   7.671 +}
   7.672 +
   7.673 +static NTSTATUS
   7.674 +XenPciPdo_UBIH_RemoveUsbDevice (
   7.675 + PVOID BusContext,
   7.676 + PUSB_DEVICE_HANDLE DeviceHandle,
   7.677 + ULONG Flags)
   7.678 +{
   7.679 +  NTSTATUS status = STATUS_SUCCESS;
   7.680 +  FUNCTION_ENTER();
   7.681 +  
   7.682 +  if (Flags & USBD_KEEP_DEVICE_DATA)
   7.683 +    KdPrint((__DRIVER_NAME "     USBD_KEEP_DEVICE_DATA\n"));
   7.684 +    
   7.685 +  if (Flags & USBD_MARK_DEVICE_BUSY)
   7.686 +    KdPrint((__DRIVER_NAME "     USBD_MARK_DEVICE_BUSY\n"));
   7.687 +
   7.688 +  FUNCTION_EXIT();
   7.689 +  return status;
   7.690 +}
   7.691 +
   7.692 +static NTSTATUS
   7.693 +XenPciPdo_UBIH_RestoreUsbDevice(
   7.694 +  PVOID BusContext,
   7.695 +  PUSB_DEVICE_HANDLE OldDeviceHandle,
   7.696 +  PUSB_DEVICE_HANDLE NewDeviceHandle)
   7.697 +{
   7.698 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.699 +  FUNCTION_ENTER();
   7.700 +
   7.701 +  FUNCTION_EXIT();
   7.702 +  return status;
   7.703 +}
   7.704 +
   7.705 +static NTSTATUS
   7.706 +XenPciPdo_UBIH_GetPortHackFlags(
   7.707 + PVOID BusContext,
   7.708 + PULONG HackFlags)
   7.709 +{
   7.710 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.711 +  FUNCTION_ENTER();
   7.712 +
   7.713 +  FUNCTION_EXIT();
   7.714 +  return status;
   7.715 +}
   7.716 +
   7.717 +static NTSTATUS
   7.718 +XenPciPdo_UBIH_QueryDeviceInformation(
   7.719 +  PVOID BusContext,
   7.720 +  PUSB_DEVICE_HANDLE DeviceHandle,
   7.721 +  PVOID DeviceInformationBuffer,
   7.722 +  ULONG DeviceInformationBufferLength,
   7.723 +  PULONG LengthOfDataReturned)
   7.724 +{
   7.725 +  PUSB_DEVICE_INFORMATION_0 udi = DeviceInformationBuffer;
   7.726 +  xenusb_device_t *usb_device = DeviceHandle;
   7.727 +
   7.728 +  FUNCTION_ENTER();
   7.729 +
   7.730 +  KdPrint((__DRIVER_NAME "     BusContext = %p\n", BusContext));
   7.731 +  KdPrint((__DRIVER_NAME "     DeviceHandle = %p\n", DeviceHandle));
   7.732 +  KdPrint((__DRIVER_NAME "     DeviceInformationBuffer = %p\n", DeviceInformationBuffer));
   7.733 +  KdPrint((__DRIVER_NAME "     DeviceInformationBufferLength = %d\n", DeviceInformationBufferLength));
   7.734 +  KdPrint((__DRIVER_NAME "     ->InformationLevel = %d\n", udi->InformationLevel));
   7.735 +  if (DeviceInformationBufferLength < FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[1]))
   7.736 +  {
   7.737 +    KdPrint((__DRIVER_NAME "     STATUS_BUFFER_TOO_SMALL\n"));
   7.738 +    FUNCTION_EXIT();
   7.739 +    return STATUS_BUFFER_TOO_SMALL;
   7.740 +  }
   7.741 +  if (udi->InformationLevel != 0)
   7.742 +  {
   7.743 +    KdPrint((__DRIVER_NAME "     STATUS_NOT_SUPPORTED\n"));
   7.744 +    FUNCTION_EXIT();
   7.745 +    return STATUS_NOT_SUPPORTED;
   7.746 +  }
   7.747 +  udi->ActualLength = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[1]);
   7.748 +  udi->PortNumber = 0;
   7.749 +  memcpy(&udi->DeviceDescriptor, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
   7.750 +  udi->CurrentConfigurationValue = usb_device->active_config->config_descriptor.bConfigurationValue;
   7.751 +  udi->DeviceAddress = usb_device->address;
   7.752 +  udi->HubAddress = usb_device->address; // ?
   7.753 +  udi->DeviceSpeed = UsbHighSpeed; // get from structure...
   7.754 +  udi->DeviceType = Usb20Device; // get from structure...
   7.755 +  udi->NumberOfOpenPipes = 1;
   7.756 +  udi->PipeList[0].EndpointDescriptor.bLength = sizeof(USB_ENDPOINT_DESCRIPTOR);
   7.757 +  udi->PipeList[0].EndpointDescriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
   7.758 +  udi->PipeList[0].EndpointDescriptor.bEndpointAddress = 0x81;
   7.759 +  udi->PipeList[0].EndpointDescriptor.bmAttributes = 0x3;
   7.760 +  udi->PipeList[0].EndpointDescriptor.wMaxPacketSize = 2;
   7.761 +  udi->PipeList[0].EndpointDescriptor.bInterval = 12;
   7.762 +  udi->PipeList[0].ScheduleOffset = 0; // not necessarily right
   7.763 +  *LengthOfDataReturned = udi->ActualLength;
   7.764 +  FUNCTION_EXIT();
   7.765 +  return STATUS_SUCCESS;
   7.766 +}
   7.767 +
   7.768 +static NTSTATUS
   7.769 +XenPciPdo_UBIH_GetControllerInformation (
   7.770 +  PVOID BusContext,
   7.771 +  PVOID ControllerInformationBuffer,
   7.772 +  ULONG ControllerInformationBufferLength,
   7.773 +  PULONG LengthOfDataReturned)
   7.774 +{
   7.775 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.776 +  PUSB_CONTROLLER_INFORMATION_0 uci = ControllerInformationBuffer;
   7.777 +  WDFDEVICE device = BusContext;
   7.778 +  //xenusb_device_t *usb_device = DeviceHandle;
   7.779 +
   7.780 +  FUNCTION_ENTER();
   7.781 +
   7.782 +  KdPrint((__DRIVER_NAME "     BusContext = %p\n", BusContext));
   7.783 +  KdPrint((__DRIVER_NAME "     ControllerInformationBuffer = %p\n", ControllerInformationBuffer));
   7.784 +  KdPrint((__DRIVER_NAME "     ControllerInformationBufferLength = %d\n", ControllerInformationBufferLength));
   7.785 +  KdPrint((__DRIVER_NAME "     ->InformationLevel = %d\n", uci->InformationLevel));
   7.786 +  if (ControllerInformationBufferLength < sizeof(USB_CONTROLLER_INFORMATION_0))
   7.787 +  {
   7.788 +    KdPrint((__DRIVER_NAME "     STATUS_BUFFER_TOO_SMALL\n"));
   7.789 +    FUNCTION_EXIT();
   7.790 +    return STATUS_BUFFER_TOO_SMALL;
   7.791 +  }
   7.792 +  if (uci->InformationLevel != 0)
   7.793 +  {
   7.794 +    KdPrint((__DRIVER_NAME "     STATUS_NOT_SUPPORTED\n"));
   7.795 +    FUNCTION_EXIT();
   7.796 +    return STATUS_NOT_SUPPORTED;
   7.797 +  }
   7.798 +  
   7.799 +  uci->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
   7.800 +  *LengthOfDataReturned = uci->ActualLength;
   7.801 +  
   7.802 +  FUNCTION_EXIT();
   7.803 +  return status;
   7.804 +}
   7.805 +
   7.806 +static NTSTATUS
   7.807 +XenPciPdo_UBIH_ControllerSelectiveSuspend (
   7.808 +  PVOID BusContext,
   7.809 +  BOOLEAN Enable)
   7.810 +{
   7.811 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.812 +  FUNCTION_ENTER();
   7.813 +
   7.814 +  FUNCTION_EXIT();
   7.815 +  return status;
   7.816 +}
   7.817 +
   7.818 +static NTSTATUS
   7.819 +XenPciPdo_UBIH_GetExtendedHubInformation (
   7.820 +  PVOID BusContext,
   7.821 +  PDEVICE_OBJECT HubPhysicalDeviceObject,
   7.822 +  PVOID HubInformationBuffer,
   7.823 +  ULONG HubInformationBufferLength,
   7.824 +  PULONG LengthOfDataReturned)
   7.825 +{
   7.826 +  PUSB_EXTHUB_INFORMATION_0 hib = HubInformationBuffer;
   7.827 +  int i;
   7.828 +
   7.829 +  FUNCTION_ENTER();
   7.830 +
   7.831 +  KdPrint((__DRIVER_NAME "     BusContext = %p\n", BusContext));
   7.832 +  KdPrint((__DRIVER_NAME "     HubPhysicalDeviceObject = %p\n", HubPhysicalDeviceObject));
   7.833 +  KdPrint((__DRIVER_NAME "     HubInformationBuffer = %p\n", HubInformationBuffer));
   7.834 +  KdPrint((__DRIVER_NAME "     HubInformationBufferLength = %d\n", HubInformationBufferLength));
   7.835 +  KdPrint((__DRIVER_NAME "     ->InformationLevel = %d\n", hib->InformationLevel));
   7.836 +  if (HubInformationBufferLength < FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]))
   7.837 +  {
   7.838 +    KdPrint((__DRIVER_NAME "     STATUS_BUFFER_TOO_SMALL\n"));
   7.839 +    FUNCTION_EXIT();
   7.840 +    return STATUS_BUFFER_TOO_SMALL;
   7.841 +  }
   7.842 +  if (hib->InformationLevel != 0)
   7.843 +  {
   7.844 +    KdPrint((__DRIVER_NAME "     STATUS_NOT_SUPPORTED\n"));
   7.845 +    FUNCTION_EXIT();
   7.846 +    return STATUS_NOT_SUPPORTED;
   7.847 +  }
   7.848 +  //hib->InformationLevel = 0;
   7.849 +  hib->NumberOfPorts = 8;
   7.850 +  for (i = 0; i < hib->NumberOfPorts; i++)
   7.851 +  {
   7.852 +    hib->Port[i].PhysicalPortNumber = i + 1;
   7.853 +    hib->Port[i].PortLabelNumber = i + 1;
   7.854 +    hib->Port[i].VidOverride = 0;
   7.855 +    hib->Port[i].PidOverride = 0;
   7.856 +    hib->Port[i].PortAttributes = USB_PORTATTR_SHARED_USB2; // | USB_PORTATTR_NO_OVERCURRENT_UI;
   7.857 +  }
   7.858 +  *LengthOfDataReturned = FIELD_OFFSET(USB_EXTHUB_INFORMATION_0, Port[8]);
   7.859 +  FUNCTION_EXIT();
   7.860 +  return STATUS_SUCCESS;
   7.861 +}
   7.862 +
   7.863 +static NTSTATUS
   7.864 +XenPciPdo_UBIH_GetRootHubSymbolicName(
   7.865 +  PVOID BusContext,
   7.866 +  PVOID HubInformationBuffer,
   7.867 +  ULONG HubInformationBufferLength,
   7.868 +  PULONG HubNameActualLength)
   7.869 +{
   7.870 +  NTSTATUS status = STATUS_SUCCESS;
   7.871 +  WDFDEVICE device = BusContext;
   7.872 +  FUNCTION_ENTER();
   7.873 +
   7.874 +  KdPrint((__DRIVER_NAME "     device = %p\n", device));
   7.875 +  KdPrint((__DRIVER_NAME "     HubInformationBuffer = %p\n", HubInformationBuffer));
   7.876 +  KdPrint((__DRIVER_NAME "     HubInformationBufferLength = %d\n", HubInformationBufferLength));
   7.877 +  RtlStringCbCopyW(HubInformationBuffer, HubInformationBufferLength, L"ROOT_HUB");
   7.878 +  *HubNameActualLength = 16;
   7.879 +
   7.880 +  FUNCTION_EXIT();
   7.881 +  return status;
   7.882 +}
   7.883 +
   7.884 +static NTSTATUS
   7.885 +XenPciPdo_UBIH_GetDeviceBusContext(
   7.886 +  PVOID BusContext,
   7.887 +  PVOID DeviceHandle)
   7.888 +{
   7.889 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.890 +  FUNCTION_ENTER();
   7.891 +
   7.892 +  FUNCTION_EXIT();
   7.893 +  return status;
   7.894 +}
   7.895 +
   7.896 +static NTSTATUS
   7.897 +XenPciPdo_UBIH_Initialize20Hub (
   7.898 +  PVOID BusContext,
   7.899 +  PUSB_DEVICE_HANDLE HubDeviceHandle,
   7.900 +  ULONG TtCount)
   7.901 +{
   7.902 +  NTSTATUS status = STATUS_SUCCESS;
   7.903 +  FUNCTION_ENTER();
   7.904 +  KdPrint((__DRIVER_NAME "     BusContext = %p\n", BusContext));
   7.905 +  KdPrint((__DRIVER_NAME "     HubDeviceHandle = %p\n", HubDeviceHandle));
   7.906 +  KdPrint((__DRIVER_NAME "     TtCount = %d\n", TtCount));
   7.907 +  FUNCTION_EXIT();
   7.908 +  return status;
   7.909 +}
   7.910 +
   7.911 +static NTSTATUS
   7.912 +XenPciPdo_UBIH_RootHubInitNotification(
   7.913 +  PVOID BusContext,
   7.914 +  PVOID CallbackContext,
   7.915 +  PRH_INIT_CALLBACK CallbackFunction)
   7.916 +{
   7.917 +  NTSTATUS status = STATUS_SUCCESS;
   7.918 +  WDFDEVICE device = BusContext;
   7.919 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
   7.920 +  
   7.921 +  FUNCTION_ENTER();
   7.922 +  
   7.923 +  xupdd->BusCallbackFunction = CallbackFunction;
   7.924 +  xupdd->BusCallbackContext = CallbackContext;
   7.925 +
   7.926 +  xupdd->BusCallbackFunction(xupdd->BusCallbackContext);
   7.927 +  
   7.928 +  FUNCTION_EXIT();
   7.929 +  return status;
   7.930 +}
   7.931 +
   7.932 +static NTSTATUS
   7.933 +XenPciPdo_UBIH_FlushTransfers(
   7.934 +  PVOID BusContext,
   7.935 +  PUSB_DEVICE_HANDLE DeviceHandle)
   7.936 +{
   7.937 +  NTSTATUS status = STATUS_SUCCESS;
   7.938 +  FUNCTION_ENTER();
   7.939 +
   7.940 +  FUNCTION_EXIT();
   7.941 +  return status;
   7.942 +}
   7.943 +
   7.944 +static VOID
   7.945 +XenPciPdo_UBIH_SetDeviceHandleData(
   7.946 +  PVOID BusContext,
   7.947 +  PUSB_DEVICE_HANDLE DeviceHandle,
   7.948 +  PDEVICE_OBJECT UsbDevicePdo)
   7.949 +{
   7.950 +  FUNCTION_ENTER();
   7.951 +  FUNCTION_EXIT();
   7.952 +}
   7.953 +
   7.954 +static NTSTATUS
   7.955 +XenPciPdo_UBIU_GetUSBDIVersion(
   7.956 +  PVOID BusContext,
   7.957 +  PUSBD_VERSION_INFORMATION VersionInformation,
   7.958 +  PULONG HcdCapabilities
   7.959 +  )
   7.960 +{
   7.961 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.962 +  FUNCTION_ENTER();
   7.963 +
   7.964 +  FUNCTION_EXIT();
   7.965 +  return status;
   7.966 +}
   7.967 +
   7.968 +static NTSTATUS
   7.969 +XenPciPdo_UBIU_QueryBusTime(
   7.970 +  PVOID BusContext,
   7.971 +  PULONG CurrentFrame
   7.972 +  )
   7.973 +{
   7.974 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.975 +  FUNCTION_ENTER();
   7.976 +
   7.977 +  FUNCTION_EXIT();
   7.978 +  return status;
   7.979 +}
   7.980 +
   7.981 +static NTSTATUS
   7.982 +XenPciPdo_UBIU_SubmitIsoOutUrb(
   7.983 +  PVOID BusContext,
   7.984 +  PURB Urb
   7.985 +  )
   7.986 +{
   7.987 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
   7.988 +  FUNCTION_ENTER();
   7.989 +
   7.990 +  FUNCTION_EXIT();
   7.991 +  return status;
   7.992 +}
   7.993 +
   7.994 +static NTSTATUS
   7.995 +XenPciPdo_UBIU_QueryBusInformation(
   7.996 +  PVOID BusContext,
   7.997 +  ULONG Level,
   7.998 +  PVOID BusInformationBuffer,
   7.999 +  PULONG BusInformationBufferLength,
  7.1000 +  PULONG BusInformationActualLength)
  7.1001 +{
  7.1002 +  NTSTATUS status = STATUS_UNSUCCESSFUL;
  7.1003 +  FUNCTION_ENTER();
  7.1004 +
  7.1005 +  FUNCTION_EXIT();
  7.1006 +  return status;
  7.1007 +}
  7.1008 +
  7.1009 +static BOOLEAN
  7.1010 +XenPciPdo_UBIU_IsDeviceHighSpeed(PVOID BusContext)
  7.1011 +{
  7.1012 +  FUNCTION_ENTER();
  7.1013 +
  7.1014 +  FUNCTION_EXIT();
  7.1015 +  return TRUE; //TODO: get port value
  7.1016 +}
  7.1017 +
  7.1018 +static NTSTATUS
  7.1019 +XenPciPdo_UBIU_EnumLogEntry(
  7.1020 +  PVOID BusContext,
  7.1021 +  ULONG DriverTag,
  7.1022 +  ULONG EnumTag,
  7.1023 +  ULONG P1,
  7.1024 +  ULONG P2
  7.1025 +)
  7.1026 +{
  7.1027 +  NTSTATUS status = STATUS_SUCCESS;
  7.1028 +  FUNCTION_ENTER();
  7.1029 +  
  7.1030 +  KdPrint((__DRIVER_NAME "     DriverTag = %08x\n", DriverTag));
  7.1031 +  KdPrint((__DRIVER_NAME "     EnumTag = %08x\n", EnumTag));
  7.1032 +  KdPrint((__DRIVER_NAME "     P1 = %08x\n", P1));
  7.1033 +  KdPrint((__DRIVER_NAME "     P2 = %08x\n", P2));
  7.1034 +
  7.1035 +  FUNCTION_EXIT();
  7.1036 +  return status;
  7.1037 +}
  7.1038 +
  7.1039 +VOID
  7.1040 +XenUsb_EnumeratePorts(WDFDEVICE device)
  7.1041 +{
  7.1042 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
  7.1043 +  PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
  7.1044 +  CHAR path[128];
  7.1045 +  PCHAR err;
  7.1046 +  PCHAR value;
  7.1047 +  int i;
  7.1048 +  
  7.1049 +  for (i = 0; i < xudd->num_ports; i++)
  7.1050 +  {
  7.1051 +    ULONG port_value;
  7.1052 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/port-%d", xudd->vectors.backend_path, i + 1);
  7.1053 +    err = xudd->vectors.XenBus_Read(xudd->vectors.context, XBT_NIL, path, &value);
  7.1054 +    if (err)
  7.1055 +    {
  7.1056 +      XenPci_FreeMem(err);
  7.1057 +      KdPrint((__DRIVER_NAME "     Failed to read port-%d\n", i + 1));
  7.1058 +      continue;
  7.1059 +    }
  7.1060 +    // 0=disconnected, 1=low_speed, 2=full_speed, 3= high_speed
  7.1061 +    port_value = (ULONG)parse_numeric_string(value);
  7.1062 +    XenPci_FreeMem(value);
  7.1063 +    KdPrint((__DRIVER_NAME "     port-%d : %d -> %d\n", i, xudd->ports[i].port_type, port_value));
  7.1064 +    if (port_value != xudd->ports[i].port_type)
  7.1065 +    {
  7.1066 +      xudd->ports[i].port_type = port_value;
  7.1067 +      // need to do more than this - probably flush everything and ensure no more activity to the new port until it is set up...
  7.1068 +      switch (port_value)
  7.1069 +      {
  7.1070 +      case USB_PORT_TYPE_NOT_CONNECTED:
  7.1071 +        xudd->ports[i].port_status = (1 << PORT_ENABLE);
  7.1072 +        break;
  7.1073 +      case USB_PORT_TYPE_LOW_SPEED:
  7.1074 +        xudd->ports[i].port_status = (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
  7.1075 +        break;
  7.1076 +      case USB_PORT_TYPE_FULL_SPEED:
  7.1077 +        xudd->ports[i].port_status = (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
  7.1078 +        break;
  7.1079 +      case USB_PORT_TYPE_HIGH_SPEED:
  7.1080 +        xudd->ports[i].port_status = (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION) | (1 << PORT_ENABLE);
  7.1081 +        break;
  7.1082 +      }      
  7.1083 +      xudd->ports[i].port_change |= (1 << PORT_CONNECTION);
  7.1084 +    }
  7.1085 +  }  
  7.1086 +}
  7.1087 +
  7.1088 +static VOID
  7.1089 +XenUsbHub_HubInterruptTimer(WDFTIMER timer)
  7.1090 +{
  7.1091 +  NTSTATUS status;
  7.1092 +  xenusb_endpoint_t *endpoint = *GetEndpoint(timer);
  7.1093 +  WDFDEVICE pdo_device = endpoint->interface->config->device->pdo_device;
  7.1094 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(pdo_device);
  7.1095 +  PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
  7.1096 +  WDF_REQUEST_PARAMETERS wrp;
  7.1097 +  WDFREQUEST request;
  7.1098 +  PURB urb;
  7.1099 +  int i;
  7.1100 +  
  7.1101 +  //FUNCTION_ENTER();
  7.1102 +  WdfSpinLockAcquire(endpoint->interrupt_lock);
  7.1103 +  status = WdfIoQueueRetrieveNextRequest(endpoint->interrupt_queue, &request);
  7.1104 +  if (status == STATUS_NO_MORE_ENTRIES)
  7.1105 +  {
  7.1106 +    WdfTimerStop(timer, FALSE);
  7.1107 +    WdfSpinLockRelease(endpoint->interrupt_lock);
  7.1108 +    KdPrint((__DRIVER_NAME "      No More Entries\n", status));
  7.1109 +    //FUNCTION_EXIT();
  7.1110 +    return;
  7.1111 +  }
  7.1112 +  if (!NT_SUCCESS(status))
  7.1113 +  {
  7.1114 +    WdfTimerStop(timer, FALSE);
  7.1115 +    WdfSpinLockRelease(endpoint->interrupt_lock);
  7.1116 +    KdPrint((__DRIVER_NAME "      Failed to get request from queue %08x\n", status));
  7.1117 +    //FUNCTION_EXIT();
  7.1118 +    return;
  7.1119 +  }
  7.1120 +  
  7.1121 +  WDF_REQUEST_PARAMETERS_INIT(&wrp);
  7.1122 +  WdfRequestGetParameters(request, &wrp);
  7.1123 +
  7.1124 +  urb = (PURB)wrp.Parameters.Others.Arg1;
  7.1125 +  ASSERT(urb);
  7.1126 +  ASSERT(urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER);
  7.1127 +  RtlZeroMemory(urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
  7.1128 +  if (urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
  7.1129 +  {
  7.1130 +    //urb->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
  7.1131 +    // check for hub change too
  7.1132 +    //((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] |= 1;
  7.1133 +    for (i = 0; i < xudd->num_ports; i++)
  7.1134 +    {
  7.1135 +      if (xudd->ports[i].port_change)
  7.1136 +      {
  7.1137 +        KdPrint((__DRIVER_NAME "      Port change on port %d - status = %04x, change = %04x\n",
  7.1138 +          xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change));
  7.1139 +        ((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[xudd->ports[i].port_number >> 3] |= 1 << (xudd->ports[i].port_number & 7);
  7.1140 +      }
  7.1141 +    }
  7.1142 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
  7.1143 +    WdfSpinLockRelease(endpoint->interrupt_lock);
  7.1144 +    WdfRequestComplete(request, STATUS_SUCCESS);
  7.1145 +  }
  7.1146 +  else
  7.1147 +  {
  7.1148 +    KdPrint((__DRIVER_NAME "      Direction mismatch\n"));
  7.1149 +    urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
  7.1150 +    WdfSpinLockRelease(endpoint->interrupt_lock);
  7.1151 +    WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
  7.1152 +  }
  7.1153 +  //FUNCTION_EXIT();
  7.1154 +  return;
  7.1155 +}
  7.1156 +
  7.1157 +NTSTATUS
  7.1158 +XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list,
  7.1159 +  PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
  7.1160 +  PWDFDEVICE_INIT child_init)
  7.1161 +{
  7.1162 +  NTSTATUS status = STATUS_SUCCESS;
  7.1163 +  WDFDEVICE bus_device = WdfChildListGetDevice(child_list);
  7.1164 +  WDF_OBJECT_ATTRIBUTES child_attributes;
  7.1165 +  WDFDEVICE child_device;
  7.1166 +  PXENUSB_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENUSB_PDO_IDENTIFICATION_DESCRIPTION)identification_header;
  7.1167 +  WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities;
  7.1168 +  DECLARE_UNICODE_STRING_SIZE(buffer, 512);
  7.1169 +  DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus");
  7.1170 +  PXENUSB_PDO_DEVICE_DATA xupdd;
  7.1171 +  PXENUSB_DEVICE_DATA xudd = GetXudd(bus_device);
  7.1172 +  WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks;
  7.1173 +  WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities;
  7.1174 +  WDF_IO_QUEUE_CONFIG queue_config;
  7.1175 +  WDFIOTARGET bus_target;
  7.1176 +  PDEVICE_OBJECT fdo;
  7.1177 +  PIRP irp;
  7.1178 +  PIO_STACK_LOCATION stack;
  7.1179 +  KEVENT irp_complete_event;
  7.1180 +  usbif_request_t *req;
  7.1181 +  usbif_response_t *rsp;
  7.1182 +  URB urb;
  7.1183 +  PVOID buf;
  7.1184 +  PUSB_DEVICE_DESCRIPTOR device_descriptor;
  7.1185 +  PUSB_CONFIGURATION_DESCRIPTOR config_descriptor;  
  7.1186 +  PUSB_INTERFACE_DESCRIPTOR interface_descriptor;
  7.1187 +  PUCHAR ptr;
  7.1188 +  int num_configs;
  7.1189 +  int i, j, k;
  7.1190 +  xenusb_device_t *usb_device;
  7.1191 +  WDF_QUERY_INTERFACE_CONFIG interface_config;
  7.1192 +  USB_BUS_INTERFACE_HUB_V5 ubih;
  7.1193 +  USB_BUS_INTERFACE_USBDI_V2 ubiu;
  7.1194 +  WDF_TIMER_CONFIG timer_config;
  7.1195 +  WDF_OBJECT_ATTRIBUTES timer_attributes;
  7.1196 +
  7.1197 +  UNREFERENCED_PARAMETER(xudd);
  7.1198 +  
  7.1199 +  FUNCTION_ENTER();
  7.1200 +
  7.1201 +  //KdPrint((__DRIVER_NAME "     device = %d, port = %d, vendor_id = %04x, product_id = %04x\n",
  7.1202 +
  7.1203 +  WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN);
  7.1204 +  
  7.1205 +  child_pnp_power_callbacks.EvtDeviceD0Entry = XenUsbHub_EvtDeviceD0Entry;
  7.1206 +  child_pnp_power_callbacks.EvtDeviceD0Exit = XenUsbHub_EvtDeviceD0Exit;
  7.1207 +  child_pnp_power_callbacks.EvtDevicePrepareHardware = XenUsbHub_EvtDevicePrepareHardware;
  7.1208 +  child_pnp_power_callbacks.EvtDeviceReleaseHardware = XenUsbHub_EvtDeviceReleaseHardware;
  7.1209 +  child_pnp_power_callbacks.EvtDeviceUsageNotification = XenUsbHub_EvtDeviceUsageNotification;
  7.1210 +  WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks);
  7.1211 +
  7.1212 +  RtlUnicodeStringPrintf(&buffer, L"USB\\ROOT_HUB");
  7.1213 +  status = WdfPdoInitAssignDeviceID(child_init, &buffer);
  7.1214 +  status = WdfPdoInitAddHardwareID(child_init, &buffer);
  7.1215 +
  7.1216 +  RtlUnicodeStringPrintf(&buffer, L"VUSB_%d", identification->device_number);
  7.1217 +  status = WdfPdoInitAssignInstanceID(child_init, &buffer);
  7.1218 +  if (!NT_SUCCESS(status))
  7.1219 +  {
  7.1220 +    return status;
  7.1221 +  }
  7.1222 +  
  7.1223 +  RtlUnicodeStringPrintf(&buffer, L"PVUSB device #%d", identification->device_number, identification);
  7.1224 +  status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409);
  7.1225 +  if (!NT_SUCCESS(status))
  7.1226 +  {
  7.1227 +    return status;
  7.1228 +  }
  7.1229 +  WdfPdoInitSetDefaultLocale(child_init, 0x0409);
  7.1230 +
  7.1231 +  WdfDeviceInitSetPowerNotPageable(child_init);
  7.1232 +
  7.1233 +  WdfDeviceInitSetIoType(child_init, WdfDeviceIoDirect);
  7.1234 +
  7.1235 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENUSB_PDO_DEVICE_DATA);
  7.1236 +  status = WdfDeviceCreate(&child_init, &child_attributes, &child_device);
  7.1237 +  if (!NT_SUCCESS(status))
  7.1238 +  {
  7.1239 +    return status;
  7.1240 +  }
  7.1241 +
  7.1242 +  xupdd = GetXupdd(child_device);
  7.1243 +
  7.1244 +  xudd->root_hub_device = child_device;
  7.1245 +  
  7.1246 +  xupdd->wdf_device = child_device;
  7.1247 +  xupdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list);
  7.1248 +  
  7.1249 +  xupdd->usb_device = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_device_t), XENUSB_POOL_TAG);
  7.1250 +  // get address from freelist...
  7.1251 +  xupdd->usb_device->pdo_device = child_device;
  7.1252 +  xupdd->usb_device->address = 1;
  7.1253 +  xupdd->usb_device->device_descriptor.bLength = sizeof(USB_DEVICE_DESCRIPTOR);
  7.1254 +  xupdd->usb_device->device_descriptor.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE;
  7.1255 +  xupdd->usb_device->device_descriptor.bcdUSB = 0x0200;
  7.1256 +  xupdd->usb_device->device_descriptor.bDeviceClass = 9;
  7.1257 +  xupdd->usb_device->device_descriptor.bDeviceSubClass = 0;
  7.1258 +  xupdd->usb_device->device_descriptor.bDeviceProtocol = 1;
  7.1259 +  xupdd->usb_device->device_descriptor.bMaxPacketSize0 = 64;
  7.1260 +  xupdd->usb_device->device_descriptor.idVendor = 0x0000;
  7.1261 +  xupdd->usb_device->device_descriptor.idProduct = 0x0000;
  7.1262 +  xupdd->usb_device->device_descriptor.bcdDevice = 0x0206;
  7.1263 +  xupdd->usb_device->device_descriptor.iManufacturer = 3;
  7.1264 +  xupdd->usb_device->device_descriptor.iProduct = 2;
  7.1265 +  xupdd->usb_device->device_descriptor.iSerialNumber = 1;
  7.1266 +  xupdd->usb_device->device_descriptor.bNumConfigurations = 1;
  7.1267 +  xupdd->usb_device->configs = ExAllocatePoolWithTag(NonPagedPool, sizeof(PVOID) * 1, XENUSB_POOL_TAG);
  7.1268 +  xupdd->usb_device->configs[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
  7.1269 +  xupdd->usb_device->active_config = xupdd->usb_device->configs[0];
  7.1270 +  xupdd->usb_device->configs[0]->device = xupdd->usb_device;
  7.1271 +  xupdd->usb_device->configs[0]->config_descriptor.bLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
  7.1272 +  xupdd->usb_device->configs[0]->config_descriptor.bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE;
  7.1273 +  xupdd->usb_device->configs[0]->config_descriptor.wTotalLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
  7.1274 +  xupdd->usb_device->configs[0]->config_descriptor.bNumInterfaces = 1;
  7.1275 +  xupdd->usb_device->configs[0]->config_descriptor.bConfigurationValue = 1;
  7.1276 +  xupdd->usb_device->configs[0]->config_descriptor.iConfiguration = 0;
  7.1277 +  xupdd->usb_device->configs[0]->config_descriptor.bmAttributes = 0xe0;
  7.1278 +  xupdd->usb_device->configs[0]->config_descriptor.MaxPower = 0;
  7.1279 +  xupdd->usb_device->configs[0]->interfaces[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_interface_t) + sizeof(PVOID) * 1, XENUSB_POOL_TAG);
  7.1280 +  xupdd->usb_device->configs[0]->interfaces[0]->config = xupdd->usb_device->configs[0];
  7.1281 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bLength = 9;
  7.1282 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE;
  7.1283 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceNumber = 0;
  7.1284 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bAlternateSetting = 0;
  7.1285 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bNumEndpoints = 1;
  7.1286 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceClass = 9;
  7.1287 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceSubClass = 0;
  7.1288 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.bInterfaceProtocol = 0;
  7.1289 +  xupdd->usb_device->configs[0]->interfaces[0]->interface_descriptor.iInterface = 0;
  7.1290 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_endpoint_t), XENUSB_POOL_TAG);
  7.1291 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interface = xupdd->usb_device->configs[0]->interfaces[0];
  7.1292 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->pipe_value = 0;
  7.1293 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bLength = 7;
  7.1294 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
  7.1295 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bEndpointAddress = 0x81; // EP 1 IN
  7.1296 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT;
  7.1297 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.wMaxPacketSize = 2;
  7.1298 +  xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bInterval = 12;
  7.1299 +  WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_lock);
  7.1300 +  WDF_TIMER_CONFIG_INIT(&timer_config, XenUsbHub_HubInterruptTimer);  
  7.1301 +  WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timer_attributes, pxenusb_endpoint_t);
  7.1302 +  timer_attributes.ParentObject = child_device;
  7.1303 +  status = WdfTimerCreate(&timer_config, &timer_attributes, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer);
  7.1304 +  if (!NT_SUCCESS(status)) {
  7.1305 +      KdPrint((__DRIVER_NAME "     Error creating timer 0x%x\n", status));
  7.1306 +      return status;
  7.1307 +  }
  7.1308 +  *GetEndpoint(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer) = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
  7.1309 +
  7.1310 +  WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
  7.1311 +  queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
  7.1312 +  queue_config.PowerManaged = TRUE; /* power managed queue for SUBMIT_URB */
  7.1313 +  status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->urb_queue);
  7.1314 +  if (!NT_SUCCESS(status)) {
  7.1315 +      KdPrint((__DRIVER_NAME "     Error creating urb_queue 0x%x\n", status));
  7.1316 +      return status;
  7.1317 +  }
  7.1318 +  WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
  7.1319 +  queue_config.PowerManaged = TRUE;
  7.1320 +  status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES,
  7.1321 +    &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_queue);
  7.1322 +  if (!NT_SUCCESS(status)) {
  7.1323 +      KdPrint((__DRIVER_NAME "     Error creating timer io_queue 0x%x\n", status));
  7.1324 +      return status;
  7.1325 +  }
  7.1326 +
  7.1327 +  WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
  7.1328 +  queue_config.EvtIoInternalDeviceControl = XenUsbHub_EvtIoInternalDeviceControl;
  7.1329 +  queue_config.EvtIoDefault = XenUsbHub_EvtIoDefault;
  7.1330 +  /* can't be power managed or deadlocks occur */
  7.1331 +  queue_config.PowerManaged = FALSE;
  7.1332 +  status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xupdd->io_queue);
  7.1333 +  if (!NT_SUCCESS(status)) {
  7.1334 +      KdPrint((__DRIVER_NAME "     Error creating io_queue 0x%x\n", status));
  7.1335 +      return status;
  7.1336 +  }
  7.1337 +
  7.1338 +  WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE);
  7.1339 +  WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE);
  7.1340 +  WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE);
  7.1341 +
  7.1342 +  WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities);
  7.1343 +  child_pnp_capabilities.LockSupported = WdfFalse;
  7.1344 +  child_pnp_capabilities.EjectSupported  = WdfTrue;
  7.1345 +  child_pnp_capabilities.Removable  = WdfTrue;
  7.1346 +  child_pnp_capabilities.DockDevice  = WdfFalse;
  7.1347 +  child_pnp_capabilities.UniqueID  = WdfTrue;
  7.1348 +  child_pnp_capabilities.SilentInstall  = WdfTrue;
  7.1349 +  child_pnp_capabilities.SurpriseRemovalOK  = WdfTrue;
  7.1350 +  child_pnp_capabilities.HardwareDisabled = WdfFalse;
  7.1351 +  WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities);
  7.1352 +
  7.1353 +  WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities);
  7.1354 +  child_power_capabilities.DeviceD1 = WdfTrue;
  7.1355 +  child_power_capabilities.WakeFromD1 = WdfTrue;
  7.1356 +  child_power_capabilities.DeviceWake = PowerDeviceD1;
  7.1357 +  child_power_capabilities.DeviceState[PowerSystemWorking]   = PowerDeviceD1;
  7.1358 +  child_power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
  7.1359 +  child_power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
  7.1360 +  child_power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
  7.1361 +  child_power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
  7.1362 +  child_power_capabilities.DeviceState[PowerSystemShutdown]  = PowerDeviceD3;
  7.1363 +  WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities);  
  7.1364 +
  7.1365 +  ubih.BusContext = child_device;
  7.1366 +  ubih.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
  7.1367 +  ubih.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
  7.1368 +  ubih.CreateUsbDevice = XenPciPdo_UBIH_CreateUsbDevice;
  7.1369 +  ubih.InitializeUsbDevice = XenPciPdo_UBIH_InitializeUsbDevice;
  7.1370 +  ubih.GetUsbDescriptors = XenPciPdo_UBIH_GetUsbDescriptors;
  7.1371 +  ubih.RemoveUsbDevice = XenPciPdo_UBIH_RemoveUsbDevice;
  7.1372 +  ubih.RestoreUsbDevice = XenPciPdo_UBIH_RestoreUsbDevice;
  7.1373 +  ubih.GetPortHackFlags = XenPciPdo_UBIH_GetPortHackFlags;
  7.1374 +  ubih.QueryDeviceInformation = XenPciPdo_UBIH_QueryDeviceInformation;
  7.1375 +  ubih.GetControllerInformation = XenPciPdo_UBIH_GetControllerInformation;
  7.1376 +  ubih.ControllerSelectiveSuspend = XenPciPdo_UBIH_ControllerSelectiveSuspend;
  7.1377 +  ubih.GetExtendedHubInformation = XenPciPdo_UBIH_GetExtendedHubInformation;
  7.1378 +  ubih.GetRootHubSymbolicName = XenPciPdo_UBIH_GetRootHubSymbolicName;
  7.1379 +  ubih.GetDeviceBusContext = XenPciPdo_UBIH_GetDeviceBusContext;
  7.1380 +  ubih.Initialize20Hub = XenPciPdo_UBIH_Initialize20Hub;
  7.1381 +  ubih.RootHubInitNotification = XenPciPdo_UBIH_RootHubInitNotification;
  7.1382 +  ubih.FlushTransfers = XenPciPdo_UBIH_FlushTransfers;
  7.1383 +  ubih.SetDeviceHandleData = XenPciPdo_UBIH_SetDeviceHandleData;
  7.1384 +  ubih.Size = sizeof(USB_BUS_INTERFACE_HUB_V5);
  7.1385 +  ubih.Version = USB_BUSIF_HUB_VERSION_5;
  7.1386 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubih, &USB_BUS_INTERFACE_HUB_GUID, NULL);
  7.1387 +  status = WdfDeviceAddQueryInterface(child_device, &interface_config);
  7.1388 +  if (!NT_SUCCESS(status))
  7.1389 +    return status;
  7.1390 +
  7.1391 +  ubiu.BusContext = child_device;
  7.1392 +  ubiu.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
  7.1393 +  ubiu.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
  7.1394 +  ubiu.GetUSBDIVersion = XenPciPdo_UBIU_GetUSBDIVersion;
  7.1395 +  ubiu.QueryBusTime = XenPciPdo_UBIU_QueryBusTime;
  7.1396 +  ubiu.SubmitIsoOutUrb = XenPciPdo_UBIU_SubmitIsoOutUrb;
  7.1397 +  ubiu.QueryBusInformation = XenPciPdo_UBIU_QueryBusInformation;
  7.1398 +  ubiu.IsDeviceHighSpeed = XenPciPdo_UBIU_IsDeviceHighSpeed;
  7.1399 +  ubiu.EnumLogEntry  = XenPciPdo_UBIU_EnumLogEntry;
  7.1400 +  ubiu.Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
  7.1401 +  ubiu.Version = USB_BUSIF_HUB_VERSION_2;
  7.1402 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubiu, &USB_BUS_INTERFACE_USBDI_GUID, NULL);
  7.1403 +  status = WdfDeviceAddQueryInterface(child_device, &interface_config);
  7.1404 +  if (!NT_SUCCESS(status))
  7.1405 +    return status;
  7.1406 +    
  7.1407 +  FUNCTION_EXIT();
  7.1408 +  
  7.1409 +  return status;
  7.1410 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xenusb/xenusb_huburb.c	Fri Sep 11 22:44:11 2009 +1000
     8.3 @@ -0,0 +1,463 @@
     8.4 +/*
     8.5 +PV Drivers for Windows Xen HVM Domains
     8.6 +Copyright (C) 2007 James Harper
     8.7 +
     8.8 +This program is free software; you can redistribute it and/or
     8.9 +modify it under the terms of the GNU General Public License
    8.10 +as published by the Free Software Foundation; either version 2
    8.11 +of the License, or (at your option) any later version.
    8.12 +
    8.13 +This program is distributed in the hope that it will be useful,
    8.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.16 +GNU General Public License for more details.
    8.17 +
    8.18 +You should have received a copy of the GNU General Public License
    8.19 +along with this program; if not, write to the Free Software
    8.20 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    8.21 +*/
    8.22 +
    8.23 +#include "xenusb.h"
    8.24 +
    8.25 +VOID
    8.26 +XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB(
    8.27 +  WDFQUEUE queue,
    8.28 +  WDFREQUEST request,
    8.29 +  size_t output_buffer_length,
    8.30 +  size_t input_buffer_length,
    8.31 +  ULONG io_control_code)
    8.32 +{
    8.33 +  NTSTATUS status;
    8.34 +  WDFDEVICE device = WdfIoQueueGetDevice(queue);
    8.35 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(device);
    8.36 +  PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
    8.37 +  WDF_REQUEST_PARAMETERS wrp;
    8.38 +  PURB urb;
    8.39 +  PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
    8.40 +  PMDL mdl;
    8.41 +  PUSBD_INTERFACE_INFORMATION interface_information;
    8.42 +  ULONG i, j;
    8.43 +  int notify;
    8.44 +  xenusb_device_t *usb_device;
    8.45 +  PUSB_HUB_DESCRIPTOR uhd;
    8.46 +  KIRQL old_irql;
    8.47 +  xenusb_endpoint_t *endpoint;
    8.48 +
    8.49 +  UNREFERENCED_PARAMETER(input_buffer_length);
    8.50 +  UNREFERENCED_PARAMETER(output_buffer_length);
    8.51 +
    8.52 +  //FUNCTION_ENTER();
    8.53 +
    8.54 +  ASSERT(io_control_code == IOCTL_INTERNAL_USB_SUBMIT_URB);
    8.55 +
    8.56 +  status = STATUS_UNSUCCESSFUL;
    8.57 +
    8.58 +  WDF_REQUEST_PARAMETERS_INIT(&wrp);
    8.59 +  WdfRequestGetParameters(request, &wrp);
    8.60 +
    8.61 +  urb = (PURB)wrp.Parameters.Others.Arg1;
    8.62 +  ASSERT(urb);
    8.63 +#if 0
    8.64 +  KdPrint((__DRIVER_NAME "     urb = %p\n", urb));
    8.65 +  KdPrint((__DRIVER_NAME "      Length = %d\n", urb->UrbHeader.Length));
    8.66 +  KdPrint((__DRIVER_NAME "      Function = %d\n", urb->UrbHeader.Function));
    8.67 +  KdPrint((__DRIVER_NAME "      Status = %d\n", urb->UrbHeader.Status));
    8.68 +  KdPrint((__DRIVER_NAME "      UsbdDeviceHandle = %p\n", urb->UrbHeader.UsbdDeviceHandle));
    8.69 +  KdPrint((__DRIVER_NAME "      UsbdFlags = %08x\n", urb->UrbHeader.UsbdFlags));
    8.70 +#endif
    8.71 +  usb_device = urb->UrbHeader.UsbdDeviceHandle;
    8.72 +
    8.73 +  if (!usb_device)
    8.74 +    usb_device = xupdd->usb_device;
    8.75 +
    8.76 +  switch(urb->UrbHeader.Function)
    8.77 +  {
    8.78 +  case URB_FUNCTION_SELECT_CONFIGURATION:
    8.79 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SELECT_CONFIGURATION\n"));
    8.80 +    KdPrint((__DRIVER_NAME "      ConfigurationDescriptor = %p\n", urb->UrbSelectConfiguration.ConfigurationDescriptor));
    8.81 +    if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
    8.82 +    {
    8.83 +      KdPrint((__DRIVER_NAME "       bLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength));
    8.84 +      KdPrint((__DRIVER_NAME "       bDescriptorType = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType));
    8.85 +      KdPrint((__DRIVER_NAME "       wTotalLength = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength));
    8.86 +      KdPrint((__DRIVER_NAME "       bNumInterfaces = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces));
    8.87 +      KdPrint((__DRIVER_NAME "       bConfigurationValue = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue));
    8.88 +      KdPrint((__DRIVER_NAME "       iConfiguration = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration));
    8.89 +      KdPrint((__DRIVER_NAME "       bmAttributes = %04x\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes));
    8.90 +      KdPrint((__DRIVER_NAME "       MaxPower = %d\n", urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower));
    8.91 +    }
    8.92 +    KdPrint((__DRIVER_NAME "      ConfigurationHandle = %p\n", urb->UrbSelectConfiguration.ConfigurationHandle));
    8.93 +    if (urb->UrbSelectConfiguration.ConfigurationDescriptor)
    8.94 +    {
    8.95 +      urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)0xEEEEEEEE;
    8.96 +      interface_information = &urb->UrbSelectConfiguration.Interface;
    8.97 +      for (i = 0; i < urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; i++)
    8.98 +      {
    8.99 +        KdPrint((__DRIVER_NAME "     InterfaceInformation[%d]\n", i));
   8.100 +        KdPrint((__DRIVER_NAME "      Length = %d\n", interface_information->Length));
   8.101 +        KdPrint((__DRIVER_NAME "      InterfaceNumber = %d\n", interface_information->InterfaceNumber));
   8.102 +        KdPrint((__DRIVER_NAME "      AlternateSetting = %d\n", interface_information->AlternateSetting));
   8.103 +        KdPrint((__DRIVER_NAME "      Class = %02x\n", (ULONG)interface_information->Class));
   8.104 +        KdPrint((__DRIVER_NAME "      SubClass = %02x\n", (ULONG)interface_information->SubClass));
   8.105 +        KdPrint((__DRIVER_NAME "      Protocol = %02x\n", (ULONG)interface_information->Protocol));
   8.106 +        KdPrint((__DRIVER_NAME "      Reserved = %02x\n", (ULONG)interface_information->Reserved));
   8.107 +        KdPrint((__DRIVER_NAME "      InterfaceHandle = %p\n", interface_information->InterfaceHandle));
   8.108 +        KdPrint((__DRIVER_NAME "      NumberOfPipes = %d\n", interface_information->NumberOfPipes));
   8.109 +        interface_information->InterfaceHandle = (PVOID)0xBBBBBBBB; // do this on completion...
   8.110 +        interface_information->Class = 0x09;
   8.111 +        interface_information->SubClass = 0x00;
   8.112 +        interface_information->SubClass = 0x00;
   8.113 +        for (j = 0; j < interface_information->NumberOfPipes; j++)
   8.114 +        {
   8.115 +          KdPrint((__DRIVER_NAME "      Pipe[%d]\n", i));
   8.116 +          KdPrint((__DRIVER_NAME "       MaximumPacketSize = %d\n", interface_information->Pipes[j].MaximumPacketSize));
   8.117 +          KdPrint((__DRIVER_NAME "       EndpointAddress = %d\n", interface_information->Pipes[j].EndpointAddress));
   8.118 +          KdPrint((__DRIVER_NAME "       Interval = %d\n", interface_information->Pipes[j].Interval));
   8.119 +          KdPrint((__DRIVER_NAME "       PipeType = %d\n", interface_information->Pipes[j].PipeType));
   8.120 +          KdPrint((__DRIVER_NAME "       PipeHandle = %d\n", interface_information->Pipes[j].PipeHandle));
   8.121 +          KdPrint((__DRIVER_NAME "       MaximumTransferSize = %d\n", interface_information->Pipes[j].MaximumTransferSize));
   8.122 +          KdPrint((__DRIVER_NAME "       PipeFlags = %08x\n", interface_information->Pipes[j].PipeFlags));
   8.123 +          interface_information->Pipes[j].MaximumPacketSize = 2;
   8.124 +          interface_information->Pipes[j].EndpointAddress = 0x81;
   8.125 +          interface_information->Pipes[j].Interval = 12;
   8.126 +          interface_information->Pipes[j].PipeType = UsbdPipeTypeInterrupt;
   8.127 +          interface_information->Pipes[j].PipeHandle = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
   8.128 +          interface_information->Pipes[j].MaximumTransferSize = 4096; /* made up number - possibly not used */
   8.129 +          // this is input actually interface_information->Pipes[j].PipeFlags = 0;
   8.130 +        }
   8.131 +        interface_information = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)interface_information + interface_information->Length);
   8.132 +      }
   8.133 +    }
   8.134 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.135 +    WdfRequestComplete(request, STATUS_SUCCESS);
   8.136 +    break;
   8.137 +  case URB_FUNCTION_SELECT_INTERFACE:
   8.138 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SELECT_INTERFACE\n"));
   8.139 +    interface_information = &urb->UrbSelectInterface.Interface;
   8.140 +    KdPrint((__DRIVER_NAME "     InterfaceInformation\n"));
   8.141 +    KdPrint((__DRIVER_NAME "      Length = %d\n", interface_information->Length));
   8.142 +    KdPrint((__DRIVER_NAME "      InterfaceNumber = %d\n", interface_information->InterfaceNumber));
   8.143 +    KdPrint((__DRIVER_NAME "      AlternateSetting = %d\n", interface_information->AlternateSetting));
   8.144 +    KdPrint((__DRIVER_NAME "      Class = %02x\n", (ULONG)interface_information->Class));
   8.145 +    KdPrint((__DRIVER_NAME "      SubClass = %02x\n", (ULONG)interface_information->SubClass));
   8.146 +    KdPrint((__DRIVER_NAME "      Protocol = %02x\n", (ULONG)interface_information->Protocol));
   8.147 +    KdPrint((__DRIVER_NAME "      Reserved = %02x\n", (ULONG)interface_information->Reserved));
   8.148 +    KdPrint((__DRIVER_NAME "      InterfaceHandle = %p\n", interface_information->InterfaceHandle));
   8.149 +    KdPrint((__DRIVER_NAME "      NumberOfPipes = %d\n", interface_information->NumberOfPipes));
   8.150 +    for (i = 0; i < interface_information->NumberOfPipes; i++)
   8.151 +    {
   8.152 +      KdPrint((__DRIVER_NAME "      Pipe[%d]\n", i));
   8.153 +      KdPrint((__DRIVER_NAME "       MaximumPacketSize = %d\n", interface_information->Pipes[i].MaximumPacketSize));
   8.154 +      KdPrint((__DRIVER_NAME "       EndpointAddress = %d\n", interface_information->Pipes[i].EndpointAddress));
   8.155 +      KdPrint((__DRIVER_NAME "       Interval = %d\n", interface_information->Pipes[i].Interval));
   8.156 +      KdPrint((__DRIVER_NAME "       PipeType = %d\n", interface_information->Pipes[i].PipeType));
   8.157 +      KdPrint((__DRIVER_NAME "       PipeHandle = %d\n", interface_information->Pipes[i].PipeHandle));
   8.158 +      KdPrint((__DRIVER_NAME "       MaximumTransferSize = %d\n", interface_information->Pipes[i].MaximumTransferSize));
   8.159 +      KdPrint((__DRIVER_NAME "       PipeFlags = %08x\n", interface_information->Pipes[i].PipeFlags));
   8.160 +    }
   8.161 +    urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   8.162 +    WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   8.163 +    break;
   8.164 +  case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
   8.165 +  //case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
   8.166 +  //case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
   8.167 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_XXX\n"));
   8.168 +    KdPrint((__DRIVER_NAME "      Reserved = %p\n", urb->UrbControlDescriptorRequest.Reserved));
   8.169 +    KdPrint((__DRIVER_NAME "      Reserved0 = %08X\n", urb->UrbControlDescriptorRequest.Reserved0));
   8.170 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength));
   8.171 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlDescriptorRequest.TransferBuffer));
   8.172 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlDescriptorRequest.TransferBufferMDL));
   8.173 +    KdPrint((__DRIVER_NAME "      UrbLink = %p\n", urb->UrbControlDescriptorRequest.UrbLink));
   8.174 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[0] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[0]));
   8.175 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[1] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[1]));
   8.176 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[2] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[2]));
   8.177 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[3] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[3]));
   8.178 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[4] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[4]));
   8.179 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[5] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[5]));
   8.180 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[6] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[6]));
   8.181 +    KdPrint((__DRIVER_NAME "      hca.Reserved8[7] = %p\n", urb->UrbControlDescriptorRequest.hca.Reserved8[7]));
   8.182 +    KdPrint((__DRIVER_NAME "      Reserved1 = %04x\n", urb->UrbControlDescriptorRequest.Reserved1));
   8.183 +    KdPrint((__DRIVER_NAME "      Index = %d\n", (int)urb->UrbControlDescriptorRequest.Index));
   8.184 +    KdPrint((__DRIVER_NAME "      DescriptorType = %d\n", (int)urb->UrbControlDescriptorRequest.DescriptorType));
   8.185 +    KdPrint((__DRIVER_NAME "      LanguageId = %04x\n", urb->UrbControlDescriptorRequest.LanguageId));
   8.186 +    KdPrint((__DRIVER_NAME "      Reserved2 = %04X\n", urb->UrbControlDescriptorRequest.Reserved2));
   8.187 +    switch (urb->UrbControlDescriptorRequest.DescriptorType)
   8.188 +    {
   8.189 +    case USB_DEVICE_DESCRIPTOR_TYPE:
   8.190 +      KdPrint((__DRIVER_NAME "      USB_DEVICE_DESCRIPTOR_TYPE\n"));
   8.191 +      memcpy(urb->UrbControlDescriptorRequest.TransferBuffer, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
   8.192 +      urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
   8.193 +      KdPrint((__DRIVER_NAME "      TransferBufferLength returned = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength));
   8.194 +      break;
   8.195 +    case USB_CONFIGURATION_DESCRIPTOR_TYPE:
   8.196 +    {
   8.197 +      xenusb_config_t *usb_config;
   8.198 +      PUCHAR ptr;
   8.199 +
   8.200 +      KdPrint((__DRIVER_NAME "      USB_CONFIGURATION_DESCRIPTOR_TYPE\n"));
   8.201 +      usb_config = usb_device->active_config;
   8.202 +      ptr = (PUCHAR)urb->UrbControlDescriptorRequest.TransferBuffer;
   8.203 +      memcpy(ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
   8.204 +      ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
   8.205 +      ((PUSB_CONFIGURATION_DESCRIPTOR)urb->UrbControlDescriptorRequest.TransferBuffer)->wTotalLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
   8.206 +      if (urb->UrbControlDescriptorRequest.TransferBufferLength > 9)
   8.207 +      {
   8.208 +        for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
   8.209 +        {
   8.210 +          memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
   8.211 +          KdPrint((__DRIVER_NAME "      bInterfaceClass = %02x\n", ((PUSB_INTERFACE_DESCRIPTOR)ptr)->bInterfaceClass));
   8.212 +          ptr += sizeof(USB_INTERFACE_DESCRIPTOR);
   8.213 +          ((PUSB_CONFIGURATION_DESCRIPTOR)urb->UrbControlDescriptorRequest.TransferBuffer)->wTotalLength += sizeof(USB_INTERFACE_DESCRIPTOR);
   8.214 +          for (j = 0; j < usb_config->interfaces[i]->interface_descriptor.bNumEndpoints; j++)
   8.215 +          {
   8.216 +            memcpy(ptr, &usb_config->interfaces[i]->endpoints[j]->endpoint_descriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
   8.217 +            ptr += sizeof(USB_ENDPOINT_DESCRIPTOR);
   8.218 +            ((PUSB_CONFIGURATION_DESCRIPTOR)urb->UrbControlDescriptorRequest.TransferBuffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
   8.219 +          }
   8.220 +        }
   8.221 +      }
   8.222 +      urb->UrbControlDescriptorRequest.TransferBufferLength = ((PUSB_CONFIGURATION_DESCRIPTOR)urb->UrbControlDescriptorRequest.TransferBuffer)->wTotalLength;
   8.223 +      if (urb->UrbControlDescriptorRequest.TransferBufferLength == 9)
   8.224 +        ((PUSB_CONFIGURATION_DESCRIPTOR)urb->UrbControlDescriptorRequest.TransferBuffer)->wTotalLength = 32;
   8.225 +      KdPrint((__DRIVER_NAME "      TransferBufferLength returned = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength));
   8.226 +      break;
   8.227 +    } 
   8.228 +    default:
   8.229 +      KdPrint((__DRIVER_NAME "      UNKNOWN_DESCRIPTOR_TYPE\n"));
   8.230 +      break;
   8.231 +    }
   8.232 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.233 +    WdfRequestComplete(request, STATUS_SUCCESS);
   8.234 +    break;
   8.235 +  case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
   8.236 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_STATUS_FROM_DEVICE\n"));
   8.237 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlGetStatusRequest.TransferBufferLength));
   8.238 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlGetStatusRequest.TransferBuffer));
   8.239 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlGetStatusRequest.TransferBufferMDL));
   8.240 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlGetStatusRequest.Index));
   8.241 +    if (urb->UrbControlGetStatusRequest.Index == 0)
   8.242 +    {
   8.243 +      urb->UrbControlGetStatusRequest.TransferBufferLength = 2;
   8.244 +      *(PUSHORT)urb->UrbControlGetStatusRequest.TransferBuffer = 0x0003;
   8.245 +      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.246 +      WdfRequestComplete(request, STATUS_SUCCESS);
   8.247 +    }
   8.248 +    else
   8.249 +    {
   8.250 +      KdPrint((__DRIVER_NAME "     Unknown Index\n"));
   8.251 +      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   8.252 +      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   8.253 +    }    
   8.254 +    break;
   8.255 +  case URB_FUNCTION_CLASS_DEVICE:
   8.256 +#if 0
   8.257 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_DEVICE\n"));
   8.258 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   8.259 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   8.260 +    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   8.261 +    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   8.262 +    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   8.263 +    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   8.264 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   8.265 +#endif
   8.266 +    switch (urb->UrbControlVendorClassRequest.Request)
   8.267 +    {
   8.268 +    case USB_REQUEST_GET_DESCRIPTOR:
   8.269 +      KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_DEVICE\n"));
   8.270 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   8.271 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   8.272 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   8.273 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   8.274 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   8.275 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   8.276 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   8.277 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_DESCRIPTOR\n"));
   8.278 +      switch (urb->UrbControlVendorClassRequest.Value >> 8)
   8.279 +      {
   8.280 +      case 0x00:
   8.281 +#if 0      
   8.282 +        memcpy(urb->UrbControlVendorClassRequest.TransferBuffer, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
   8.283 +        urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
   8.284 +        urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.285 +        WdfRequestComplete(request, STATUS_SUCCESS);
   8.286 +        break;
   8.287 +#endif
   8.288 +      case 0x29: // Hub Descriptor
   8.289 +        KdPrint((__DRIVER_NAME "       HUB_DESCRIPTOR\n"));
   8.290 +        uhd = urb->UrbControlVendorClassRequest.TransferBuffer;
   8.291 +        urb->UrbControlVendorClassRequest.TransferBufferLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask[0]) + 2 + 1;
   8.292 +        uhd->bDescriptorLength = (UCHAR)urb->UrbControlVendorClassRequest.TransferBufferLength;
   8.293 +        uhd->bDescriptorType = 0x29;
   8.294 +        uhd->bNumberOfPorts = 8;
   8.295 +        uhd->wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
   8.296 +        uhd->bPowerOnToPowerGood = 1; // 2ms units
   8.297 +        uhd->bHubControlCurrent = 0;
   8.298 +        // DeviceRemovable bits (includes an extra bit at the start)
   8.299 +        uhd->bRemoveAndPowerMask[0] = 0;
   8.300 +        uhd->bRemoveAndPowerMask[1] = 0;
   8.301 +        // PortPwrCtrlMask
   8.302 +        uhd->bRemoveAndPowerMask[2] = 0xFF;
   8.303 +        urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.304 +        WdfRequestComplete(request, STATUS_SUCCESS);
   8.305 +        break;
   8.306 +      default:
   8.307 +        KdPrint((__DRIVER_NAME "       Unknown Value %02x\n", urb->UrbControlVendorClassRequest.Value >> 8));
   8.308 +        urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   8.309 +        WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   8.310 +        break;
   8.311 +      }
   8.312 +      break;
   8.313 +    case USB_REQUEST_GET_STATUS:
   8.314 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   8.315 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   8.316 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   8.317 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   8.318 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   8.319 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   8.320 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   8.321 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   8.322 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_STATUS\n"));
   8.323 +      // Check that RequestTypeReservedBits == 0xA0
   8.324 +      KdPrint((__DRIVER_NAME "       GetHubStatus\n"));
   8.325 +      /* hub status */
   8.326 +      // shoud be able to get this field from somewhere else...
   8.327 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0x0000;
   8.328 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[1] = 0x0000; /* no change occurred */
   8.329 +      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.330 +      WdfRequestComplete(request, STATUS_SUCCESS);
   8.331 +      break;
   8.332 +    case USB_REQUEST_CLEAR_FEATURE:
   8.333 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   8.334 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   8.335 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   8.336 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   8.337 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   8.338 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   8.339 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   8.340 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   8.341 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_CLEAR_FEATURE\n"));
   8.342 +      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.343 +      WdfRequestComplete(request, STATUS_SUCCESS);
   8.344 +      break;
   8.345 +    default:
   8.346 +      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   8.347 +      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   8.348 +      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   8.349 +      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   8.350 +      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   8.351 +      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   8.352 +      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   8.353 +      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   8.354 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_%02x\n", urb->UrbControlVendorClassRequest.Request));
   8.355 +      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   8.356 +      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   8.357 +      break;
   8.358 +    }
   8.359 +    break;
   8.360 +  case URB_FUNCTION_CLASS_OTHER:
   8.361 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_OTHER\n"));
   8.362 +    KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   8.363 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   8.364 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   8.365 +    KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   8.366 +    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   8.367 +    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   8.368 +    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   8.369 +    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   8.370 +    switch (urb->UrbControlVendorClassRequest.Request)
   8.371 +    {
   8.372 +    case USB_REQUEST_GET_STATUS:
   8.373 +      /* port status - 11.24.2.7.1 */
   8.374 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_STATUS\n"));
   8.375 +      KdPrint((__DRIVER_NAME "       GetHubStatus\n"));
   8.376 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[0] = xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status;
   8.377 +      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[1] = xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change;
   8.378 +      break;
   8.379 +    case USB_REQUEST_SET_FEATURE:
   8.380 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_SET_FEATURE\n"));
   8.381 +      KdPrint((__DRIVER_NAME "       SetPortFeature\n"));
   8.382 +      switch (urb->UrbControlVendorClassRequest.Value)
   8.383 +      {
   8.384 +      case PORT_ENABLE:
   8.385 +        KdPrint((__DRIVER_NAME "        PORT_ENABLE\n"));
   8.386 +        /* do something here */
   8.387 +        break;
   8.388 +      case PORT_RESET:
   8.389 +        KdPrint((__DRIVER_NAME "        PORT_RESET\n"));
   8.390 +        /* just fake the reset */
   8.391 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change |= (1 << PORT_RESET);
   8.392 +        break;
   8.393 +      default:
   8.394 +        KdPrint((__DRIVER_NAME "        Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value));
   8.395 +        break;
   8.396 +      }
   8.397 +      KdPrint((__DRIVER_NAME "        status = %04x, change = %04x\n",
   8.398 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   8.399 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   8.400 +      break;
   8.401 +    case USB_REQUEST_CLEAR_FEATURE:
   8.402 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_CLEAR_FEATURE\n"));
   8.403 +      KdPrint((__DRIVER_NAME "       ClearPortFeature\n"));
   8.404 +      switch (urb->UrbControlVendorClassRequest.Value)
   8.405 +      {
   8.406 +      case C_PORT_CONNECTION:
   8.407 +        KdPrint((__DRIVER_NAME "        C_PORT_CONNECTION\n"));
   8.408 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change &= ~(1 << PORT_CONNECTION);
   8.409 +        break;
   8.410 +      case C_PORT_RESET:
   8.411 +        KdPrint((__DRIVER_NAME "        C_PORT_RESET\n"));
   8.412 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change &= ~(1 << PORT_RESET);
   8.413 +        break;
   8.414 +      default:
   8.415 +        KdPrint((__DRIVER_NAME "        Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value));
   8.416 +        break;
   8.417 +      }
   8.418 +      KdPrint((__DRIVER_NAME "        status = %04x, change = %04x\n",
   8.419 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   8.420 +        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   8.421 +      break;
   8.422 +    default:
   8.423 +      KdPrint((__DRIVER_NAME "      USB_REQUEST_%02x\n", urb->UrbControlVendorClassRequest.Request));
   8.424 +      break;
   8.425 +    }
   8.426 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.427 +    WdfRequestComplete(request, STATUS_SUCCESS);
   8.428 +    //urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   8.429 +    //WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   8.430 +    break;
   8.431 +  case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
   8.432 +#if 0
   8.433 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n"));
   8.434 +    KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbBulkOrInterruptTransfer.PipeHandle));
   8.435 +    KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags));
   8.436 +    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbBulkOrInterruptTransfer.TransferBufferLength));
   8.437 +    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBuffer));
   8.438 +    KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBufferMDL));
   8.439 +#endif
   8.440 +    endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;
   8.441 +    WdfSpinLockAcquire (endpoint->interrupt_lock);
   8.442 +    // we should synchronise to the timer here to prevent a race
   8.443 +    if (WdfIoQueueGetState(endpoint->interrupt_queue, NULL, NULL) & WdfIoQueueNoRequests)
   8.444 +    {
   8.445 +      status = WdfTimerStart(endpoint->interrupt_timer, WDF_REL_TIMEOUT_IN_MS(100));
   8.446 +    }
   8.447 +    status = WdfRequestForwardToIoQueue(request, endpoint->interrupt_queue);
   8.448 +    WdfSpinLockRelease(endpoint->interrupt_lock);
   8.449 +    break;
   8.450 +  case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
   8.451 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n"));
   8.452 +    KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
   8.453 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   8.454 +    WdfRequestComplete(request, STATUS_SUCCESS);
   8.455 +    break;
   8.456 +  default:
   8.457 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_%04x\n", urb->UrbHeader.Function));
   8.458 +    KdPrint((__DRIVER_NAME "     Calling WdfRequestCompletestatus with status = %08x\n", status));
   8.459 +    urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   8.460 +    WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   8.461 +    break;
   8.462 +  }
   8.463 +
   8.464 +  //FUNCTION_EXIT();
   8.465 +}
   8.466 +