win-pvdrivers

changeset 964:19d7c9dd9f5c

Fixes for USB
Still _very_ experimental
Only tested under 2008 R2
Does not clear requests cleanly - hang on shutdown
author James Harper <james.harper@bendigoit.com.au>
date Tue Jan 10 12:10:51 2012 +1100 (2012-01-10)
parents f4bc40d6987f
children 63bdd096d8d1
files xenusb/xenusb.h xenusb/xenusb_decode.c xenusb/xenusb_devurb.c xenusb/xenusb_fdo.c xenusb/xenusb_hub.c xenusb/xenusb_huburb.c
line diff
     1.1 --- a/xenusb/xenusb.h	Fri Dec 30 21:05:57 2011 +1100
     1.2 +++ b/xenusb/xenusb.h	Tue Jan 10 12:10:51 2012 +1100
     1.3 @@ -158,6 +158,7 @@ typedef struct _xenusb_interface_t {
     1.4  typedef struct _xenusb_config_t {
     1.5    xenusb_device_t *device;
     1.6    USB_CONFIGURATION_DESCRIPTOR config_descriptor;
     1.7 +  PUCHAR config_descriptor_all;
     1.8    xenusb_interface_t *interfaces[0];
     1.9  } xenusb_config_t;
    1.10  
    1.11 @@ -188,11 +189,18 @@ typedef struct
    1.12    ULONG reset_counter;
    1.13  } xenusb_port_t;
    1.14  
    1.15 -typedef struct {  
    1.16 +/*
    1.17 +TODO: this driver crashes under checked build of windows (or probably just checked usbhub.sys)
    1.18 +Needs a magic number of (ULONG)'HUBx' at the start of BusContext
    1.19 +Other magic numbers (ULONG)'BStx' at offset 0x4C of some structure
    1.20 + and (ULONG)'HUB ' somewhere in an FDO extension(?)
    1.21 +*/
    1.22 +
    1.23 +typedef struct {
    1.24 +  ULONG magic; /* (ULONG)'HUBx' */
    1.25 +  /* other magic numbers are (ULONG)'BStx' at offset 0x4C and (ULONG)'HUB ' somewhere in an FDO extension(?) */
    1.26    BOOLEAN XenBus_ShuttingDown;
    1.27    WDFQUEUE io_queue;
    1.28 -  //WDFDMAENABLER dma_enabler;
    1.29 -  
    1.30    WDFCHILDLIST child_list;
    1.31    
    1.32    WDFDEVICE root_hub_device;
    1.33 @@ -341,8 +349,11 @@ XenUsb_ExecuteRequest(
    1.34  #define URB_DECODE_NOT_CONTROL 3 /* URB is known but not a control packet */
    1.35  
    1.36  typedef struct {
    1.37 +  char *urb_function_name;
    1.38    PULONG length;
    1.39    PVOID buffer;
    1.40 +  PVOID mdl;
    1.41 +  ULONG transfer_flags;
    1.42    union {
    1.43      USB_DEFAULT_PIPE_SETUP_PACKET default_pipe_setup_packet;
    1.44      UCHAR raw[8];
     2.1 --- a/xenusb/xenusb_decode.c	Fri Dec 30 21:05:57 2011 +1100
     2.2 +++ b/xenusb/xenusb_decode.c	Tue Jan 10 12:10:51 2012 +1100
     2.3 @@ -19,6 +19,85 @@ Foundation, Inc., 51 Franklin Street, Fi
     2.4  
     2.5  #include "xenusb.h"
     2.6  
     2.7 +#define DECODE_COMPUTE 0x40000000 /* calculate the value - not applicable to all fields */
     2.8 +#define DECODE_COPY    0x80000000 /* copy from URB */
     2.9 +/* otherwise literal value */
    2.10 +
    2.11 +typedef struct {
    2.12 +  PCHAR urb_function_name;
    2.13 +  BOOLEAN is_simple_control;
    2.14 +  ULONG bmRequestTypeRecipient;
    2.15 +  ULONG bmRequestTypeType;
    2.16 +  ULONG bmRequestTypeDir;
    2.17 +  ULONG bRequest;
    2.18 +  ULONG wValueLow;
    2.19 +  ULONG wValueHigh;
    2.20 +  ULONG wIndexLow;
    2.21 +  ULONG wIndexHigh;
    2.22 +  ULONG wLength;
    2.23 +  ULONG transfer_flags;
    2.24 +} decode_t;
    2.25 +
    2.26 +static decode_t decodes[] = {
    2.27 +  /* 0000 */
    2.28 +  {"URB_FUNCTION_SELECT_CONFIGURATION",             FALSE},
    2.29 +  {"URB_FUNCTION_SELECT_INTERFACE",                 FALSE},
    2.30 +  {"URB_FUNCTION_ABORT_PIPE",                       FALSE},
    2.31 +  {"URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL",        FALSE},
    2.32 +  {"URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL",     FALSE},
    2.33 +  {"URB_FUNCTION_GET_FRAME_LENGTH",                 FALSE},
    2.34 +  {"URB_FUNCTION_SET_FRAME_LENGTH",                 FALSE},
    2.35 +  {"URB_FUNCTION_GET_CURRENT_FRAME_NUMBER",         FALSE},
    2.36 +  {"URB_FUNCTION_CONTROL_TRANSFER",                 TRUE, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.37 +  {"URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER",       FALSE},
    2.38 +  {"URB_FUNCTION_ISOCH_TRANSFER",                   FALSE},
    2.39 +  {"URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE",       TRUE, BMREQUEST_TO_DEVICE, BMREQUEST_STANDARD, BMREQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.40 +  {"URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE",         FALSE},
    2.41 +  {"URB_FUNCTION_SET_FEATURE_TO_DEVICE",            FALSE},
    2.42 +  {"URB_FUNCTION_SET_FEATURE_TO_INTERFACE",         FALSE},
    2.43 +  {"URB_FUNCTION_SET_FEATURE_TO_ENDPOINT",          FALSE},
    2.44 +  /* 0010 */
    2.45 +  {"URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE",          FALSE},
    2.46 +  {"URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE",       FALSE},
    2.47 +  {"URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT",        FALSE},
    2.48 +  {"URB_FUNCTION_GET_STATUS_FROM_DEVICE",           FALSE},
    2.49 +  {"URB_FUNCTION_GET_STATUS_FROM_INTERFACE",        FALSE},
    2.50 +  {"URB_FUNCTION_GET_STATUS_FROM_ENDPOINT",         FALSE},
    2.51 +  {"URB_FUNCTION_RESERVED_0X0016",                  FALSE},
    2.52 +  {"URB_FUNCTION_VENDOR_DEVICE",                    TRUE, BMREQUEST_TO_DEVICE, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.53 +  {"URB_FUNCTION_VENDOR_INTERFACE",                 TRUE, BMREQUEST_TO_INTERFACE, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.54 +  {"URB_FUNCTION_VENDOR_ENDPOINT",                  TRUE, BMREQUEST_TO_ENDPOINT, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.55 +  {"URB_FUNCTION_CLASS_DEVICE",                     TRUE, BMREQUEST_TO_DEVICE, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.56 +  {"URB_FUNCTION_CLASS_INTERFACE",                  TRUE, BMREQUEST_TO_INTERFACE, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.57 +  {"URB_FUNCTION_CLASS_ENDPOINT",                   TRUE, BMREQUEST_TO_ENDPOINT, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.58 +  {"URB_FUNCTION_RESERVE_0X001D",                   FALSE},
    2.59 +  {"URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL",  FALSE},
    2.60 +  {"URB_FUNCTION_CLASS_OTHER",                      TRUE, BMREQUEST_TO_OTHER, BMREQUEST_CLASS, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.61 +  /* 0020 */
    2.62 +  {"URB_FUNCTION_VENDOR_OTHER",                     TRUE, BMREQUEST_TO_OTHER, BMREQUEST_VENDOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.63 +  {"URB_FUNCTION_GET_STATUS_FROM_OTHER",            FALSE},
    2.64 +  {"URB_FUNCTION_CLEAR_FEATURE_TO_OTHER",           FALSE},
    2.65 +  {"URB_FUNCTION_SET_FEATURE_TO_OTHER",             FALSE},
    2.66 +  {"URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT",     TRUE, BMREQUEST_TO_ENDPOINT, BMREQUEST_STANDARD, BMREQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.67 +  {"URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT",       FALSE},
    2.68 +  {"URB_FUNCTION_GET_CONFIGURATION",                FALSE},
    2.69 +  {"URB_FUNCTION_GET_INTERFACE",                    FALSE},
    2.70 +  {"URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE",    TRUE, BMREQUEST_TO_INTERFACE, BMREQUEST_STANDARD, BMREQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.71 +  {"URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE",      FALSE},
    2.72 +  {"URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR",        FALSE},
    2.73 +  {"URB_FUNCTION_RESERVE_0X002B",                   FALSE},
    2.74 +  {"URB_FUNCTION_RESERVE_0X002C",                   FALSE},
    2.75 +  {"URB_FUNCTION_RESERVE_0X002D",                   FALSE},
    2.76 +  {"URB_FUNCTION_RESERVE_0X002E",                   FALSE},
    2.77 +  {"URB_FUNCTION_RESERVE_0X002F",                   FALSE},
    2.78 +  /* 0030 */
    2.79 +  {"URB_FUNCTION_SYNC_RESET_PIPE",                  FALSE},
    2.80 +  {"URB_FUNCTION_SYNC_CLEAR_STALL",                 FALSE},
    2.81 +  {"URB_FUNCTION_CONTROL_TRANSFER_EX",              TRUE, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COPY, DECODE_COMPUTE, DECODE_COMPUTE},
    2.82 +  {"URB_FUNCTION_RESERVE_0X0033",                   FALSE},
    2.83 +  {"URB_FUNCTION_RESERVE_0X0034",                   FALSE},
    2.84 +};
    2.85 +
    2.86  /*
    2.87  decode all the funky URB_Xxx functions into a basic 8 byte SetupPacket
    2.88  */
    2.89 @@ -26,6 +105,86 @@ ULONG
    2.90  XenUsb_DecodeControlUrb(PURB urb, urb_decode_t *decode_data)
    2.91  {
    2.92    ULONG retval;
    2.93 +  decode_t *decode;
    2.94 +  PUSB_DEFAULT_PIPE_SETUP_PACKET setup_packet;
    2.95 +
    2.96 +  if (urb->UrbHeader.Function > ARRAY_SIZE(decodes)) {
    2.97 +    FUNCTION_MSG("Unknown URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
    2.98 +    return URB_DECODE_UNKNOWN;
    2.99 +  }
   2.100 +  decode = &decodes[urb->UrbHeader.Function];
   2.101 +  FUNCTION_MSG("decoding %s\n", decode->urb_function_name);
   2.102 +  
   2.103 +  if (decode->is_simple_control) {
   2.104 +    FUNCTION_MSG("is a simple control URB\n");
   2.105 +    
   2.106 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)urb->UrbControlTransfer.SetupPacket;
   2.107 +    
   2.108 +    if (decode->bmRequestTypeRecipient == DECODE_COPY)
   2.109 +      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = setup_packet->bmRequestType.Recipient;
   2.110 +    else
   2.111 +      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = (UCHAR)decode->bmRequestTypeRecipient;
   2.112 +    if (decode->bmRequestTypeType == DECODE_COPY)
   2.113 +      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = setup_packet->bmRequestType.Type;
   2.114 +    else
   2.115 +      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = (UCHAR)decode->bmRequestTypeType;
   2.116 +    if (decode->bmRequestTypeDir == DECODE_COPY)
   2.117 +      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = setup_packet->bmRequestType.Dir;
   2.118 +    else
   2.119 +      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = (UCHAR)decode->bmRequestTypeDir;
   2.120 +
   2.121 +    if (decode->bRequest == DECODE_COPY)
   2.122 +      decode_data->setup_packet.default_pipe_setup_packet.bRequest = setup_packet->bRequest;
   2.123 +    else
   2.124 +      decode_data->setup_packet.default_pipe_setup_packet.bRequest = (UCHAR)decode->bRequest;
   2.125 +      
   2.126 +    if (decode->wValueLow == DECODE_COPY)
   2.127 +      decode_data->setup_packet.default_pipe_setup_packet.wValue.LowByte = setup_packet->wValue.LowByte;
   2.128 +    else
   2.129 +      decode_data->setup_packet.default_pipe_setup_packet.wValue.LowByte = (UCHAR)decode->wValueLow;
   2.130 +
   2.131 +    if (decode->wValueHigh == DECODE_COPY)
   2.132 +      decode_data->setup_packet.default_pipe_setup_packet.wValue.HiByte = setup_packet->wValue.HiByte;
   2.133 +    else
   2.134 +      decode_data->setup_packet.default_pipe_setup_packet.wValue.HiByte = (UCHAR)decode->wValueHigh;
   2.135 +
   2.136 +    if (decode->wIndexLow == DECODE_COPY)
   2.137 +      decode_data->setup_packet.default_pipe_setup_packet.wIndex.LowByte = setup_packet->wIndex.LowByte;
   2.138 +    else
   2.139 +      decode_data->setup_packet.default_pipe_setup_packet.wIndex.LowByte = (UCHAR)decode->wIndexLow;
   2.140 +
   2.141 +    if (decode->wIndexHigh == DECODE_COPY)
   2.142 +      decode_data->setup_packet.default_pipe_setup_packet.wIndex.HiByte = setup_packet->wIndex.HiByte;
   2.143 +    else
   2.144 +      decode_data->setup_packet.default_pipe_setup_packet.wIndex.HiByte = (UCHAR)decode->wIndexHigh;
   2.145 +
   2.146 +    if (decode->wLength == DECODE_COMPUTE)
   2.147 +      /* use buffer length */
   2.148 +      decode_data->setup_packet.default_pipe_setup_packet.wLength = (USHORT)urb->UrbControlTransfer.TransferBufferLength;
   2.149 +    else if (decode->wLength == DECODE_COPY)
   2.150 +      decode_data->setup_packet.default_pipe_setup_packet.wLength = setup_packet->wLength;
   2.151 +    else
   2.152 +      decode_data->setup_packet.default_pipe_setup_packet.wLength = (UCHAR)decode->wLength;
   2.153 +
   2.154 +    if (decode->transfer_flags == DECODE_COMPUTE) {
   2.155 +      /* Fix up transfer_flags based on direction in bmRequest */
   2.156 +      if (decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir == BMREQUEST_DEVICE_TO_HOST)
   2.157 +        decode_data->transfer_flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
   2.158 +      else
   2.159 +        decode_data->transfer_flags = 0;
   2.160 +    } else if (decode->transfer_flags == DECODE_COPY) {
   2.161 +      decode_data->transfer_flags = urb->UrbControlTransfer.TransferFlags;
   2.162 +    } else {
   2.163 +      decode_data->transfer_flags = decode->transfer_flags;
   2.164 +    }
   2.165 +
   2.166 +
   2.167 +    decode_data->buffer = urb->UrbControlTransfer.TransferBuffer;
   2.168 +    decode_data->mdl = urb->UrbControlTransfer.TransferBufferMDL;
   2.169 +    decode_data->length = &urb->UrbControlTransfer.TransferBufferLength;
   2.170 +
   2.171 +    return URB_DECODE_COMPLETE;
   2.172 +  }
   2.173    
   2.174    //FUNCTION_ENTER();
   2.175    switch(urb->UrbHeader.Function)
   2.176 @@ -39,7 +198,9 @@ XenUsb_DecodeControlUrb(PURB urb, urb_de
   2.177      decode_data->setup_packet.default_pipe_setup_packet.wLength = 0;
   2.178      decode_data->setup_packet.default_pipe_setup_packet.wValue.W = urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue;
   2.179      decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = 0;
   2.180 +    decode_data->transfer_flags = 0;
   2.181      decode_data->buffer = NULL;
   2.182 +    decode_data->mdl = NULL;
   2.183      retval = URB_DECODE_INCOMPLETE;
   2.184      break;
   2.185    case URB_FUNCTION_SELECT_INTERFACE:
   2.186 @@ -51,9 +212,12 @@ XenUsb_DecodeControlUrb(PURB urb, urb_de
   2.187      decode_data->setup_packet.default_pipe_setup_packet.wLength = 0;
   2.188      decode_data->setup_packet.default_pipe_setup_packet.wValue.W = urb->UrbSelectInterface.Interface.AlternateSetting;
   2.189      decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = urb->UrbSelectInterface.Interface.InterfaceNumber;
   2.190 +    decode_data->transfer_flags = 0;
   2.191      decode_data->buffer = NULL;
   2.192 +    decode_data->mdl = NULL;
   2.193      retval = URB_DECODE_INCOMPLETE;
   2.194      break;
   2.195 +#if 0
   2.196    case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
   2.197      KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"));
   2.198      decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   2.199 @@ -72,22 +236,48 @@ XenUsb_DecodeControlUrb(PURB urb, urb_de
   2.200        break;
   2.201      }
   2.202      decode_data->setup_packet.default_pipe_setup_packet.wLength = (USHORT)urb->UrbControlDescriptorRequest.TransferBufferLength;
   2.203 +    decode_data->transfer_flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
   2.204      decode_data->buffer = urb->UrbControlTransfer.TransferBuffer;
   2.205 +    decode_data->mdl = urb->UrbControlTransfer.TransferBufferMDL;
   2.206 +    decode_data->length = &urb->UrbControlTransfer.TransferBufferLength;
   2.207 +    retval = URB_DECODE_COMPLETE;
   2.208 +    break;
   2.209 +  case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
   2.210 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n"));
   2.211 +    decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
   2.212 +    decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Type = BMREQUEST_STANDARD;
   2.213 +    decode_data->setup_packet.default_pipe_setup_packet.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   2.214 +    decode_data->setup_packet.default_pipe_setup_packet.bRequest = USB_REQUEST_GET_DESCRIPTOR;
   2.215 +    decode_data->setup_packet.default_pipe_setup_packet.wValue.LowByte = urb->UrbControlDescriptorRequest.Index;
   2.216 +    decode_data->setup_packet.default_pipe_setup_packet.wValue.HiByte = urb->UrbControlDescriptorRequest.DescriptorType;
   2.217 +    switch(urb->UrbControlDescriptorRequest.DescriptorType)
   2.218 +    {
   2.219 +    case USB_STRING_DESCRIPTOR_TYPE:
   2.220 +      decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = urb->UrbControlDescriptorRequest.LanguageId;
   2.221 +      break;
   2.222 +    default:
   2.223 +      decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = 0;
   2.224 +      break;
   2.225 +    }
   2.226 +    decode_data->setup_packet.default_pipe_setup_packet.wLength = (USHORT)urb->UrbControlDescriptorRequest.TransferBufferLength;
   2.227 +    decode_data->transfer_flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
   2.228 +    decode_data->buffer = urb->UrbControlTransfer.TransferBuffer;
   2.229 +    decode_data->mdl = urb->UrbControlTransfer.TransferBufferMDL;
   2.230      decode_data->length = &urb->UrbControlTransfer.TransferBufferLength;
   2.231      retval = URB_DECODE_COMPLETE;
   2.232      break;
   2.233    case URB_FUNCTION_CLASS_DEVICE: /* CONTROL_TRANSFER has same underlying format as FUNCTION_CLASS_XXX */
   2.234 -FUNCTION_MSG("Function = %04x, RequestTypeReservedBits = %02x\n", urb->UrbHeader.Function, urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
   2.235    case URB_FUNCTION_CLASS_OTHER:
   2.236 +  case URB_FUNCTION_CLASS_INTERFACE: /* not yet tested */
   2.237    //case URB_FUNCTION_GET_STATUS_FROM_DEVICE: // seems to be missing fields...
   2.238    case URB_FUNCTION_CONTROL_TRANSFER:
   2.239  #if (NTDDI_VERSION >= NTDDI_VISTA)  
   2.240    case URB_FUNCTION_CONTROL_TRANSFER_EX:
   2.241  #endif
   2.242 -
   2.243 -    //KdPrint((__DRIVER_NAME "     URB_FUNCTION_CONTROL_TRANSFER\n"));
   2.244      decode_data->buffer = urb->UrbControlTransfer.TransferBuffer;
   2.245 +    decode_data->mdl = urb->UrbControlTransfer.TransferBufferMDL;
   2.246      decode_data->length = &urb->UrbControlTransfer.TransferBufferLength;
   2.247 +    decode_data->transfer_flags = urb->UrbControlTransfer.TransferFlags;
   2.248      memcpy(decode_data->setup_packet.raw, urb->UrbControlTransfer.SetupPacket, sizeof(decode_data->setup_packet.raw));
   2.249      retval = URB_DECODE_COMPLETE;
   2.250      break;
   2.251 @@ -101,7 +291,9 @@ FUNCTION_MSG("Function = %04x, RequestTy
   2.252      decode_data->setup_packet.default_pipe_setup_packet.wValue.W = 0;
   2.253      decode_data->setup_packet.default_pipe_setup_packet.wIndex.W = urb->UrbControlGetStatusRequest.Index;
   2.254      decode_data->buffer = urb->UrbControlTransfer.TransferBuffer;
   2.255 +    decode_data->mdl = urb->UrbControlTransfer.TransferBufferMDL;
   2.256      decode_data->length = &urb->UrbControlTransfer.TransferBufferLength;
   2.257 +    decode_data->transfer_flags = urb->UrbControlTransfer.TransferFlags;
   2.258      retval = URB_DECODE_COMPLETE;
   2.259      break;
   2.260  #if 0
   2.261 @@ -402,13 +594,15 @@ FUNCTION_MSG("Function = %04x, RequestTy
   2.262      WdfRequestComplete(request, STATUS_SUCCESS);
   2.263      break;
   2.264  #endif
   2.265 +#endif
   2.266    case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
   2.267    case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
   2.268 -    //FUNCTION_MSG("NOT_CONTROL URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
   2.269 +  case URB_FUNCTION_ABORT_PIPE:
   2.270 +    FUNCTION_MSG("NOT_CONTROL URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
   2.271      retval = URB_DECODE_NOT_CONTROL;
   2.272      break;
   2.273    default:
   2.274 -    FUNCTION_MSG("Unknown URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
   2.275 +    FUNCTION_MSG("NOT IMPLEMENTED\n", urb->UrbHeader.Function);
   2.276      retval = URB_DECODE_UNKNOWN;
   2.277      break;
   2.278    }
     3.1 --- a/xenusb/xenusb_devurb.c	Fri Dec 30 21:05:57 2011 +1100
     3.2 +++ b/xenusb/xenusb_devurb.c	Tue Jan 10 12:10:51 2012 +1100
     3.3 @@ -88,6 +88,17 @@ XenUsb_UrbCallback(usbif_shadow_t *shado
     3.4      KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_INTERFACE\n"));
     3.5      shadow->urb->UrbControlVendorClassRequest.TransferBufferLength = shadow->total_length;
     3.6      break;
     3.7 +  case URB_FUNCTION_CONTROL_TRANSFER:
     3.8 +  case URB_FUNCTION_CONTROL_TRANSFER_EX:
     3.9 +    KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
    3.10 +    KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
    3.11 +    KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
    3.12 +    KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
    3.13 +    KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
    3.14 +    KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
    3.15 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CONTROL_TRANSFER (_EX)\n"));
    3.16 +    shadow->urb->UrbControlTransfer.TransferBufferLength = shadow->total_length;
    3.17 +    break;
    3.18    case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
    3.19  //    if (shadow->rsp.status)
    3.20      {
    3.21 @@ -171,6 +182,8 @@ XenUsb_EvtIoInternalDeviceControl_DEVICE
    3.22    xenusb_device_t *usb_device;
    3.23    //PUSB_HUB_DESCRIPTOR uhd;
    3.24    xenusb_endpoint_t *endpoint;
    3.25 +  urb_decode_t decode_data;
    3.26 +  ULONG decode_retval;
    3.27  
    3.28    UNREFERENCED_PARAMETER(input_buffer_length);
    3.29    UNREFERENCED_PARAMETER(output_buffer_length);
    3.30 @@ -198,6 +211,33 @@ XenUsb_EvtIoInternalDeviceControl_DEVICE
    3.31    usb_device = urb->UrbHeader.UsbdDeviceHandle;
    3.32  
    3.33    ASSERT(usb_device);
    3.34 +
    3.35 +  decode_retval = XenUsb_DecodeControlUrb(urb, &decode_data);
    3.36 +  if (decode_retval == URB_DECODE_UNKNOWN)
    3.37 +  {
    3.38 +    FUNCTION_MSG("Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL);
    3.39 +    urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
    3.40 +    WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
    3.41 +    return;
    3.42 +  }
    3.43 +
    3.44 +#if 0
    3.45 +  if (decode_retval != URB_DECODE_NOT_CONTROL)
    3.46 +  {
    3.47 +    FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
    3.48 +    FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
    3.49 +    FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
    3.50 +    FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
    3.51 +    FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
    3.52 +    FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
    3.53 +    FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
    3.54 +    FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
    3.55 +    FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
    3.56 +    FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
    3.57 +    FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
    3.58 +    FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
    3.59 +  }
    3.60 +#endif
    3.61    
    3.62    switch(urb->UrbHeader.Function)
    3.63    {
    3.64 @@ -262,15 +302,19 @@ XenUsb_EvtIoInternalDeviceControl_DEVICE
    3.65            switch (usb_endpoint->endpoint_descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK)
    3.66            {
    3.67            case USB_ENDPOINT_TYPE_CONTROL:
    3.68 +            FUNCTION_MSG("USB_ENDPOINT_TYPE_CONTROL");
    3.69              interface_information->Pipes[j].PipeType = UsbdPipeTypeControl;
    3.70              break;
    3.71            case USB_ENDPOINT_TYPE_ISOCHRONOUS:
    3.72 +            FUNCTION_MSG("USB_ENDPOINT_TYPE_ISOCHRONOUS");
    3.73              interface_information->Pipes[j].PipeType = UsbdPipeTypeIsochronous;
    3.74              break;
    3.75            case USB_ENDPOINT_TYPE_BULK:
    3.76 +            FUNCTION_MSG("USB_ENDPOINT_TYPE_BULK");
    3.77              interface_information->Pipes[j].PipeType = UsbdPipeTypeBulk;
    3.78              break;
    3.79            case USB_ENDPOINT_TYPE_INTERRUPT:
    3.80 +            FUNCTION_MSG("USB_ENDPOINT_TYPE_INTERRUPT");
    3.81              interface_information->Pipes[j].PipeType = UsbdPipeTypeInterrupt;
    3.82              break;
    3.83            }
    3.84 @@ -362,385 +406,52 @@ XenUsb_EvtIoInternalDeviceControl_DEVICE
    3.85        KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
    3.86      }
    3.87      break;
    3.88 +#if (NTDDI_VERSION >= NTDDI_VISTA)  
    3.89 +  case URB_FUNCTION_CONTROL_TRANSFER_EX:
    3.90 +#endif
    3.91 +  case URB_FUNCTION_CONTROL_TRANSFER:
    3.92 +  case URB_FUNCTION_CLASS_DEVICE:
    3.93 +  case URB_FUNCTION_CLASS_INTERFACE:
    3.94 +  case URB_FUNCTION_CLASS_OTHER:
    3.95    case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
    3.96 -    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n"));
    3.97 -    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength));
    3.98 -    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlDescriptorRequest.TransferBuffer));
    3.99 -    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlDescriptorRequest.TransferBufferMDL));
   3.100 -    KdPrint((__DRIVER_NAME "      Index = %d\n", (int)urb->UrbControlDescriptorRequest.Index));
   3.101 -    KdPrint((__DRIVER_NAME "      DescriptorType = %d\n", (int)urb->UrbControlDescriptorRequest.DescriptorType));
   3.102 -    KdPrint((__DRIVER_NAME "      LanguageId = %04x\n", urb->UrbControlDescriptorRequest.LanguageId));
   3.103 -    shadow = get_shadow_from_freelist(xudd);
   3.104 -    shadow->request = request;
   3.105 -    shadow->urb = urb;
   3.106 -    shadow->callback = XenUsb_UrbCallback;
   3.107 -    shadow->req.id = shadow->id;
   3.108 -    shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   3.109 -    shadow->req.transfer_flags = 0; 
   3.110 -    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   3.111 -    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   3.112 -    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   3.113 -    setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   3.114 -    setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
   3.115 -    setup_packet->wValue.LowByte = urb->UrbControlDescriptorRequest.Index;
   3.116 -    setup_packet->wValue.HiByte = urb->UrbControlDescriptorRequest.DescriptorType;
   3.117 -    switch(urb->UrbControlDescriptorRequest.DescriptorType)
   3.118 -    {
   3.119 -    case USB_STRING_DESCRIPTOR_TYPE:
   3.120 -      setup_packet->wIndex.W = urb->UrbControlDescriptorRequest.LanguageId;
   3.121 -      break;
   3.122 -    default:
   3.123 -      setup_packet->wIndex.W = 0;
   3.124 -      break;
   3.125 -    }
   3.126 -    setup_packet->wLength = (USHORT)urb->UrbControlDescriptorRequest.TransferBufferLength;
   3.127 -    status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbControlDescriptorRequest.TransferBuffer, urb->UrbControlDescriptorRequest.TransferBufferMDL, urb->UrbControlDescriptorRequest.TransferBufferLength);
   3.128 -    if (!NT_SUCCESS(status))
   3.129 -    {
   3.130 -      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   3.131 -    }
   3.132 -    break;
   3.133    case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
   3.134 -    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n"));
   3.135 -    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlDescriptorRequest.TransferBufferLength));
   3.136 -    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlDescriptorRequest.TransferBuffer));
   3.137 -    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlDescriptorRequest.TransferBufferMDL));
   3.138 -    KdPrint((__DRIVER_NAME "      Index = %d\n", (int)urb->UrbControlDescriptorRequest.Index));
   3.139 -    KdPrint((__DRIVER_NAME "      DescriptorType = %d\n", (int)urb->UrbControlDescriptorRequest.DescriptorType));
   3.140 -    KdPrint((__DRIVER_NAME "      LanguageId = %04x\n", urb->UrbControlDescriptorRequest.LanguageId));
   3.141 -    shadow = get_shadow_from_freelist(xudd);
   3.142 -    shadow->request = request;
   3.143 -    shadow->urb = urb;
   3.144 -    shadow->callback = XenUsb_UrbCallback;
   3.145 -    shadow->req.id = shadow->id;
   3.146 -    shadow->req.pipe = LINUX_PIPE_DIRECTION_IN | LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   3.147 -    shadow->req.transfer_flags = 0; 
   3.148 -    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   3.149 -    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
   3.150 -    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
   3.151 -    setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   3.152 -    setup_packet->bRequest = USB_REQUEST_GET_DESCRIPTOR;
   3.153 -    setup_packet->wValue.LowByte = urb->UrbControlDescriptorRequest.Index;
   3.154 -    setup_packet->wValue.HiByte = urb->UrbControlDescriptorRequest.DescriptorType;
   3.155 -    switch(urb->UrbControlDescriptorRequest.DescriptorType)
   3.156 -    {
   3.157 -    case USB_STRING_DESCRIPTOR_TYPE:
   3.158 -      setup_packet->wIndex.W = urb->UrbControlDescriptorRequest.LanguageId;
   3.159 -      break;
   3.160 -    default:
   3.161 -      setup_packet->wIndex.W = 0;
   3.162 -      break;
   3.163 -    }
   3.164 -    setup_packet->wLength = (USHORT)urb->UrbControlDescriptorRequest.TransferBufferLength;
   3.165 -    status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbControlDescriptorRequest.TransferBuffer, urb->UrbControlDescriptorRequest.TransferBufferMDL, urb->UrbControlDescriptorRequest.TransferBufferLength);
   3.166 -    if (!NT_SUCCESS(status))
   3.167 -    {
   3.168 -      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   3.169 -    }
   3.170 -    break;
   3.171 -  case URB_FUNCTION_CLASS_INTERFACE:
   3.172 -    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_INTERFACE\n"));
   3.173 -    KdPrint((__DRIVER_NAME "      TransferFlags  = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   3.174 -    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.175 -    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.176 -    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.177 -    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.178 -    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.179 -    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.180 -    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.181 -
   3.182 +  case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
   3.183 +    FUNCTION_MSG("URB_FUNCTION_%04x\n", urb->UrbHeader.Function);
   3.184 +    FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
   3.185 +    FUNCTION_MSG(" Recipient = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
   3.186 +    FUNCTION_MSG(" Type = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type);
   3.187 +    FUNCTION_MSG(" Dir = %x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Dir);
   3.188 +    FUNCTION_MSG("bRequest = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bRequest);
   3.189 +    FUNCTION_MSG("wValue = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
   3.190 +    FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.LowByte);
   3.191 +    FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.HiByte);
   3.192 +    FUNCTION_MSG("wIndex = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex);
   3.193 +    FUNCTION_MSG(" Low = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte);
   3.194 +    FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
   3.195 +    FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
   3.196 +    FUNCTION_MSG("decode_data.transfer_flags = %08x\n", decode_data.transfer_flags);
   3.197 +    FUNCTION_MSG("*decode_data.length = %04x\n", *decode_data.length);
   3.198      shadow = get_shadow_from_freelist(xudd);
   3.199      shadow->request = request;
   3.200      shadow->urb = urb;
   3.201      shadow->callback = XenUsb_UrbCallback;
   3.202      shadow->req.id = shadow->id;
   3.203      shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   3.204 -    shadow->req.transfer_flags = 0;
   3.205 -    if (!(urb->UrbControlVendorClassRequest.TransferFlags & USBD_SHORT_TRANSFER_OK))
   3.206 +    shadow->req.transfer_flags = 0; 
   3.207 +    if (!(decode_data.transfer_flags & USBD_SHORT_TRANSFER_OK))
   3.208        shadow->req.transfer_flags |= LINUX_URB_SHORT_NOT_OK;
   3.209 -    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   3.210 -    setup_packet->bmRequestType.B = urb->UrbControlVendorClassRequest.RequestTypeReservedBits;
   3.211 -    if (urb->UrbControlVendorClassRequest.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   3.212 -    {      
   3.213 -      setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   3.214 +    if (decode_data.transfer_flags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   3.215        shadow->req.pipe |= LINUX_PIPE_DIRECTION_IN;
   3.216 -    }
   3.217      else
   3.218 -    {
   3.219 -      setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   3.220        shadow->req.pipe |= LINUX_PIPE_DIRECTION_OUT;
   3.221 -    }
   3.222 -    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
   3.223 -    setup_packet->bmRequestType.Type = BMREQUEST_CLASS;
   3.224 -    setup_packet->bRequest = urb->UrbControlVendorClassRequest.Request;
   3.225 -    setup_packet->wValue.W = urb->UrbControlVendorClassRequest.Value;
   3.226 -    setup_packet->wIndex.W = urb->UrbControlVendorClassRequest.Index;
   3.227 -    status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbControlVendorClassRequest.TransferBuffer, urb->UrbControlVendorClassRequest.TransferBufferMDL, urb->UrbControlVendorClassRequest.TransferBufferLength);
   3.228 -    if (!NT_SUCCESS(status))
   3.229 -    {
   3.230 +    memcpy(shadow->req.u.ctrl, decode_data.setup_packet.raw, 8);
   3.231 +    FUNCTION_MSG("req.pipe = %08x\n", shadow->req.pipe);
   3.232 +    FUNCTION_MSG("req.transfer_flags = %08x\n", shadow->req.transfer_flags);
   3.233 +    status = XenUsb_ExecuteRequest(xudd, shadow, decode_data.buffer, decode_data.mdl, *decode_data.length);
   3.234 +    if (!NT_SUCCESS(status)) {
   3.235        KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
   3.236      }
   3.237      break;
   3.238 -#if 0
   3.239 -  case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
   3.240 -    KdPrint((__DRIVER_NAME "     URB_FUNCTION_GET_STATUS_FROM_DEVICE\n"));
   3.241 -    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlGetStatusRequest.TransferBufferLength));
   3.242 -    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlGetStatusRequest.TransferBuffer));
   3.243 -    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlGetStatusRequest.TransferBufferMDL));
   3.244 -    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlGetStatusRequest.Index));
   3.245 -    if (urb->UrbControlGetStatusRequest.Index == 0)
   3.246 -    {
   3.247 -      urb->UrbControlGetStatusRequest.TransferBufferLength = 2;
   3.248 -      *(PUSHORT)urb->UrbControlGetStatusRequest.TransferBuffer = 0x0003;
   3.249 -      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.250 -      WdfRequestComplete(request, STATUS_SUCCESS);
   3.251 -    }
   3.252 -    else
   3.253 -    {
   3.254 -      KdPrint((__DRIVER_NAME "     Unknown Index\n"));
   3.255 -      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   3.256 -      WdfRequestComplete(request, STATUS_ACCESS_VIOLATION); //STATUS_UNSUCCESSFUL);
   3.257 -    }    
   3.258 -    break;
   3.259 -  case URB_FUNCTION_CLASS_DEVICE:
   3.260 -#if 1
   3.261 -    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_DEVICE\n"));
   3.262 -    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.263 -    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.264 -    KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.265 -    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.266 -    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.267 -    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.268 -    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.269 -#endif
   3.270 -    switch (urb->UrbControlVendorClassRequest.Request)
   3.271 -    {
   3.272 -    case USB_REQUEST_GET_DESCRIPTOR:
   3.273 -      KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_DEVICE\n"));
   3.274 -      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.275 -      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.276 -      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.277 -      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.278 -      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.279 -      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.280 -      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.281 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_DESCRIPTOR\n"));
   3.282 -      switch (urb->UrbControlVendorClassRequest.Value >> 8)
   3.283 -      {
   3.284 -      case 0x00:
   3.285 -#if 0      
   3.286 -        memcpy(urb->UrbControlVendorClassRequest.TransferBuffer, &usb_device->device_descriptor, sizeof(USB_DEVICE_DESCRIPTOR));
   3.287 -        urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
   3.288 -        urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.289 -        WdfRequestComplete(request, STATUS_SUCCESS);
   3.290 -        break;
   3.291 -#endif
   3.292 -      case 0x29: // Hub Descriptor
   3.293 -        KdPrint((__DRIVER_NAME "       HUB_DESCRIPTOR\n"));
   3.294 -        uhd = urb->UrbControlVendorClassRequest.TransferBuffer;
   3.295 -        urb->UrbControlVendorClassRequest.TransferBufferLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask[0]) + 2 + 1;
   3.296 -        uhd->bDescriptorLength = (UCHAR)urb->UrbControlVendorClassRequest.TransferBufferLength;
   3.297 -        uhd->bDescriptorType = 0x29;
   3.298 -        uhd->bNumberOfPorts = 8;
   3.299 -        uhd->wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
   3.300 -        uhd->bPowerOnToPowerGood = 1; // 2ms units
   3.301 -        uhd->bHubControlCurrent = 0;
   3.302 -        // DeviceRemovable bits (includes an extra bit at the start)
   3.303 -        uhd->bRemoveAndPowerMask[0] = 0;
   3.304 -        uhd->bRemoveAndPowerMask[1] = 0;
   3.305 -        // PortPwrCtrlMask
   3.306 -        uhd->bRemoveAndPowerMask[2] = 0xFF;
   3.307 -        urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.308 -        WdfRequestComplete(request, STATUS_SUCCESS);
   3.309 -        break;
   3.310 -      default:
   3.311 -        KdPrint((__DRIVER_NAME "       Unknown Value %02x\n", urb->UrbControlVendorClassRequest.Value >> 8));
   3.312 -        urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   3.313 -        WdfRequestComplete(request, STATUS_ACCESS_VIOLATION); //STATUS_UNSUCCESSFUL);
   3.314 -        break;
   3.315 -      }
   3.316 -      break;
   3.317 -    case USB_REQUEST_GET_STATUS:
   3.318 -      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   3.319 -      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.320 -      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.321 -      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.322 -      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.323 -      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.324 -      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.325 -      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.326 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_STATUS\n"));
   3.327 -      // Check that RequestTypeReservedBits == 0xA0
   3.328 -      KdPrint((__DRIVER_NAME "       GetHubStatus\n"));
   3.329 -      /* hub status */
   3.330 -      // shoud be able to get this field from somewhere else...
   3.331 -      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0x0000;
   3.332 -      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[1] = 0x0000; /* no change occurred */
   3.333 -      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.334 -      WdfRequestComplete(request, STATUS_SUCCESS);
   3.335 -      break;
   3.336 -    case USB_REQUEST_CLEAR_FEATURE:
   3.337 -      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   3.338 -      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.339 -      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.340 -      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.341 -      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.342 -      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.343 -      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.344 -      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.345 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_CLEAR_FEATURE\n"));
   3.346 -      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.347 -      WdfRequestComplete(request, STATUS_SUCCESS);
   3.348 -      break;
   3.349 -    default:
   3.350 -URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE      KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   3.351 -      KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.352 -      KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.353 -      KdPrint((__DRIVER_NAME "      TransferBufferMDL = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.354 -      KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.355 -      KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.356 -      KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.357 -      KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.358 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_%02x\n", urb->UrbControlVendorClassRequest.Request));
   3.359 -      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   3.360 -      WdfRequestComplete(request, STATUS_ACCESS_VIOLATION); //STATUS_UNSUCCESSFUL);
   3.361 -      break;
   3.362 -    }
   3.363 -#if 0
   3.364 -    shadow = get_shadow_from_freelist(xudd);
   3.365 -    shadow->request = request;
   3.366 -    shadow->urb = urb;
   3.367 -    shadow->callback = XenUsb_UrbCallback;
   3.368 -    shadow->req.id = shadow->id;
   3.369 -    shadow->req.pipe = PIPE_TYPE_CTRL | (1 << 8) | usb_device->port_number;
   3.370 -    if (urb->UrbControlVendorClassRequest.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   3.371 -      shadow->req.pipe |= PIPE_DIRECTION_IN;
   3.372 -#if 0
   3.373 -    if (urb->UrbControlVendorClassRequest.TransferFlags & USBD_SHORT_TRANSFER_OK)
   3.374 -      shadow->req.transfer_flags = ;
   3.375 -#endif
   3.376 -    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
   3.377 -    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
   3.378 -    setup_packet->bmRequestType.Type = BMREQUEST_CLASS;
   3.379 -    if (urb->UrbControlVendorClassRequest.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
   3.380 -      setup_packet->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
   3.381 -    else
   3.382 -      setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
   3.383 -    setup_packet->bmRequestType.B |= urb->UrbControlVendorClassRequest.RequestTypeReservedBits;
   3.384 -    setup_packet->bRequest = urb->UrbControlVendorClassRequest.Request;
   3.385 -    setup_packet->wValue.W = urb->UrbControlVendorClassRequest.Value;
   3.386 -    setup_packet->wIndex.W = urb->UrbControlVendorClassRequest.Index;
   3.387 -    setup_packet->wLength = shadow->req.buffer_lengthxxx;
   3.388 -    if (!urb->UrbControlVendorClassRequest.TransferBufferMDL)
   3.389 -    {
   3.390 -      mdl = IoAllocateMdl(urb->UrbControlVendorClassRequest.TransferBuffer, urb->UrbControlVendorClassRequest.TransferBufferLength, FALSE, FALSE, NULL);
   3.391 -      MmBuildMdlForNonPagedPool(mdl);
   3.392 -      shadow->mdl = mdl;
   3.393 -    }
   3.394 -    else
   3.395 -    {
   3.396 -      mdl = urb->UrbControlVendorClassRequest.TransferBufferMDL;
   3.397 -      shadow->mdl = NULL;
   3.398 -    }
   3.399 -    KdPrint((__DRIVER_NAME "     VA = %p\n", MmGetMdlVirtualAddress(mdl)));
   3.400 -    KdPrint((__DRIVER_NAME "     phys = %08x\n", MmGetPhysicalAddress(urb->UrbControlVendorClassRequest.TransferBuffer).LowPart));
   3.401 -    KdPrint((__DRIVER_NAME "     PFN[0] = %08x\n", MmGetMdlPfnArray(mdl)[0]));
   3.402 -
   3.403 -    status = WdfDmaTransactionCreate(xudd->dma_enabler, WDF_NO_OBJECT_ATTRIBUTES, &shadow->dma_transaction);
   3.404 -    if (!status)
   3.405 -    {
   3.406 -      KdPrint((__DRIVER_NAME "     WdfDmaTransactionCreate status = %08x\n", status));
   3.407 -    }
   3.408 -    status = WdfDmaTransactionInitialize(
   3.409 -      shadow->dma_transaction,
   3.410 -      XenUsb_FillShadowSegs,
   3.411 -      (shadow->req.pipe & PIPE_DIRECTION_IN)?WdfDmaDirectionReadFromDevice:WdfDmaDirectionWriteToDevice,
   3.412 -      mdl,
   3.413 -      MmGetMdlVirtualAddress(mdl),
   3.414 -      urb->UrbControlVendorClassRequest.TransferBufferLength);
   3.415 -    if (!status)
   3.416 -    {
   3.417 -      KdPrint((__DRIVER_NAME "     WdfDmaTransactionInitialize status = %08x\n", status));
   3.418 -    }
   3.419 -    status = WdfDmaTransactionExecute(shadow->dma_transaction, shadow);
   3.420 -    if (!status)
   3.421 -    {
   3.422 -      KdPrint((__DRIVER_NAME "     WdfDmaTransactionExecute status = %08x\n", status));
   3.423 -    }
   3.424 -#endif
   3.425 -    break;
   3.426 -  case URB_FUNCTION_CLASS_OTHER:
   3.427 -    KdPrint((__DRIVER_NAME "     URB_FUNCTION_CLASS_OTHER\n"));
   3.428 -    KdPrint((__DRIVER_NAME "      TransferFlags = %08x\n", urb->UrbControlVendorClassRequest.TransferFlags));
   3.429 -    KdPrint((__DRIVER_NAME "      TransferBufferLength = %d\n", urb->UrbControlVendorClassRequest.TransferBufferLength));
   3.430 -    KdPrint((__DRIVER_NAME "      TransferBuffer = %p\n", urb->UrbControlVendorClassRequest.TransferBuffer));
   3.431 -    KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", urb->UrbControlVendorClassRequest.TransferBufferMDL));
   3.432 -    KdPrint((__DRIVER_NAME "      RequestTypeReservedBits = %02x\n", urb->UrbControlVendorClassRequest.RequestTypeReservedBits));
   3.433 -    KdPrint((__DRIVER_NAME "      Request = %02x\n", urb->UrbControlVendorClassRequest.Request));
   3.434 -    KdPrint((__DRIVER_NAME "      Value = %04x\n", urb->UrbControlVendorClassRequest.Value));
   3.435 -    KdPrint((__DRIVER_NAME "      Index = %04x\n", urb->UrbControlVendorClassRequest.Index));
   3.436 -    switch (urb->UrbControlVendorClassRequest.Request)
   3.437 -    {
   3.438 -    case USB_REQUEST_GET_STATUS:
   3.439 -      /* port status - 11.24.2.7.1 */
   3.440 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_GET_STATUS\n"));
   3.441 -      KdPrint((__DRIVER_NAME "       GetHubStatus\n"));
   3.442 -      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[0] = xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status;
   3.443 -      ((PUSHORT)urb->UrbControlVendorClassRequest.TransferBuffer)[1] = xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change;
   3.444 -      break;
   3.445 -    case USB_REQUEST_SET_FEATURE:
   3.446 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_SET_FEATURE\n"));
   3.447 -      KdPrint((__DRIVER_NAME "       SetPortFeature\n"));
   3.448 -      switch (urb->UrbControlVendorClassRequest.Value)
   3.449 -      {
   3.450 -      case PORT_ENABLE:
   3.451 -        KdPrint((__DRIVER_NAME "        PORT_ENABLE\n"));
   3.452 -        /* do something here */
   3.453 -        break;
   3.454 -      case PORT_RESET:
   3.455 -        KdPrint((__DRIVER_NAME "        PORT_RESET\n"));
   3.456 -        /* just fake the reset */
   3.457 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change |= (1 << PORT_RESET);
   3.458 -        break;
   3.459 -      default:
   3.460 -        KdPrint((__DRIVER_NAME "        Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value));
   3.461 -        break;
   3.462 -      }
   3.463 -      KdPrint((__DRIVER_NAME "        status = %04x, change = %04x\n",
   3.464 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   3.465 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   3.466 -      break;
   3.467 -    case USB_REQUEST_CLEAR_FEATURE:
   3.468 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_CLEAR_FEATURE\n"));
   3.469 -      KdPrint((__DRIVER_NAME "       ClearPortFeature\n"));
   3.470 -      switch (urb->UrbControlVendorClassRequest.Value)
   3.471 -      {
   3.472 -      case C_PORT_CONNECTION:
   3.473 -        KdPrint((__DRIVER_NAME "        C_PORT_CONNECTION\n"));
   3.474 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change &= ~(1 << PORT_CONNECTION);
   3.475 -        break;
   3.476 -      case C_PORT_RESET:
   3.477 -        KdPrint((__DRIVER_NAME "        C_PORT_RESET\n"));
   3.478 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change &= ~(1 << PORT_RESET);
   3.479 -        break;
   3.480 -      default:
   3.481 -        KdPrint((__DRIVER_NAME "        Unknown Value %04X\n", urb->UrbControlVendorClassRequest.Value));
   3.482 -        break;
   3.483 -      }
   3.484 -      KdPrint((__DRIVER_NAME "        status = %04x, change = %04x\n",
   3.485 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   3.486 -        xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   3.487 -      break;
   3.488 -    default:
   3.489 -      KdPrint((__DRIVER_NAME "      USB_REQUEST_%02x\n", urb->UrbControlVendorClassRequest.Request));
   3.490 -      break;
   3.491 -    }
   3.492 -    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.493 -    WdfRequestComplete(request, STATUS_SUCCESS);
   3.494 -    //urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
   3.495 -    //WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   3.496 -    break;
   3.497 -#endif
   3.498    case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
   3.499      endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;    
   3.500      KdPrint((__DRIVER_NAME "      pipe_handle = %p\n", endpoint));
   3.501 @@ -753,6 +464,7 @@ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 
   3.502      shadow->req.id = shadow->id;
   3.503      shadow->req.pipe = endpoint->pipe_value;
   3.504      shadow->req.transfer_flags = 0;
   3.505 +    shadow->req.u.intr.interval = endpoint->endpoint_descriptor.bInterval; /* check this... maybe there is some overridden value that should be used? */
   3.506      if (!(urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK) && (endpoint->pipe_value & LINUX_PIPE_DIRECTION_IN))
   3.507        shadow->req.transfer_flags |= LINUX_URB_SHORT_NOT_OK;
   3.508      switch(endpoint->endpoint_descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK)
   3.509 @@ -767,7 +479,9 @@ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 
   3.510        KdPrint((__DRIVER_NAME "      USB_ENDPOINT_TYPE_%d\n", endpoint->endpoint_descriptor.bmAttributes));
   3.511        break;
   3.512      }
   3.513 +
   3.514      FUNCTION_MSG("endpoint address = %02x\n", endpoint->endpoint_descriptor.bEndpointAddress);
   3.515 +    FUNCTION_MSG("endpoint interval = %02x\n", endpoint->endpoint_descriptor.bInterval);
   3.516      FUNCTION_MSG("pipe_direction_bit = %08x\n", endpoint->pipe_value & LINUX_PIPE_DIRECTION_IN);
   3.517      FUNCTION_MSG("short_ok_bit = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK);
   3.518      FUNCTION_MSG("flags_direction_bit = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN);
   3.519 @@ -786,7 +500,6 @@ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 
   3.520      shadow->request = request;
   3.521      shadow->urb = urb;
   3.522      shadow->mdl = NULL;
   3.523 -    //shadow->dma_transaction = NULL;
   3.524      shadow->callback = XenUsb_UrbCallback;
   3.525      shadow->req.id = shadow->id;
   3.526      shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
   3.527 @@ -808,6 +521,9 @@ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 
   3.528    case URB_FUNCTION_ABORT_PIPE:
   3.529      KdPrint((__DRIVER_NAME "     URB_FUNCTION_ABORT_PIPE\n"));
   3.530      KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
   3.531 +    /* just fake this.... i think we really need to flush any pending requests too */
   3.532 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   3.533 +    WdfRequestComplete(request, STATUS_SUCCESS);
   3.534      break;
   3.535    default:
   3.536      KdPrint((__DRIVER_NAME "     URB_FUNCTION_%04x\n", urb->UrbHeader.Function));
     4.1 --- a/xenusb/xenusb_fdo.c	Fri Dec 30 21:05:57 2011 +1100
     4.2 +++ b/xenusb/xenusb_fdo.c	Tue Jan 10 12:10:51 2012 +1100
     4.3 @@ -262,19 +262,20 @@ XenUsb_HandleEvent(PVOID context)
     4.4        KdPrint((__DRIVER_NAME "     conn_rsp->speed = %d\n", conn_rsp->speed));
     4.5        
     4.6        xudd->ports[conn_rsp->portnum - 1].port_type = conn_rsp->speed;
     4.7 +      xudd->ports[conn_rsp->portnum - 1].port_status &= ~((1 << PORT_LOW_SPEED) | (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION));
     4.8        switch (conn_rsp->speed)
     4.9        {
    4.10        case USB_PORT_TYPE_NOT_CONNECTED:
    4.11 -        xudd->ports[conn_rsp->portnum - 1].port_status = 0; //(1 << PORT_ENABLE);
    4.12 +        //xudd->ports[conn_rsp->portnum - 1].port_status |= 0;
    4.13          break;
    4.14        case USB_PORT_TYPE_LOW_SPEED:
    4.15 -        xudd->ports[conn_rsp->portnum - 1].port_status = (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION); // | (1 << PORT_ENABLE);
    4.16 +        xudd->ports[conn_rsp->portnum - 1].port_status |= (1 << PORT_LOW_SPEED) | (1 << PORT_CONNECTION);
    4.17          break;
    4.18        case USB_PORT_TYPE_FULL_SPEED:
    4.19 -        xudd->ports[conn_rsp->portnum - 1].port_status = (1 << PORT_CONNECTION); // | (1 << PORT_ENABLE);
    4.20 +        xudd->ports[conn_rsp->portnum - 1].port_status |= (1 << PORT_CONNECTION);
    4.21          break;
    4.22        case USB_PORT_TYPE_HIGH_SPEED:
    4.23 -        xudd->ports[conn_rsp->portnum - 1].port_status = (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION); // | (1 << PORT_ENABLE);
    4.24 +        xudd->ports[conn_rsp->portnum - 1].port_status |= (1 << PORT_HIGH_SPEED) | (1 << PORT_CONNECTION);
    4.25          break;
    4.26        }      
    4.27        xudd->ports[conn_rsp->portnum - 1].port_change |= (1 << PORT_CONNECTION);
    4.28 @@ -791,7 +792,7 @@ XenUsb_EvtIoDeviceControl(
    4.29          if (output_buffer_length >= FIELD_OFFSET(USB_NODE_INFORMATION, u.HubInformation.HubDescriptor.bRemoveAndPowerMask) + 3)
    4.30          {
    4.31            uni->u.HubInformation.HubDescriptor.bDescriptorType = 0x29;
    4.32 -          uni->u.HubInformation.HubDescriptor.bNumberOfPorts = 8;
    4.33 +          uni->u.HubInformation.HubDescriptor.bNumberOfPorts = xudd->num_ports;
    4.34            uni->u.HubInformation.HubDescriptor.wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
    4.35            uni->u.HubInformation.HubDescriptor.bPowerOnToPowerGood = 1; // 2ms units
    4.36            uni->u.HubInformation.HubDescriptor.bHubControlCurrent = 0;
     5.1 --- a/xenusb/xenusb_hub.c	Fri Dec 30 21:05:57 2011 +1100
     5.2 +++ b/xenusb/xenusb_hub.c	Tue Jan 10 12:10:51 2012 +1100
     5.3 @@ -256,11 +256,15 @@ XenUsbHub_EvtIoInternalDeviceControl(
     5.4      break;
     5.5  #if (NTDDI_VERSION >= NTDDI_VISTA)
     5.6    case IOCTL_INTERNAL_USB_GET_HUB_NAME:
     5.7 -    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_HUB_NAME\n"));
     5.8 -    status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhn, &length);
     5.9 -    uhn->ActualLength = sizeof(USB_HUB_NAME);
    5.10 -    uhn->HubName[0] = 0;
    5.11 -    status = STATUS_SUCCESS;
    5.12 +    KdPrint((__DRIVER_NAME "     IOCTL_INTERNAL_USB_GET_HUB_NAME (hub)\n"));
    5.13 +    status = WdfRequestRetrieveOutputBuffer(request, FIELD_OFFSET(USB_HUB_NAME, HubName) + 18, (PVOID *)&uhn, &length);
    5.14 +    if (NT_SUCCESS(status))
    5.15 +    {
    5.16 +      /* not sure this is correct... it's not the full symbolic name */
    5.17 +      uhn->ActualLength = sizeof(USB_HUB_NAME);
    5.18 +      RtlStringCbCopyW(uhn->HubName, length - FIELD_OFFSET(USB_HUB_NAME, HubName), L"ROOT_HUB");
    5.19 +      status = STATUS_SUCCESS;
    5.20 +    }
    5.21      break;
    5.22  #endif
    5.23    case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
    5.24 @@ -342,10 +346,12 @@ XenUsbHub_EvtIoInternalDeviceControl(
    5.25      FUNCTION_MSG(" NtStatus = %08x\n", usfd->NtStatus);
    5.26      FUNCTION_MSG(" UsbdStatus = %08x\n", usfd->UsbdStatus);
    5.27      FUNCTION_MSG(" ConnectStatus = %08x\n", usfd->ConnectStatus);
    5.28 +#if 0
    5.29      FUNCTION_MSG(" DriverData[0] = %s\n", usfd->DriverData);
    5.30      FUNCTION_MSG(" DriverData[0] = %S\n", usfd->DriverData);
    5.31      FUNCTION_MSG(" DriverData[5] = %s\n", &usfd->DriverData[5]);
    5.32      FUNCTION_MSG(" DriverData[5] = %S\n", &usfd->DriverData[5]);
    5.33 +#endif
    5.34      status = STATUS_SUCCESS;
    5.35      break;  
    5.36  #endif
    5.37 @@ -718,6 +724,8 @@ XenUsbHub_UBIH_InitializeUsbDevice(
    5.38      usb_device->configs[i] = ExAllocatePoolWithTag(NonPagedPool, sizeof(xenusb_config_t) + sizeof(PVOID) * config_descriptor->bNumInterfaces, XENUSB_POOL_TAG);
    5.39      usb_device->configs[i]->device = usb_device;
    5.40      memcpy(&usb_device->configs[i]->config_descriptor, config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
    5.41 +    usb_device->configs[i]->config_descriptor_all = ExAllocatePoolWithTag(NonPagedPool, config_descriptor->wTotalLength, XENUSB_POOL_TAG);
    5.42 +    memcpy(usb_device->configs[i]->config_descriptor_all, config_descriptor, config_descriptor->wTotalLength);
    5.43      ptr += config_descriptor->bLength;
    5.44      j = 0;
    5.45      while (j < config_descriptor->bNumInterfaces)
    5.46 @@ -832,11 +840,13 @@ XenUsbHub_UBIH_GetUsbDescriptors(
    5.47    
    5.48    usb_config = usb_device->active_config;
    5.49    ptr = ConfigDescriptorBuffer;
    5.50 -  KdPrint((__DRIVER_NAME "     memcpy(%p, %p, %d)\n", ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)));
    5.51 -  memcpy(ptr, &usb_config->config_descriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
    5.52 +  memcpy(ptr, usb_config->config_descriptor_all, min(usb_config->config_descriptor.wTotalLength, *ConfigDescriptorBufferLength));
    5.53 +  *ConfigDescriptorBufferLength = ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
    5.54 +
    5.55 +#if 0
    5.56    ptr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
    5.57 -  ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += 1;
    5.58 -#if 0
    5.59 +  // why was this here? ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += 1;
    5.60 +
    5.61    for (i = 0; i < usb_config->config_descriptor.bNumInterfaces; i++)
    5.62    {
    5.63      memcpy(ptr, &usb_config->interfaces[i]->interface_descriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
    5.64 @@ -849,9 +859,9 @@ XenUsbHub_UBIH_GetUsbDescriptors(
    5.65        ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength += sizeof(USB_ENDPOINT_DESCRIPTOR);
    5.66      }
    5.67    }
    5.68 +  *ConfigDescriptorBufferLength = ((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
    5.69  #endif
    5.70 -  *ConfigDescriptorBufferLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); //((PUSB_CONFIGURATION_DESCRIPTOR)ConfigDescriptorBuffer)->wTotalLength;
    5.71 -  
    5.72 +
    5.73    FUNCTION_EXIT();
    5.74    return status;
    5.75  }
    5.76 @@ -1207,6 +1217,35 @@ XenUsbHub_UBIH_CreateUsbDeviceEx(
    5.77    return status;
    5.78  }
    5.79  
    5.80 +#if (NTDDI_VERSION >= NTDDI_VISTA)  
    5.81 +static NTSTATUS
    5.82 +XenUsbHub_UBIH_CreateUsbDeviceV7(
    5.83 +    PVOID BusContext,
    5.84 +    PUSB_DEVICE_HANDLE *NewDeviceHandle,
    5.85 +    PUSB_DEVICE_HANDLE HsHubDeviceHandle,
    5.86 +    USHORT PortStatus,
    5.87 +    PUSB_PORT_PATH PortPath,
    5.88 +    PUSB_CD_ERROR_INFORMATION CdErrorInfo,
    5.89 +    USHORT TtPortNumber,
    5.90 +    PDEVICE_OBJECT PdoDeviceObject,
    5.91 +    PUNICODE_STRING PhysicalDeviceObjectName)
    5.92 +{
    5.93 +  NTSTATUS status;
    5.94 +  
    5.95 +  UNREFERENCED_PARAMETER(PdoDeviceObject);
    5.96 +  UNREFERENCED_PARAMETER(PhysicalDeviceObjectName);
    5.97 +  
    5.98 +  FUNCTION_ENTER();
    5.99 +  KdPrint((__DRIVER_NAME "     PortPath->PortPathDepth = %d\n", PortPath->PortPathDepth));
   5.100 +  KdPrint((__DRIVER_NAME "     PortPath->PortPath[%d] = %d\n", PortPath->PortPathDepth - 1));
   5.101 +  status = XenUsbHub_UBIH_CreateUsbDeviceEx(BusContext, NewDeviceHandle, &HsHubDeviceHandle, PortStatus, (USHORT)PortPath->PortPath[PortPath->PortPathDepth-1], CdErrorInfo, TtPortNumber);
   5.102 +  KdPrint((__DRIVER_NAME "     PdoDeviceObject = %p\n", PdoDeviceObject));
   5.103 +  KdPrint((__DRIVER_NAME "     PhysicalDeviceObjectName = %S\n", PhysicalDeviceObjectName->Buffer));
   5.104 +  FUNCTION_EXIT();
   5.105 +  return status;
   5.106 +}
   5.107 +#endif
   5.108 +
   5.109  static NTSTATUS
   5.110  XenUsbHub_UBIH_InitializeUsbDeviceEx(
   5.111   PVOID BusContext,
   5.112 @@ -1379,8 +1418,9 @@ XenUsbHub_UBIH_RefDeviceHandle(
   5.113    UNREFERENCED_PARAMETER(Object);
   5.114    UNREFERENCED_PARAMETER(Tag);
   5.115    FUNCTION_ENTER();
   5.116 +  FUNCTION_MSG("This should do something\n");
   5.117    FUNCTION_EXIT();
   5.118 -  return STATUS_UNSUCCESSFUL;
   5.119 +  return STATUS_SUCCESS;
   5.120  }
   5.121  
   5.122  static NTSTATUS
   5.123 @@ -1415,32 +1455,6 @@ XenUsbHub_UBIH_SetDeviceHandleIdleReadyS
   5.124  }
   5.125  
   5.126  static NTSTATUS
   5.127 -XenUsbHub_UBIH_CreateUsbDeviceV7(
   5.128 -    PVOID BusContext,
   5.129 -    PUSB_DEVICE_HANDLE *NewDeviceHandle,
   5.130 -    PUSB_DEVICE_HANDLE HsHubDeviceHandle,
   5.131 -    USHORT PortStatus,
   5.132 -    PUSB_PORT_PATH PortPath,
   5.133 -    PUSB_CD_ERROR_INFORMATION CdErrorInfo,
   5.134 -    USHORT TtPortNumber,
   5.135 -    PDEVICE_OBJECT PdoDeviceObject,
   5.136 -    PUNICODE_STRING PhysicalDeviceObjectName)
   5.137 -{
   5.138 -  UNREFERENCED_PARAMETER(BusContext);
   5.139 -  UNREFERENCED_PARAMETER(NewDeviceHandle);
   5.140 -  UNREFERENCED_PARAMETER(HsHubDeviceHandle);
   5.141 -  UNREFERENCED_PARAMETER(PortStatus);
   5.142 -  UNREFERENCED_PARAMETER(PortPath);
   5.143 -  UNREFERENCED_PARAMETER(CdErrorInfo);
   5.144 -  UNREFERENCED_PARAMETER(TtPortNumber);
   5.145 -  UNREFERENCED_PARAMETER(PdoDeviceObject);
   5.146 -  UNREFERENCED_PARAMETER(PhysicalDeviceObjectName);
   5.147 -  FUNCTION_ENTER();
   5.148 -  FUNCTION_EXIT();
   5.149 -  return STATUS_UNSUCCESSFUL;
   5.150 -}
   5.151 -
   5.152 -static NTSTATUS
   5.153  XenUsbHub_UBIH_GetContainerIdForPort(
   5.154    PVOID BusContext,
   5.155    USHORT PortNumber,
   5.156 @@ -1477,7 +1491,7 @@ XenUsbHub_UBIH_AbortAllDevicePipes(
   5.157    UNREFERENCED_PARAMETER(DeviceHandle);
   5.158    FUNCTION_ENTER();
   5.159    FUNCTION_EXIT();
   5.160 -  return STATUS_UNSUCCESSFUL;
   5.161 +  return STATUS_SUCCESS;
   5.162  }
   5.163  
   5.164  static VOID
   5.165 @@ -1525,9 +1539,9 @@ XenUsbHub_UBIU_QueryBusTime(
   5.166    UNREFERENCED_PARAMETER(BusContext);
   5.167    UNREFERENCED_PARAMETER(CurrentFrame);
   5.168    
   5.169 -  FUNCTION_ENTER();
   5.170 +  //FUNCTION_ENTER();
   5.171    *CurrentFrame = frame_no++;
   5.172 -  FUNCTION_EXIT();
   5.173 +  //FUNCTION_EXIT();
   5.174    return status;
   5.175  }
   5.176  
   5.177 @@ -1651,7 +1665,7 @@ XenUsbHub_UBIHSS_SuspendHub(
   5.178    UNREFERENCED_PARAMETER(BusContext);
   5.179    FUNCTION_ENTER();
   5.180    FUNCTION_EXIT();
   5.181 -  return STATUS_UNSUCCESSFUL;
   5.182 +  return STATUS_SUCCESS;
   5.183  }
   5.184  
   5.185  static NTSTATUS
   5.186 @@ -1661,7 +1675,7 @@ XenUsbHub_UBIHSS_ResumeHub(
   5.187    UNREFERENCED_PARAMETER(BusContext);
   5.188    FUNCTION_ENTER();
   5.189    FUNCTION_EXIT();
   5.190 -  return STATUS_UNSUCCESSFUL;
   5.191 +  return STATUS_SUCCESS;
   5.192  }
   5.193  
   5.194  VOID
   5.195 @@ -1705,13 +1719,14 @@ XenUsbHub_ProcessHubInterruptEvent(xenus
   5.196  
   5.197    for (i = 0; i < xudd->num_ports; i++)
   5.198    {
   5.199 -    if (xudd->ports[i].port_change)
   5.200 -    {
   5.201 +FUNCTION_MSG("port %d - status = %04x, change = %04x\n", xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
   5.202 +    if (xudd->ports[i].port_change) {
   5.203        FUNCTION_MSG("Port change on port %d - status = %04x, change = %04x\n",
   5.204          xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
   5.205        ((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[xudd->ports[i].port_number >> 3] |= 1 << (xudd->ports[i].port_number & 7);
   5.206        port_change_flag = TRUE;
   5.207      }
   5.208 +FUNCTION_MSG("port %d - status = %04x, change = %04x\n", xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
   5.209    }
   5.210    WdfSpinLockRelease(endpoint->lock);
   5.211    if (port_change_flag)
   5.212 @@ -1783,19 +1798,6 @@ XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY
   5.213          ubih->ubih7.RefDeviceHandle = XenUsbHub_UBIH_RefDeviceHandle;
   5.214          ubih->ubih7.DerefDeviceHandle = XenUsbHub_UBIH_DerefDeviceHandle;
   5.215          ubih->ubih7.SetDeviceHandleIdleReadyState = XenUsbHub_UBIH_SetDeviceHandleIdleReadyState;
   5.216 -        ubih->ubih7.HubIsRoot = XenUsbHub_UBIH_HubIsRoot;
   5.217 -        ubih->ubih7.AcquireBusSemaphore = XenUsbHub_UBIH_AcquireBusSemaphore;
   5.218 -        ubih->ubih7.ReleaseBusSemaphore = XenUsbHub_UBIH_ReleaseBusSemaphore;
   5.219 -        ubih->ubih7.CaculatePipeBandwidth = XenUsbHub_UBIH_CaculatePipeBandwidth;
   5.220 -        ubih->ubih7.SetBusSystemWakeMode = XenUsbHub_UBIH_SetBusSystemWakeMode;
   5.221 -        ubih->ubih7.SetDeviceFlag = XenUsbHub_UBIH_SetDeviceFlag;
   5.222 -        ubih->ubih7.HubTestPoint = XenUsbHub_UBIH_HubTestPoint;
   5.223 -        ubih->ubih7.GetDevicePerformanceInfo = XenUsbHub_UBIH_GetDevicePerformanceInfo;
   5.224 -        ubih->ubih7.WaitAsyncPowerUp = XenUsbHub_UBIH_WaitAsyncPowerUp;
   5.225 -        ubih->ubih7.GetDeviceAddress = XenUsbHub_UBIH_GetDeviceAddress;
   5.226 -        ubih->ubih7.RefDeviceHandle = XenUsbHub_UBIH_RefDeviceHandle;
   5.227 -        ubih->ubih7.DerefDeviceHandle = XenUsbHub_UBIH_DerefDeviceHandle;
   5.228 -        ubih->ubih7.SetDeviceHandleIdleReadyState = XenUsbHub_UBIH_SetDeviceHandleIdleReadyState;
   5.229          ubih->ubih7.CreateUsbDeviceV7 = XenUsbHub_UBIH_CreateUsbDeviceV7;
   5.230          ubih->ubih7.GetContainerIdForPort = XenUsbHub_UBIH_GetContainerIdForPort;
   5.231          ubih->ubih7.SetContainerIdForPort = XenUsbHub_UBIH_SetContainerIdForPort;
   5.232 @@ -1918,6 +1920,16 @@ XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY
   5.233  }
   5.234  
   5.235  NTSTATUS
   5.236 +XenUsbHub_PLI_GetLocationString(PVOID context, PWCHAR *location_strings) {
   5.237 +  UNREFERENCED_PARAMETER(context);
   5.238 +  
   5.239 +  FUNCTION_ENTER();
   5.240 +  *location_strings = L"james\0";
   5.241 +  FUNCTION_EXIT();
   5.242 +  return STATUS_SUCCESS;
   5.243 +}
   5.244 +
   5.245 +NTSTATUS
   5.246  XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list,
   5.247    PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header,
   5.248    PWDFDEVICE_INIT child_init)
   5.249 @@ -1937,8 +1949,11 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   5.250    WDF_IO_QUEUE_CONFIG queue_config;
   5.251  #if (NTDDI_VERSION >= NTDDI_VISTA)
   5.252    WDF_QUERY_INTERFACE_CONFIG interface_config;
   5.253 +#if 0
   5.254    USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND ubihss;
   5.255  #endif
   5.256 +  PNP_LOCATION_INTERFACE pli;
   5.257 +#endif
   5.258    UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
   5.259  
   5.260    FUNCTION_ENTER();
   5.261 @@ -2126,6 +2141,7 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   5.262    WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities);  
   5.263  
   5.264  #if (NTDDI_VERSION >= NTDDI_VISTA)
   5.265 +#if 0
   5.266    ubihss.BusContext = child_device;
   5.267    ubihss.Size = sizeof(USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND);
   5.268    ubihss.Version = USB_BUSIF_HUB_SS_VERSION_0;
   5.269 @@ -2138,6 +2154,17 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   5.270    if (!NT_SUCCESS(status))
   5.271      return status;
   5.272  #endif
   5.273 +  pli.Size = sizeof(USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND);
   5.274 +  pli.Version = 1;
   5.275 +  pli.Context = child_device;
   5.276 +  pli.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   5.277 +  pli.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   5.278 +  pli.GetLocationString = XenUsbHub_PLI_GetLocationString;
   5.279 +  WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&pli, &GUID_PNP_LOCATION_INTERFACE, NULL);
   5.280 +  status = WdfDeviceAddQueryInterface(child_device, &interface_config);
   5.281 +  if (!NT_SUCCESS(status))
   5.282 +    return status;  
   5.283 +#endif
   5.284  
   5.285    status = WdfDeviceCreateDeviceInterface(child_device, &GUID_DEVINTERFACE_USB_HUB, NULL);
   5.286    if (!NT_SUCCESS(status))
     6.1 --- a/xenusb/xenusb_huburb.c	Fri Dec 30 21:05:57 2011 +1100
     6.2 +++ b/xenusb/xenusb_huburb.c	Tue Jan 10 12:10:51 2012 +1100
     6.3 @@ -68,7 +68,7 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
     6.4    decode_retval = XenUsb_DecodeControlUrb(urb, &decode_data);
     6.5    if (decode_retval == URB_DECODE_UNKNOWN)
     6.6    {
     6.7 -    FUNCTION_MSG("Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL); //STATUS_UNSUCCESSFUL));
     6.8 +    FUNCTION_MSG("Unknown URB - Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL); //STATUS_UNSUCCESSFUL));
     6.9      urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
    6.10      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
    6.11      return;
    6.12 @@ -76,7 +76,6 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.13  
    6.14    urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
    6.15    
    6.16 -#if 0
    6.17    if (decode_retval != URB_DECODE_NOT_CONTROL)
    6.18    {
    6.19      FUNCTION_MSG("bmRequestType = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.B);
    6.20 @@ -92,7 +91,6 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.21      FUNCTION_MSG(" High = %02x\n", decode_data.setup_packet.default_pipe_setup_packet.wIndex.HiByte);
    6.22      FUNCTION_MSG("wLength = %04x\n", decode_data.setup_packet.default_pipe_setup_packet.wLength);
    6.23    }
    6.24 -#endif
    6.25    
    6.26    switch(urb->UrbHeader.Function)
    6.27    {
    6.28 @@ -186,7 +184,9 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.29    case URB_FUNCTION_CONTROL_TRANSFER:
    6.30    case URB_FUNCTION_CLASS_DEVICE:
    6.31    case URB_FUNCTION_CLASS_OTHER:
    6.32 +  case URB_FUNCTION_CLASS_INTERFACE:
    6.33    case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
    6.34 +  case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
    6.35    case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
    6.36      switch(decode_data.setup_packet.default_pipe_setup_packet.bRequest)
    6.37      {
    6.38 @@ -301,7 +301,7 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.39          *decode_data.length = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask[0]) + 2 + 1;
    6.40          uhd->bDescriptorLength = (UCHAR)*decode_data.length;
    6.41          uhd->bDescriptorType = 0x29;
    6.42 -        uhd->bNumberOfPorts = 8;
    6.43 +        uhd->bNumberOfPorts = (UCHAR)xudd->num_ports;
    6.44          uhd->wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
    6.45          uhd->bPowerOnToPowerGood = 1; // 2ms units
    6.46          uhd->bHubControlCurrent = 0;
    6.47 @@ -335,7 +335,28 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.48        switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type)
    6.49        {
    6.50        case BMREQUEST_STANDARD: /* Standard */
    6.51 -        KdPrint((__DRIVER_NAME "       Type=Standard (unsupported)\n"));
    6.52 +        KdPrint((__DRIVER_NAME "       Type=Standard\n"));
    6.53 +        switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
    6.54 +        {
    6.55 +        case BMREQUEST_TO_DEVICE:
    6.56 +          KdPrint((__DRIVER_NAME "       Recipient=Device\n"));
    6.57 +          switch (decode_data.setup_packet.default_pipe_setup_packet.wValue.W)
    6.58 +          {
    6.59 +          case 1: /* DEVICE_REMOTE_WAKEUP */
    6.60 +            KdPrint((__DRIVER_NAME "       Feature=DEVICE_REMOTE_WAKEUP\n"));
    6.61 +            /* fake this */
    6.62 +            urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
    6.63 +            break;
    6.64 +          default:
    6.65 +            FUNCTION_MSG(__DRIVER_NAME "       Feature=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
    6.66 +            break;
    6.67 +          }
    6.68 +          break;
    6.69 +        default:
    6.70 +          FUNCTION_MSG(__DRIVER_NAME "       Recipient=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
    6.71 +          break;
    6.72 +        }
    6.73 +        break;
    6.74          break;
    6.75        case BMREQUEST_CLASS: /* Class */
    6.76          KdPrint((__DRIVER_NAME "       Type=Class\n"));
    6.77 @@ -350,6 +371,11 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.78              xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status &= ~(1 << PORT_ENABLE);
    6.79              urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
    6.80              break;
    6.81 +          case PORT_SUSPEND:
    6.82 +            KdPrint((__DRIVER_NAME "        PORT_SUSPEND (NOOP)\n"));
    6.83 +            /* do something here */
    6.84 +            urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
    6.85 +            break;
    6.86            case C_PORT_CONNECTION:
    6.87              KdPrint((__DRIVER_NAME "        C_PORT_CONNECTION\n"));
    6.88              xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change &= ~(1 << PORT_CONNECTION);
    6.89 @@ -384,7 +410,27 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    6.90        switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Type)
    6.91        {
    6.92        case 0: /* Standard */
    6.93 -        KdPrint((__DRIVER_NAME "       Type=Standard (unsupported)\n"));
    6.94 +        KdPrint((__DRIVER_NAME "       Type=Standard\n"));
    6.95 +        switch (decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient)
    6.96 +        {
    6.97 +        case BMREQUEST_TO_DEVICE:
    6.98 +          KdPrint((__DRIVER_NAME "       Recipient=Device\n"));
    6.99 +          switch (decode_data.setup_packet.default_pipe_setup_packet.wValue.W)
   6.100 +          {
   6.101 +          case 1: /* DEVICE_REMOTE_WAKEUP */
   6.102 +            KdPrint((__DRIVER_NAME "       Feature=DEVICE_REMOTE_WAKEUP\n"));
   6.103 +            /* fake this */
   6.104 +            urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   6.105 +            break;
   6.106 +          default:
   6.107 +            FUNCTION_MSG(__DRIVER_NAME "       Feature=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.wValue.W);
   6.108 +            break;
   6.109 +          }
   6.110 +          break;
   6.111 +        default:
   6.112 +          FUNCTION_MSG(__DRIVER_NAME "       Recipient=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
   6.113 +          break;
   6.114 +        }
   6.115          break;
   6.116        case 1: /* Class */
   6.117          KdPrint((__DRIVER_NAME "       Type=Class\n"));
   6.118 @@ -399,10 +445,15 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
   6.119              /* do something here */
   6.120              urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   6.121              break;
   6.122 +          case PORT_SUSPEND:
   6.123 +            KdPrint((__DRIVER_NAME "        PORT_SUSPEND (NOOP)\n"));
   6.124 +            /* do something here */
   6.125 +            urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   6.126 +            break;
   6.127            case PORT_RESET:
   6.128              KdPrint((__DRIVER_NAME "        PORT_RESET\n"));
   6.129              /* just fake the reset by setting the status bit to indicate that the reset is complete*/
   6.130 -            xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status |= (1 << PORT_RESET);
   6.131 +            //xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status |= (1 << PORT_RESET);
   6.132              //xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].reset_counter = 10;
   6.133              // TODO: maybe fake a 10ms time here...
   6.134              xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status &= ~(1 << PORT_RESET);
   6.135 @@ -425,6 +476,9 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
   6.136              xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_status,
   6.137              xudd->ports[urb->UrbControlVendorClassRequest.Index - 1].port_change));
   6.138            break;
   6.139 +        default:
   6.140 +          FUNCTION_MSG(__DRIVER_NAME "       Recipient=%d (not valid)\n", decode_data.setup_packet.default_pipe_setup_packet.bmRequestType.Recipient);
   6.141 +          break;
   6.142          }
   6.143          break;
   6.144        }
   6.145 @@ -440,6 +494,11 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
   6.146      KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
   6.147      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   6.148      break;
   6.149 +  case URB_FUNCTION_ABORT_PIPE:
   6.150 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_ABORT_PIPE\n"));
   6.151 +    KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
   6.152 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   6.153 +    break;
   6.154    case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
   6.155  #if 0
   6.156      KdPrint((__DRIVER_NAME "     URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n"));
   6.157 @@ -575,7 +634,7 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
   6.158          urb->UrbControlVendorClassRequest.TransferBufferLength = FIELD_OFFSET(USB_HUB_DESCRIPTOR, bRemoveAndPowerMask[0]) + 2 + 1;
   6.159          uhd->bDescriptorLength = (UCHAR)urb->UrbControlVendorClassRequest.TransferBufferLength;
   6.160          uhd->bDescriptorType = 0x29;
   6.161 -        uhd->bNumberOfPorts = 8;
   6.162 +        uhd->bNumberOfPorts = xudd->num_ports;
   6.163          uhd->wHubCharacteristics = 0x0012; // no power switching no overcurrent protection
   6.164          uhd->bPowerOnToPowerGood = 1; // 2ms units
   6.165          uhd->bHubControlCurrent = 0;