win-pvdrivers

changeset 931:b655cd52f2ad

USB storage now partially working under XP
author James Harper <james.harper@bendigoit.com.au>
date Sun Jun 12 00:17:30 2011 +1000 (2011-06-12)
parents 95579023dfe9
children f03bcaa67233
files xenusb/xenusb.h 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 Jun 10 20:47:09 2011 +1000
     1.2 +++ b/xenusb/xenusb.h	Sun Jun 12 00:17:30 2011 +1000
     1.3 @@ -141,12 +141,12 @@ typedef struct _xenusb_device_t xenusb_d
     1.4  typedef struct _xenusb_endpoint_t {
     1.5    xenusb_interface_t *interface;
     1.6    ULONG pipe_value;
     1.7 -  WDFTIMER interrupt_timer;
     1.8 -  WDFQUEUE interrupt_queue;
     1.9 -  WDFSPINLOCK interrupt_lock;
    1.10 +  //WDFTIMER interrupt_timer;
    1.11 +  WDFQUEUE queue;
    1.12 +  WDFSPINLOCK lock;
    1.13    USB_ENDPOINT_DESCRIPTOR endpoint_descriptor;
    1.14  };
    1.15 -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pxenusb_endpoint_t, GetEndpoint)
    1.16 +//WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(pxenusb_endpoint_t, GetEndpoint)
    1.17  
    1.18  typedef struct _xenusb_interface_t {
    1.19    //ULONG pipe_value;
    1.20 @@ -351,5 +351,8 @@ typedef struct {
    1.21  
    1.22  ULONG
    1.23  XenUsb_DecodeControlUrb(PURB urb, urb_decode_t *decode_data);
    1.24 +
    1.25 +VOID
    1.26 +XenUsbHub_ProcessHubInterruptEvent(xenusb_endpoint_t *endpoint);
    1.27    
    1.28  #endif
     2.1 --- a/xenusb/xenusb_devurb.c	Fri Jun 10 20:47:09 2011 +1000
     2.2 +++ b/xenusb/xenusb_devurb.c	Sun Jun 12 00:17:30 2011 +1000
     2.3 @@ -100,6 +100,17 @@ XenUsb_UrbCallback(usbif_shadow_t *shado
     2.4        KdPrint((__DRIVER_NAME "     URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n"));
     2.5      }
     2.6      shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferLength = shadow->total_length;
     2.7 +{
     2.8 +  PUCHAR grr;
     2.9 +  if (shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
    2.10 +    grr = MmGetSystemAddressForMdl(shadow->urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
    2.11 +  else
    2.12 +    grr = shadow->urb->UrbBulkOrInterruptTransfer.TransferBuffer;
    2.13 +  FUNCTION_MSG("data = %02x %02x %02x %02x\n", (ULONG)grr[0], (ULONG)grr[1], (ULONG)grr[2], (ULONG)grr[3]);
    2.14 +}
    2.15 +    break;
    2.16 +  case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
    2.17 +    KdPrint((__DRIVER_NAME "     URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n"));
    2.18      break;
    2.19    default:
    2.20      KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
    2.21 @@ -138,7 +149,10 @@ XenUsb_UrbCallback(usbif_shadow_t *shado
    2.22      KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
    2.23      break;
    2.24    }
    2.25 -  WdfRequestComplete(shadow->request, STATUS_SUCCESS);
    2.26 +  if (shadow->urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
    2.27 +    WdfRequestComplete(shadow->request, STATUS_SUCCESS);
    2.28 +  else
    2.29 +    WdfRequestComplete(shadow->request, STATUS_UNSUCCESSFUL);
    2.30    put_shadow_on_freelist(xudd, shadow);
    2.31  
    2.32    FUNCTION_EXIT();
    2.33 @@ -737,6 +751,7 @@ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 
    2.34  #endif
    2.35    case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: /* 11.12.4 */
    2.36      endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;    
    2.37 +    KdPrint((__DRIVER_NAME "      pipe_handle = %p\n", endpoint));
    2.38      KdPrint((__DRIVER_NAME "      pipe_value = %08x\n", endpoint->pipe_value));
    2.39      shadow = get_shadow_from_freelist(xudd);
    2.40      KdPrint((__DRIVER_NAME "      id = %d\n", shadow->id));
    2.41 @@ -760,20 +775,44 @@ URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 
    2.42        KdPrint((__DRIVER_NAME "      USB_ENDPOINT_TYPE_%d\n", endpoint->endpoint_descriptor.bmAttributes));
    2.43        break;
    2.44      }
    2.45 +    FUNCTION_MSG("endpoint address = %02x\n", endpoint->endpoint_descriptor.bEndpointAddress);
    2.46 +    FUNCTION_MSG("pipe_direction_bit = %08x\n", endpoint->pipe_value & LINUX_PIPE_DIRECTION_IN);
    2.47 +    FUNCTION_MSG("short_ok_bit = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_SHORT_TRANSFER_OK);
    2.48 +    FUNCTION_MSG("flags_direction_bit = %08x\n", urb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN);
    2.49      status = XenUsb_ExecuteRequest(xudd, shadow, urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferMDL, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
    2.50      if (!NT_SUCCESS(status))
    2.51      {
    2.52        KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
    2.53      }
    2.54      break;
    2.55 -#if 0
    2.56    case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
    2.57      KdPrint((__DRIVER_NAME "     URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL\n"));
    2.58      KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
    2.59 -    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
    2.60 -    WdfRequestComplete(request, STATUS_SUCCESS);
    2.61 +    /* we only clear the stall here */
    2.62 +    endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;    
    2.63 +    shadow = get_shadow_from_freelist(xudd);
    2.64 +    shadow->request = request;
    2.65 +    shadow->urb = urb;
    2.66 +    shadow->mdl = NULL;
    2.67 +    //shadow->dma_transaction = NULL;
    2.68 +    shadow->callback = XenUsb_UrbCallback;
    2.69 +    shadow->req.id = shadow->id;
    2.70 +    shadow->req.pipe = LINUX_PIPE_TYPE_CTRL | (usb_device->address << 8) | usb_device->port_number;
    2.71 +    shadow->req.transfer_flags = 0;
    2.72 +    setup_packet = (PUSB_DEFAULT_PIPE_SETUP_PACKET)shadow->req.u.ctrl;
    2.73 +    setup_packet->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
    2.74 +    setup_packet->bmRequestType.Type = BMREQUEST_STANDARD;
    2.75 +    setup_packet->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
    2.76 +    setup_packet->bRequest = USB_REQUEST_CLEAR_FEATURE;
    2.77 +    setup_packet->wLength = 0;
    2.78 +    setup_packet->wValue.W = 0; /* 0 == ENDPOINT_HALT */
    2.79 +    setup_packet->wIndex.W = endpoint->endpoint_descriptor.bEndpointAddress;
    2.80 +    status = XenUsb_ExecuteRequest(xudd, shadow, NULL, NULL, 0);
    2.81 +    if (!NT_SUCCESS(status))
    2.82 +    {
    2.83 +      KdPrint((__DRIVER_NAME "     XenUsb_ExecuteRequest status = %08x\n", status));
    2.84 +    }
    2.85      break;
    2.86 -#endif
    2.87    case URB_FUNCTION_ABORT_PIPE:
    2.88      KdPrint((__DRIVER_NAME "     URB_FUNCTION_ABORT_PIPE\n"));
    2.89      KdPrint((__DRIVER_NAME "      PipeHandle = %p\n", urb->UrbPipeRequest.PipeHandle));
     3.1 --- a/xenusb/xenusb_fdo.c	Fri Jun 10 20:47:09 2011 +1000
     3.2 +++ b/xenusb/xenusb_fdo.c	Sun Jun 12 00:17:30 2011 +1000
     3.3 @@ -54,6 +54,8 @@ XenUsb_ExecuteRequest(
     3.4    FUNCTION_ENTER();
     3.5    FUNCTION_MSG("IRQL = %d\n", KeGetCurrentIrql());
     3.6    
     3.7 +  KdPrint((__DRIVER_NAME "     transfer_buffer = %p\n", transfer_buffer));
     3.8 +  KdPrint((__DRIVER_NAME "     transfer_buffer_mdl = %p\n", transfer_buffer_mdl));
     3.9    KdPrint((__DRIVER_NAME "     transfer_buffer_length = %d\n", transfer_buffer_length));
    3.10    shadow->total_length = 0;
    3.11    if (!transfer_buffer_length)
    3.12 @@ -92,6 +94,15 @@ XenUsb_ExecuteRequest(
    3.13    ASSERT(mdl);
    3.14    ASSERT(transfer_buffer_length);
    3.15  
    3.16 +  FUNCTION_MSG("MmGetMdlVirtualAddress = %d\n", MmGetMdlVirtualAddress(mdl));
    3.17 +  FUNCTION_MSG("MmGetMdlByteCount = %d\n", MmGetMdlByteCount(mdl));
    3.18 +  FUNCTION_MSG("MmGetMdlByteOffset = %d\n", MmGetMdlByteOffset(mdl));
    3.19 +  
    3.20 +{
    3.21 +  PUCHAR grr = MmGetSystemAddressForMdl(mdl);
    3.22 +  FUNCTION_MSG("data = %02x %02x %02x %02x\n", (ULONG)grr[0], (ULONG)grr[1], (ULONG)grr[2], (ULONG)grr[3]);
    3.23 +}
    3.24 +  
    3.25    remaining = MmGetMdlByteCount(mdl);
    3.26    offset = (USHORT)MmGetMdlByteOffset(mdl);
    3.27    shadow->req.buffer_length = (USHORT)MmGetMdlByteCount(mdl);
    3.28 @@ -104,6 +115,10 @@ XenUsb_ExecuteRequest(
    3.29      shadow->req.seg[i].length = (USHORT)min(remaining, PAGE_SIZE);
    3.30      offset = 0;
    3.31      remaining -= shadow->req.seg[i].length;
    3.32 +    KdPrint((__DRIVER_NAME "     seg = %d\n", i));
    3.33 +    KdPrint((__DRIVER_NAME "      gref = %d\n", shadow->req.seg[i].gref));
    3.34 +    KdPrint((__DRIVER_NAME "      offset = %d\n", shadow->req.seg[i].offset));
    3.35 +    KdPrint((__DRIVER_NAME "      length = %d\n", shadow->req.seg[i].length));
    3.36    }
    3.37    KdPrint((__DRIVER_NAME "     buffer_length = %d\n", shadow->req.buffer_length));
    3.38    KdPrint((__DRIVER_NAME "     nr_buffer_segs = %d\n", shadow->req.nr_buffer_segs));
    3.39 @@ -189,8 +204,9 @@ XenUsb_HandleEvent(PVOID context)
    3.40    int more_to_do;
    3.41    usbif_shadow_t *complete_head = NULL, *complete_tail = NULL;
    3.42    usbif_shadow_t *shadow;
    3.43 +  BOOLEAN port_changed = FALSE;
    3.44  
    3.45 -  //FUNCTION_ENTER();
    3.46 +  FUNCTION_ENTER();
    3.47  
    3.48    more_to_do = TRUE;
    3.49    KeAcquireSpinLockAtDpcLevel(&xudd->urb_ring_lock);
    3.50 @@ -206,14 +222,14 @@ XenUsb_HandleEvent(PVOID context)
    3.51        shadow->rsp = *urb_rsp;
    3.52        shadow->next = NULL;
    3.53        shadow->total_length += urb_rsp->actual_length;
    3.54 -#if 0
    3.55 -      KdPrint((__DRIVER_NAME "     rsp id = %d\n", shadow->rsp.id));
    3.56 -      KdPrint((__DRIVER_NAME "     rsp start_frame = %d\n", shadow->rsp.start_frame));
    3.57 -      KdPrint((__DRIVER_NAME "     rsp status = %d\n", shadow->rsp.status));
    3.58 -      KdPrint((__DRIVER_NAME "     rsp actual_length = %d\n", shadow->rsp.actual_length));
    3.59 -      KdPrint((__DRIVER_NAME "     rsp error_count = %d\n", shadow->rsp.error_count));
    3.60 -      KdPrint((__DRIVER_NAME "     total_length = %d\n", shadow->total_length));
    3.61 -#endif
    3.62 +
    3.63 +      KdPrint((__DRIVER_NAME "     urb_ring rsp id = %d\n", shadow->rsp.id));
    3.64 +      KdPrint((__DRIVER_NAME "     urb_ring rsp start_frame = %d\n", shadow->rsp.start_frame));
    3.65 +      KdPrint((__DRIVER_NAME "     urb_ring rsp status = %d\n", shadow->rsp.status));
    3.66 +      KdPrint((__DRIVER_NAME "     urb_ring rsp actual_length = %d\n", shadow->rsp.actual_length));
    3.67 +      KdPrint((__DRIVER_NAME "     urb_ring rsp error_count = %d\n", shadow->rsp.error_count));
    3.68 +      KdPrint((__DRIVER_NAME "     urb_ring total_length = %d\n", shadow->total_length));
    3.69 +
    3.70        if (complete_tail)
    3.71        {
    3.72          complete_tail->next = shadow;
    3.73 @@ -267,9 +283,7 @@ XenUsb_HandleEvent(PVOID context)
    3.74          break;
    3.75        }      
    3.76        xudd->ports[conn_rsp->portnum - 1].port_change |= (1 << PORT_CONNECTION);
    3.77 -      
    3.78 -      // notify pending interrupt urb?
    3.79 -      
    3.80 +      port_changed = TRUE;    
    3.81        conn_req = RING_GET_REQUEST(&xudd->conn_ring, xudd->conn_ring.req_prod_pvt);
    3.82        conn_req->id = conn_rsp->id;
    3.83        xudd->conn_ring.req_prod_pvt++;
    3.84 @@ -312,7 +326,14 @@ XenUsb_HandleEvent(PVOID context)
    3.85      }
    3.86      shadow = shadow->next;
    3.87    }
    3.88 -  //FUNCTION_EXIT();
    3.89 +
    3.90 +  if (port_changed)
    3.91 +  {
    3.92 +    PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(xudd->root_hub_device);
    3.93 +    XenUsbHub_ProcessHubInterruptEvent(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]);
    3.94 +  }
    3.95 +      
    3.96 +  FUNCTION_EXIT();
    3.97  
    3.98    return TRUE;
    3.99  }
   3.100 @@ -469,47 +490,6 @@ XenUsb_EvtDevicePrepareHardware(WDFDEVIC
   3.101      }
   3.102    }
   3.103  
   3.104 -#if 0
   3.105 -*** No owner thread found for resource 808a5920
   3.106 -*** No owner thread found for resource 808a5920
   3.107 -*** No owner thread found for resource 808a5920
   3.108 -*** No owner thread found for resource 808a5920
   3.109 -Probably caused by : USBSTOR.SYS ( USBSTOR!USBSTOR_SyncSendUsbRequest+77 )
   3.110 -
   3.111 -f78e27a4 8081df53 809c560e f78e27c4 809c560e nt!IovCallDriver+0x82
   3.112 -f78e27b0 809c560e 80a5ff00 82b431a8 00000000 nt!IofCallDriver+0x13
   3.113 -f78e27c4 809b550c 82b431a8 8454ef00 8454ef00 nt!ViFilterDispatchGeneric+0x2a
   3.114 -f78e27f4 8081df53 bac7818a f78e2808 bac7818a nt!IovCallDriver+0x112
   3.115 -f78e2800 bac7818a f78e282c bac79d3c 8454ef00 nt!IofCallDriver+0x13
   3.116 -f78e2808 bac79d3c 8454ef00 82b431a8 80a5ff00 usbhub!USBH_PassIrp+0x18
   3.117 -f78e282c bac79f08 822ea7c0 8454ef00 f78e286c usbhub!USBH_FdoDispatch+0x4c
   3.118 -f78e283c 809b550c 822ea708 8454ef00 8454efb0 usbhub!USBH_HubDispatch+0x5e
   3.119 -f78e286c 8081df53 809c560e f78e288c 809c560e nt!IovCallDriver+0x112
   3.120 -f78e2878 809c560e 80a5ff00 8233dad0 00000000 nt!IofCallDriver+0x13
   3.121 -f78e288c 809b550c 8233dad0 8454ef00 8454efd4 nt!ViFilterDispatchGeneric+0x2a
   3.122 -f78e28bc 8081df53 bac7c15e f78e28e0 bac7c15e nt!IovCallDriver+0x112
   3.123 -f78e28c8 bac7c15e 822ea7c0 81f98df8 8454ef00 nt!IofCallDriver+0x13
   3.124 -f78e28e0 bac7ca33 822ea7c0 8454ef00 80a5ff00 usbhub!USBH_PdoUrbFilter+0x14c
   3.125 -f78e2900 bac79ef2 8380cfb0 8454ef00 f78e2940 usbhub!USBH_PdoDispatch+0x211
   3.126 -f78e2910 809b550c 81f98d40 8454ef00 82334c80 usbhub!USBH_HubDispatch+0x48
   3.127 -f78e2940 8081df53 ba2ed27d f78e2978 ba2ed27d nt!IovCallDriver+0x112
   3.128 -f78e294c ba2ed27d 82334bc8 8380cfb0 82334c80 nt!IofCallDriver+0x13
   3.129 -f78e2978 ba2ed570 82334bc8 8380cfb0 00000000 USBSTOR!USBSTOR_SyncSendUsbRequest+0x77
   3.130 -f78e29ac ba2ee0a4 82334bc8 82334bc8 82334c80 USBSTOR!USBSTOR_SelectConfiguration+0x7e
   3.131 -f78e29ec ba2ee1e8 82334bc8 83caced8 80a5ff00 USBSTOR!USBSTOR_FdoStartDevice+0x68
   3.132 -f78e2a04 809b550c 82334bc8 83caced8 83cacffc USBSTOR!USBSTOR_Pnp+0x5a
   3.133 -f78e2a34 8081df53 8090d728 f78e2a6c 8090d728 nt!IovCallDriver+0x112
   3.134 -f78e2a40 8090d728 f78e2aac 81f98d40 00000000 nt!IofCallDriver+0x13
   3.135 -f78e2a6c 8090d7bb 82334bc8 f78e2a88 00000000 nt!IopSynchronousCall+0xb8
   3.136 -f78e2ab0 8090a684 81f98d40 823c71a8 00000001 nt!IopStartDevice+0x4d
   3.137 -f78e2acc 8090cd9d 81f98d40 00000001 823c71a8 nt!PipProcessStartPhase1+0x4e
   3.138 -f78e2d24 8090d21c 82403628 00000001 00000000 nt!PipProcessDevNodeTree+0x1db
   3.139 -f78e2d58 80823345 00000003 82d06020 808ae5fc nt!PiProcessReenumeration+0x60
   3.140 -f78e2d80 80880469 00000000 00000000 82d06020 nt!PipDeviceActionWorker+0x16b
   3.141 -f78e2dac 80949b7c 00000000 00000000 00000000 nt!ExpWorkerThread+0xeb
   3.142 -f78e2ddc 8088e092 8088037e 00000001 00000000 nt!PspSystemThreadStartup+0x2e
   3.143 -#endif
   3.144 -
   3.145    status = XenUsb_StartXenbusInit(xudd);
   3.146  
   3.147    ptr = xudd->config_page;
   3.148 @@ -1030,7 +1010,7 @@ XenUsb_EvtIoInternalDeviceControl(
   3.149      usb_device = urb->UrbHeader.UsbdDeviceHandle;
   3.150      FUNCTION_MSG("usb_device = %p\n", usb_device);
   3.151      ASSERT(usb_device);
   3.152 -    if (usb_device == (ULONG_PTR)0 - 1)
   3.153 +    if (usb_device == (xenusb_device_t *)((ULONG_PTR)0 - 1))
   3.154        WdfRequestComplete(request, STATUS_INVALID_PARAMETER);
   3.155      else
   3.156        WdfRequestForwardToIoQueue(request, usb_device->urb_queue);
   3.157 @@ -1103,7 +1083,11 @@ XenUsb_EvtDriverDeviceAdd(WDFDRIVER driv
   3.158    WDF_DEVICE_POWER_CAPABILITIES power_capabilities;
   3.159    WDF_IO_QUEUE_CONFIG queue_config;
   3.160    UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
   3.161 -  
   3.162 +  DECLARE_CONST_UNICODE_STRING(symbolicname_name, L"SymbolicName");
   3.163 +  WDFSTRING symbolicname_value_wdfstring;
   3.164 +  WDFKEY device_key;
   3.165 +  UNICODE_STRING symbolicname_value;
   3.166 +
   3.167    UNREFERENCED_PARAMETER(driver);
   3.168  
   3.169    FUNCTION_ENTER();
   3.170 @@ -1187,6 +1171,15 @@ XenUsb_EvtDriverDeviceAdd(WDFDRIVER driv
   3.171    if (!NT_SUCCESS(status))
   3.172      return status;
   3.173  
   3.174 +  /* USB likes to have a registry key with the symbolic link name in it */
   3.175 +  status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolicname_value_wdfstring);
   3.176 +  status = WdfDeviceRetrieveDeviceInterfaceString(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, symbolicname_value_wdfstring);
   3.177 +  if (!NT_SUCCESS(status))
   3.178 +    return status;
   3.179 +  WdfStringGetUnicodeString(symbolicname_value_wdfstring, &symbolicname_value);
   3.180 +  status = WdfDeviceOpenRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &device_key);
   3.181 +  WdfRegistryAssignUnicodeString(device_key, &symbolicname_name, &symbolicname_value);
   3.182 +
   3.183    FUNCTION_EXIT();
   3.184    return status;
   3.185  }
     4.1 --- a/xenusb/xenusb_hub.c	Fri Jun 10 20:47:09 2011 +1000
     4.2 +++ b/xenusb/xenusb_hub.c	Sun Jun 12 00:17:30 2011 +1000
     4.3 @@ -57,54 +57,6 @@ static USB_BUSIFFN_ROOTHUB_INIT_NOTIFY X
     4.4  static USB_BUSIFFN_FLUSH_TRANSFERS XenUsbHub_UBIH_FlushTransfers;
     4.5  static USB_BUSIFFN_SET_DEVHANDLE_DATA XenUsbHub_UBIH_SetDeviceHandleData;
     4.6  
     4.7 -static NTSTATUS
     4.8 -XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE(WDFDEVICE device, PIRP irp)
     4.9 -{
    4.10 -  PIO_STACK_LOCATION stack;
    4.11 - 
    4.12 -  FUNCTION_ENTER();
    4.13 - 
    4.14 -  stack = IoGetCurrentIrpStackLocation(irp);
    4.15 -
    4.16 -  if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID, sizeof(GUID)) == 0)
    4.17 -    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_GUID\n"));
    4.18 -  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID, sizeof(GUID)) == 0)
    4.19 -    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_USBDI_GUID\n"));
    4.20 -  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_TRANSLATOR_INTERFACE_STANDARD, sizeof(GUID)) == 0)
    4.21 -    KdPrint((__DRIVER_NAME "     GUID_TRANSLATOR_INTERFACE_STANDARD\n"));
    4.22 -#if (NTDDI_VERSION >= NTDDI_VISTA)
    4.23 -  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_PNP_LOCATION_INTERFACE, sizeof(GUID)) == 0)
    4.24 -    KdPrint((__DRIVER_NAME "     GUID_PNP_LOCATION_INTERFACE\n"));
    4.25 -#endif
    4.26 -  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_MINIDUMP_GUID, sizeof(GUID)) == 0)
    4.27 -    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_MINIDUMP_GUID\n"));
    4.28 -  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_SS_GUID, sizeof(GUID)) == 0)
    4.29 -    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_SS_GUID\n"));
    4.30 -  else
    4.31 -    KdPrint((__DRIVER_NAME "     GUID = %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
    4.32 -      stack->Parameters.QueryInterface.InterfaceType->Data1,
    4.33 -      stack->Parameters.QueryInterface.InterfaceType->Data2,
    4.34 -      stack->Parameters.QueryInterface.InterfaceType->Data3,
    4.35 -      (stack->Parameters.QueryInterface.InterfaceType->Data4[0] << 8) |
    4.36 -       stack->Parameters.QueryInterface.InterfaceType->Data4[1],
    4.37 -      stack->Parameters.QueryInterface.InterfaceType->Data4[2],
    4.38 -      stack->Parameters.QueryInterface.InterfaceType->Data4[3],
    4.39 -      stack->Parameters.QueryInterface.InterfaceType->Data4[4],
    4.40 -      stack->Parameters.QueryInterface.InterfaceType->Data4[5],
    4.41 -      stack->Parameters.QueryInterface.InterfaceType->Data4[6],
    4.42 -      stack->Parameters.QueryInterface.InterfaceType->Data4[7]));
    4.43 -
    4.44 -  KdPrint((__DRIVER_NAME "     Size = %d\n", stack->Parameters.QueryInterface.Size));
    4.45 -  KdPrint((__DRIVER_NAME "     Version = %d\n", stack->Parameters.QueryInterface.Version));
    4.46 -  KdPrint((__DRIVER_NAME "     Interface = %p\n", stack->Parameters.QueryInterface.Interface));
    4.47 -
    4.48 -  IoSkipCurrentIrpStackLocation(irp);
    4.49 -  
    4.50 -  FUNCTION_EXIT();
    4.51 -
    4.52 -  return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
    4.53 -}
    4.54 -
    4.55  static VOID
    4.56  XenUsbHub_EvtIoDefault(
    4.57    WDFQUEUE queue,
    4.58 @@ -413,6 +365,10 @@ static NTSTATUS
    4.59  XenUsbHub_EvtDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previous_state)
    4.60  {
    4.61    NTSTATUS status = STATUS_SUCCESS;
    4.62 +  DECLARE_CONST_UNICODE_STRING(symbolicname_name, L"SymbolicName");
    4.63 +  WDFSTRING symbolicname_value_wdfstring;
    4.64 +  WDFKEY device_key;
    4.65 +  UNICODE_STRING symbolicname_value;
    4.66    
    4.67    UNREFERENCED_PARAMETER(device);
    4.68  
    4.69 @@ -442,7 +398,18 @@ XenUsbHub_EvtDeviceD0Entry(WDFDEVICE dev
    4.70      KdPrint((__DRIVER_NAME "     Unknown WdfPowerDevice state %d\n", previous_state));
    4.71      break;  
    4.72    }
    4.73 -  
    4.74 +
    4.75 +  /* USB likes to have a registry key with the symbolic link name in it. Have to wait until D0Entry as this is the PDO */
    4.76 +  status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolicname_value_wdfstring);
    4.77 +  status = WdfDeviceRetrieveDeviceInterfaceString(device, &GUID_DEVINTERFACE_USB_HUB, NULL, symbolicname_value_wdfstring);
    4.78 +  FUNCTION_MSG("WdfDeviceREtrieveDeviceInterfaceString = %08x\n", status);
    4.79 +  if (!NT_SUCCESS(status))
    4.80 +    return status;
    4.81 +  WdfStringGetUnicodeString(symbolicname_value_wdfstring, &symbolicname_value);
    4.82 +  FUNCTION_MSG("ROOT_HUB SymbolicName = %S\n", symbolicname_value.Buffer);
    4.83 +  status = WdfDeviceOpenRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &device_key);
    4.84 +  WdfRegistryAssignUnicodeString(device_key, &symbolicname_name, &symbolicname_value);
    4.85 +
    4.86    FUNCTION_EXIT();
    4.87    
    4.88    return status;
    4.89 @@ -1637,6 +1604,72 @@ XenUsbHub_UBIHSS_ResumeHub(
    4.90    return STATUS_UNSUCCESSFUL;
    4.91  }
    4.92  
    4.93 +VOID
    4.94 +XenUsbHub_ProcessHubInterruptEvent(xenusb_endpoint_t *endpoint)
    4.95 +{
    4.96 +  NTSTATUS status;
    4.97 +  WDFDEVICE pdo_device = endpoint->interface->config->device->pdo_device;
    4.98 +  PXENUSB_PDO_DEVICE_DATA xupdd = GetXupdd(pdo_device);
    4.99 +  PXENUSB_DEVICE_DATA xudd = GetXudd(xupdd->wdf_device_bus_fdo);
   4.100 +  WDF_REQUEST_PARAMETERS wrp;
   4.101 +  WDFREQUEST request;
   4.102 +  PURB urb;
   4.103 +  ULONG i;
   4.104 +  BOOLEAN port_change_flag = FALSE;
   4.105 +  
   4.106 +  FUNCTION_ENTER();
   4.107 +  WdfSpinLockAcquire(endpoint->lock);
   4.108 +  status = WdfIoQueueRetrieveNextRequest(endpoint->queue, &request);
   4.109 +  if (status == STATUS_NO_MORE_ENTRIES)
   4.110 +  {
   4.111 +    WdfSpinLockRelease(endpoint->lock);
   4.112 +    KdPrint((__DRIVER_NAME "      No More Entries\n", status));
   4.113 +    FUNCTION_EXIT();
   4.114 +    return;
   4.115 +  }
   4.116 +  if (!NT_SUCCESS(status))
   4.117 +  {
   4.118 +    WdfSpinLockRelease(endpoint->lock);
   4.119 +    KdPrint((__DRIVER_NAME "      Failed to get request from queue %08x\n", status));
   4.120 +    FUNCTION_EXIT();
   4.121 +    return;
   4.122 +  }
   4.123 +  
   4.124 +  WDF_REQUEST_PARAMETERS_INIT(&wrp);
   4.125 +  WdfRequestGetParameters(request, &wrp);
   4.126 +
   4.127 +  urb = (PURB)wrp.Parameters.Others.Arg1;
   4.128 +  ASSERT(urb);
   4.129 +  ASSERT(urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER);
   4.130 +  RtlZeroMemory(urb->UrbBulkOrInterruptTransfer.TransferBuffer, urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
   4.131 +
   4.132 +  for (i = 0; i < xudd->num_ports; i++)
   4.133 +  {
   4.134 +    if (xudd->ports[i].port_change)
   4.135 +    {
   4.136 +      FUNCTION_MSG("Port change on port %d - status = %04x, change = %04x\n",
   4.137 +        xudd->ports[i].port_number, xudd->ports[i].port_status, xudd->ports[i].port_change);
   4.138 +      ((PUCHAR)urb->UrbBulkOrInterruptTransfer.TransferBuffer)[xudd->ports[i].port_number >> 3] |= 1 << (xudd->ports[i].port_number & 7);
   4.139 +      port_change_flag = TRUE;
   4.140 +    }
   4.141 +  }
   4.142 +  WdfSpinLockRelease(endpoint->lock);
   4.143 +  if (port_change_flag)
   4.144 +  {
   4.145 +    FUNCTION_MSG("Completing request %p\n", request);
   4.146 +    urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   4.147 +    WdfRequestComplete(request, STATUS_SUCCESS);
   4.148 +  }
   4.149 +  else
   4.150 +  {
   4.151 +    FUNCTION_MSG("Requeuing request %p\n", request);
   4.152 +    WdfRequestRequeue(request);
   4.153 +  }
   4.154 +  FUNCTION_EXIT();
   4.155 +  return;
   4.156 +}
   4.157 +
   4.158 +#if 0
   4.159  static VOID
   4.160  XenUsbHub_HubInterruptTimer(WDFTIMER timer)
   4.161  {
   4.162 @@ -1651,12 +1684,12 @@ XenUsbHub_HubInterruptTimer(WDFTIMER tim
   4.163    ULONG i;
   4.164    
   4.165    //FUNCTION_ENTER();
   4.166 -  WdfSpinLockAcquire(endpoint->interrupt_lock);
   4.167 -  status = WdfIoQueueRetrieveNextRequest(endpoint->interrupt_queue, &request);
   4.168 +  WdfSpinLockAcquire(endpoint->lock);
   4.169 +  status = WdfIoQueueRetrieveNextRequest(endpoint->queue, &request);
   4.170    if (status == STATUS_NO_MORE_ENTRIES)
   4.171    {
   4.172      WdfTimerStop(timer, FALSE);
   4.173 -    WdfSpinLockRelease(endpoint->interrupt_lock);
   4.174 +    WdfSpinLockRelease(endpoint->lock);
   4.175      //KdPrint((__DRIVER_NAME "      No More Entries\n", status));
   4.176      //FUNCTION_EXIT();
   4.177      return;
   4.178 @@ -1664,7 +1697,7 @@ XenUsbHub_HubInterruptTimer(WDFTIMER tim
   4.179    if (!NT_SUCCESS(status))
   4.180    {
   4.181      WdfTimerStop(timer, FALSE);
   4.182 -    WdfSpinLockRelease(endpoint->interrupt_lock);
   4.183 +    WdfSpinLockRelease(endpoint->lock);
   4.184      KdPrint((__DRIVER_NAME "      Failed to get request from queue %08x\n", status));
   4.185      //FUNCTION_EXIT();
   4.186      return;
   4.187 @@ -1708,19 +1741,115 @@ XenUsbHub_HubInterruptTimer(WDFTIMER tim
   4.188      if (port_change_flag)
   4.189        urb->UrbBulkOrInterruptTransfer.TransferBufferLength = 2;
   4.190      urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
   4.191 -    WdfSpinLockRelease(endpoint->interrupt_lock);
   4.192 +    WdfSpinLockRelease(endpoint->lock);
   4.193      WdfRequestComplete(request, STATUS_SUCCESS);
   4.194    }
   4.195    else
   4.196    {
   4.197      KdPrint((__DRIVER_NAME "      Direction mismatch\n"));
   4.198      urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
   4.199 -    WdfSpinLockRelease(endpoint->interrupt_lock);
   4.200 +    WdfSpinLockRelease(endpoint->lock);
   4.201      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
   4.202    }
   4.203    //FUNCTION_EXIT();
   4.204    return;
   4.205  }
   4.206 +#endif
   4.207 +
   4.208 +static NTSTATUS
   4.209 +XenUsbHub_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE(WDFDEVICE device, PIRP irp)
   4.210 +{
   4.211 +  PIO_STACK_LOCATION stack;
   4.212 +  union {
   4.213 +    USB_BUS_INTERFACE_USBDI_V1 ubiu0;
   4.214 +    USB_BUS_INTERFACE_USBDI_V1 ubiu1;
   4.215 +    USB_BUS_INTERFACE_USBDI_V2 ubiu2;
   4.216 +#if (NTDDI_VERSION >= NTDDI_VISTA)
   4.217 +    USB_BUS_INTERFACE_USBDI_V3 ubiu3;
   4.218 +#endif
   4.219 +  } *ubiu;
   4.220 +
   4.221 +  FUNCTION_ENTER();
   4.222 + 
   4.223 +  stack = IoGetCurrentIrpStackLocation(irp);
   4.224 +
   4.225 +  if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID, sizeof(GUID)) == 0)
   4.226 +    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_GUID\n"));
   4.227 +  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID, sizeof(GUID)) == 0)
   4.228 +  {
   4.229 +    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_USBDI_GUID\n"));
   4.230 +    if ((stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_0 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V0))
   4.231 +      || (stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_1 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V1))
   4.232 +      || (stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_2 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V2))
   4.233 +#if (NTDDI_VERSION >= NTDDI_VISTA)  
   4.234 +      || (stack->Parameters.QueryInterface.Version == USB_BUSIF_USBDI_VERSION_3 && stack->Parameters.QueryInterface.Size == sizeof(USB_BUS_INTERFACE_USBDI_V3))
   4.235 +#endif
   4.236 +    )
   4.237 +    {
   4.238 +      ubiu = (PVOID)stack->Parameters.QueryInterface.Interface;
   4.239 +      ubiu->ubiu0.Size = stack->Parameters.QueryInterface.Size;
   4.240 +      ubiu->ubiu0.Version = stack->Parameters.QueryInterface.Version;
   4.241 +      ubiu->ubiu0.BusContext = device;
   4.242 +      ubiu->ubiu0.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   4.243 +      ubiu->ubiu0.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   4.244 +      switch (stack->Parameters.QueryInterface.Version)
   4.245 +      {
   4.246 +      case USB_BUSIF_USBDI_VERSION_0:          
   4.247 +        ubiu->ubiu0.GetUSBDIVersion = XenUsbHub_UBIU_GetUSBDIVersion;
   4.248 +        ubiu->ubiu0.QueryBusTime = XenUsbHub_UBIU_QueryBusTime;
   4.249 +        ubiu->ubiu0.SubmitIsoOutUrb = XenUsbHub_UBIU_SubmitIsoOutUrb;
   4.250 +        ubiu->ubiu0.QueryBusInformation = XenUsbHub_UBIU_QueryBusInformation;
   4.251 +        /* fall through */
   4.252 +      case USB_BUSIF_USBDI_VERSION_1:
   4.253 +        ubiu->ubiu1.IsDeviceHighSpeed = XenUsbHub_UBIU_IsDeviceHighSpeed;
   4.254 +        /* fall through */
   4.255 +      case USB_BUSIF_USBDI_VERSION_2:
   4.256 +        ubiu->ubiu2.EnumLogEntry  = XenUsbHub_UBIU_EnumLogEntry;
   4.257 +        /* fall through */
   4.258 +#if (NTDDI_VERSION >= NTDDI_VISTA)  
   4.259 +      case USB_BUSIF_USBDI_VERSION_3:
   4.260 +        ubiu->ubiu3.QueryBusTimeEx = XenUsbHub_UBIU_QueryBusTimeEx;
   4.261 +        ubiu->ubiu3.QueryControllerType = XenUsbHub_UBIU_QueryControllerType;
   4.262 +#endif
   4.263 +      }
   4.264 +      irp->IoStatus.Information = 0;
   4.265 +      irp->IoStatus.Status = STATUS_SUCCESS;
   4.266 +    }
   4.267 +  }
   4.268 +  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_TRANSLATOR_INTERFACE_STANDARD, sizeof(GUID)) == 0)
   4.269 +    KdPrint((__DRIVER_NAME "     GUID_TRANSLATOR_INTERFACE_STANDARD\n"));
   4.270 +#if (NTDDI_VERSION >= NTDDI_VISTA)
   4.271 +  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &GUID_PNP_LOCATION_INTERFACE, sizeof(GUID)) == 0)
   4.272 +    KdPrint((__DRIVER_NAME "     GUID_PNP_LOCATION_INTERFACE\n"));
   4.273 +#endif
   4.274 +  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_MINIDUMP_GUID, sizeof(GUID)) == 0)
   4.275 +    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_MINIDUMP_GUID\n"));
   4.276 +  else if (memcmp(stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_SS_GUID, sizeof(GUID)) == 0)
   4.277 +    KdPrint((__DRIVER_NAME "     USB_BUS_INTERFACE_HUB_SS_GUID\n"));
   4.278 +  else
   4.279 +    KdPrint((__DRIVER_NAME "     GUID = %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
   4.280 +      stack->Parameters.QueryInterface.InterfaceType->Data1,
   4.281 +      stack->Parameters.QueryInterface.InterfaceType->Data2,
   4.282 +      stack->Parameters.QueryInterface.InterfaceType->Data3,
   4.283 +      (stack->Parameters.QueryInterface.InterfaceType->Data4[0] << 8) |
   4.284 +       stack->Parameters.QueryInterface.InterfaceType->Data4[1],
   4.285 +      stack->Parameters.QueryInterface.InterfaceType->Data4[2],
   4.286 +      stack->Parameters.QueryInterface.InterfaceType->Data4[3],
   4.287 +      stack->Parameters.QueryInterface.InterfaceType->Data4[4],
   4.288 +      stack->Parameters.QueryInterface.InterfaceType->Data4[5],
   4.289 +      stack->Parameters.QueryInterface.InterfaceType->Data4[6],
   4.290 +      stack->Parameters.QueryInterface.InterfaceType->Data4[7]));
   4.291 +
   4.292 +  KdPrint((__DRIVER_NAME "     Size = %d\n", stack->Parameters.QueryInterface.Size));
   4.293 +  KdPrint((__DRIVER_NAME "     Version = %d\n", stack->Parameters.QueryInterface.Version));
   4.294 +  KdPrint((__DRIVER_NAME "     Interface = %p\n", stack->Parameters.QueryInterface.Interface));
   4.295 +
   4.296 +  IoSkipCurrentIrpStackLocation(irp);
   4.297 +  
   4.298 +  FUNCTION_EXIT();
   4.299 +
   4.300 +  return WdfDeviceWdmDispatchPreprocessedIrp(device, irp);
   4.301 +}
   4.302  
   4.303  NTSTATUS
   4.304  XenUsb_EvtChildListCreateDevice(WDFCHILDLIST child_list,
   4.305 @@ -1747,6 +1876,7 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.306      USB_BUS_INTERFACE_HUB_V7 ubih7; /* support versions 6,  and 7 - base definition changed */
   4.307  #endif
   4.308    } ubih;
   4.309 +#if 0
   4.310    union {
   4.311      USB_BUS_INTERFACE_USBDI_V1 ubiu1;
   4.312      USB_BUS_INTERFACE_USBDI_V2 ubiu2;
   4.313 @@ -1754,13 +1884,14 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.314      USB_BUS_INTERFACE_USBDI_V3 ubiu3;
   4.315  #endif
   4.316    } ubiu;
   4.317 +#endif
   4.318 +#if (NTDDI_VERSION >= NTDDI_VISTA)
   4.319    USB_BUS_INTERFACE_HUB_SELECTIVE_SUSPEND ubihss;
   4.320 +#endif
   4.321    WDF_TIMER_CONFIG timer_config;
   4.322 -  WDF_OBJECT_ATTRIBUTES timer_attributes;
   4.323 +  //WDF_OBJECT_ATTRIBUTES timer_attributes;
   4.324    UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE };
   4.325  
   4.326 -  UNREFERENCED_PARAMETER(xudd);
   4.327 -  
   4.328    FUNCTION_ENTER();
   4.329  
   4.330    //KdPrint((__DRIVER_NAME "     device = %d, port = %d, vendor_id = %04x, product_id = %04x\n",
   4.331 @@ -1872,7 +2003,8 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.332    xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT;
   4.333    xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.wMaxPacketSize = 2;
   4.334    xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->endpoint_descriptor.bInterval = 12;
   4.335 -  WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_lock);
   4.336 +  WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->lock);
   4.337 +#if 0
   4.338    WDF_TIMER_CONFIG_INIT(&timer_config, XenUsbHub_HubInterruptTimer);  
   4.339    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timer_attributes, pxenusb_endpoint_t);
   4.340    timer_attributes.ParentObject = child_device;
   4.341 @@ -1882,6 +2014,7 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.342        return status;
   4.343    }
   4.344    *GetEndpoint(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_timer) = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
   4.345 +#endif
   4.346  
   4.347    WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel);
   4.348    queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_ROOTHUB_SUBMIT_URB;
   4.349 @@ -1891,14 +2024,18 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.350        KdPrint((__DRIVER_NAME "     Error creating urb_queue 0x%x\n", status));
   4.351        return status;
   4.352    }
   4.353 +  
   4.354    WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual);
   4.355 +  //WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queue_attributes, pxenusb_endpoint_t);
   4.356    queue_config.PowerManaged = TRUE;
   4.357 +  //queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_Interrupt_SUBMIT_URB;
   4.358    status = WdfIoQueueCreate(child_device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES,
   4.359 -    &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->interrupt_queue);
   4.360 +    &xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->queue);
   4.361    if (!NT_SUCCESS(status)) {
   4.362        KdPrint((__DRIVER_NAME "     Error creating timer io_queue 0x%x\n", status));
   4.363        return status;
   4.364    }
   4.365 +  //*GetEndpoint(xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0]->queue) = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
   4.366  
   4.367    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
   4.368    queue_config.EvtIoInternalDeviceControl = XenUsbHub_EvtIoInternalDeviceControl;
   4.369 @@ -2013,7 +2150,7 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.370    status = WdfDeviceAddQueryInterface(child_device, &interface_config);
   4.371    if (!NT_SUCCESS(status))
   4.372      return status;
   4.373 -
   4.374 +#if 0
   4.375    ubiu.ubiu1.BusContext = child_device;
   4.376    ubiu.ubiu1.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
   4.377    ubiu.ubiu1.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
   4.378 @@ -2058,7 +2195,8 @@ XenUsb_EvtChildListCreateDevice(WDFCHILD
   4.379    WDF_QUERY_INTERFACE_CONFIG_INIT(&interface_config, (PINTERFACE)&ubiu, &USB_BUS_INTERFACE_HUB_SS_GUID, NULL);
   4.380    status = WdfDeviceAddQueryInterface(child_device, &interface_config);
   4.381    if (!NT_SUCCESS(status))
   4.382 -  return status;
   4.383 +    return status;
   4.384 +#endif
   4.385  
   4.386    status = WdfDeviceCreateDeviceInterface(child_device, &GUID_DEVINTERFACE_USB_HUB, NULL);
   4.387    if (!NT_SUCCESS(status))
     5.1 --- a/xenusb/xenusb_huburb.c	Fri Jun 10 20:47:09 2011 +1000
     5.2 +++ b/xenusb/xenusb_huburb.c	Sun Jun 12 00:17:30 2011 +1000
     5.3 @@ -409,6 +409,8 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
     5.4              xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_status |= (1 << PORT_ENABLE);
     5.5              xudd->ports[decode_data.setup_packet.default_pipe_setup_packet.wIndex.LowByte - 1].port_change |= (1 << PORT_RESET);
     5.6              urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
     5.7 +            endpoint = xupdd->usb_device->configs[0]->interfaces[0]->endpoints[0];
     5.8 +            XenUsbHub_ProcessHubInterruptEvent(endpoint);
     5.9              break;
    5.10            case PORT_POWER:
    5.11              KdPrint((__DRIVER_NAME "        PORT_POWER\n"));
    5.12 @@ -448,13 +450,10 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    5.13      KdPrint((__DRIVER_NAME "      TransferBufferMdl = %p\n", urb->UrbBulkOrInterruptTransfer.TransferBufferMDL));
    5.14  #endif
    5.15      endpoint = urb->UrbBulkOrInterruptTransfer.PipeHandle;
    5.16 -    WdfSpinLockAcquire(endpoint->interrupt_lock);
    5.17 -    if (WdfIoQueueGetState(endpoint->interrupt_queue, NULL, NULL) & WdfIoQueueNoRequests)
    5.18 -    {
    5.19 -      WdfTimerStart(endpoint->interrupt_timer, WDF_REL_TIMEOUT_IN_MS(100));
    5.20 -    }
    5.21 -    WdfRequestForwardToIoQueue(request, endpoint->interrupt_queue);
    5.22 -    WdfSpinLockRelease(endpoint->interrupt_lock);
    5.23 +    //WdfSpinLockAcquire(endpoint->lock);
    5.24 +    WdfRequestForwardToIoQueue(request, endpoint->queue);
    5.25 +    XenUsbHub_ProcessHubInterruptEvent(endpoint);
    5.26 +    //WdfSpinLockRelease(endpoint->lock);
    5.27      //FUNCTION_EXIT();
    5.28      return;
    5.29      
    5.30 @@ -737,6 +736,7 @@ XenUsb_EvtIoInternalDeviceControl_ROOTHU
    5.31      FUNCTION_MSG("Calling WdfRequestCompletestatus with status = %08x\n", STATUS_UNSUCCESSFUL);
    5.32      WdfRequestComplete(request, STATUS_UNSUCCESSFUL);
    5.33    }
    5.34 +
    5.35    //FUNCTION_EXIT();
    5.36    return;
    5.37  }