win-pvdrivers

changeset 406:b9028997f48b

More changes to try and prevent lockups on save and restore
author James Harper <james.harper@bendigoit.com.au>
date Fri Jul 25 11:17:41 2008 +1000 (2008-07-25)
parents 4fee03f012ee
children d84a58b968e8
files common/include/xen_windows.h xenconfig/xenconfig.c xennet/xennet.c xennet/xennet.h xenpci/evtchn.c xenpci/xenbus.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/common/include/xen_windows.h	Thu Jul 24 19:53:37 2008 +1000
     1.2 +++ b/common/include/xen_windows.h	Fri Jul 25 11:17:41 2008 +1000
     1.3 @@ -59,21 +59,20 @@ typedef unsigned long xenbus_transaction
     1.4  #define SPLITSTRING_POOL_TAG (ULONG) 'SSPT'
     1.5  
     1.6  #define wmb() KeMemoryBarrier()
     1.7 -#define mb() KeMemoryBarrier()
     1.8 -
     1.9 -#define FUNCTION_ENTER()       KdPrint((__DRIVER_NAME " --> %s\n", __FUNCTION__))
    1.10 -#define FUNCTION_EXIT()        KdPrint((__DRIVER_NAME " <-- %s\n", __FUNCTION__))
    1.11 -#define FUNCTION_EXIT_STATUS(_status) KdPrint((__DRIVER_NAME " <-- %s, status = %08x\n", __FUNCTION__, _status))
    1.12 -#define FUNCTION_ERROR_EXIT()  KdPrint((__DRIVER_NAME " <-- %s (error path)\n", __FUNCTION__))
    1.13 -#define FUNCTION_CALLED()      KdPrint((__DRIVER_NAME " %s called (line %d)\n", __FUNCTION__, __LINE__))
    1.14 -#ifdef __MINGW32__
    1.15 -#define FUNCTION_MSG(_x) _FUNCTION_MSG _x
    1.16 -#define _FUNCTION_MSG(format, args...) KdPrint((__DRIVER_NAME " %s called: " format, __FUNCTION__, ##args))
    1.17 +#define mb() KeMemoryBarrier()
    1.18 +#define FUNCTION_ENTER()       KdPrint((__DRIVER_NAME " --> %s\n", __FUNCTION__))
    1.19 +#define FUNCTION_EXIT()        KdPrint((__DRIVER_NAME " <-- %s\n", __FUNCTION__))
    1.20 +#define FUNCTION_EXIT_STATUS(_status) KdPrint((__DRIVER_NAME " <-- %s, status = %08x\n", __FUNCTION__, _status))
    1.21 +#define FUNCTION_ERROR_EXIT()  KdPrint((__DRIVER_NAME " <-- %s (error path)\n", __FUNCTION__))
    1.22 +#define FUNCTION_CALLED()      KdPrint((__DRIVER_NAME " %s called (line %d)\n", __FUNCTION__, __LINE__))
    1.23 +#ifdef __MINGW32__
    1.24 +#define FUNCTION_MSG(_x) _FUNCTION_MSG _x
    1.25 +#define _FUNCTION_MSG(format, args...) KdPrint((__DRIVER_NAME " %s called: " format, __FUNCTION__, ##args))
    1.26  #else
    1.27 -#define FUNCTION_MSG(_x)     {  \
    1.28 -    KdPrint((__DRIVER_NAME " %s called: ", __FUNCTION__));          \
    1.29 -    KdPrint(_x);                \
    1.30 -  }
    1.31 +#define FUNCTION_MSG(_x)     {  \
    1.32 +    KdPrint((__DRIVER_NAME " %s called: ", __FUNCTION__));          \
    1.33 +    KdPrint(_x);                \
    1.34 +  }
    1.35  #endif
    1.36  
    1.37  static __inline char **
     2.1 --- a/xenconfig/xenconfig.c	Thu Jul 24 19:53:37 2008 +1000
     2.2 +++ b/xenconfig/xenconfig.c	Fri Jul 25 11:17:41 2008 +1000
     2.3 @@ -309,8 +309,8 @@ XenConfig_QueueWorkItem(PDEVICE_OBJECT d
     2.4    PIO_WORKITEM work_item;
     2.5    NTSTATUS status = STATUS_SUCCESS;
     2.6  
     2.7 -	work_item = IoAllocateWorkItem(device_object);
     2.8 -	IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
     2.9 +  work_item = IoAllocateWorkItem(device_object);
    2.10 +  IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
    2.11  	
    2.12    return status;
    2.13  }
     3.1 --- a/xennet/xennet.c	Thu Jul 24 19:53:37 2008 +1000
     3.2 +++ b/xennet/xennet.c	Fri Jul 25 11:17:41 2008 +1000
     3.3 @@ -561,14 +561,15 @@ XenNet_Init(
     3.4  
     3.5    status = NdisMRegisterInterrupt(&xi->interrupt, MiniportAdapterHandle, irq_vector, irq_level,
     3.6      TRUE, TRUE, NdisInterruptLatched);
     3.7 -  /* send fake arp? */
     3.8    if (!NT_SUCCESS(status))
     3.9    {
    3.10      KdPrint(("NdisMRegisterInterrupt failed with 0x%x\n", status));
    3.11 -    //status = NDIS_STATUS_FAILURE;
    3.12 -    //goto err;
    3.13 +    status = NDIS_STATUS_FAILURE;
    3.14 +    goto err;
    3.15    }
    3.16  
    3.17 +  /* send fake arp? */
    3.18 +
    3.19    NdisMInitializeTimer(&xi->resume_timer, xi->adapter_handle, XenResumeCheck_Timer, xi);
    3.20    NdisMSetPeriodicTimer(&xi->resume_timer, 100);
    3.21  
     4.1 --- a/xennet/xennet.h	Thu Jul 24 19:53:37 2008 +1000
     4.2 +++ b/xennet/xennet.h	Fri Jul 25 11:17:41 2008 +1000
     4.3 @@ -91,8 +91,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     4.4  
     4.5  #pragma warning(disable: 4127) // conditional expression is constant
     4.6  
     4.7 -//#define XEN_PROFILE
     4.8 -
     4.9  #define MIN_LARGE_SEND_SEGMENTS 4
    4.10  
    4.11  /* TODO: crank this up if we support higher mtus? */
    4.12 @@ -239,36 +237,6 @@ struct xennet_info
    4.13  } typedef xennet_info_t;
    4.14  
    4.15  
    4.16 -extern LARGE_INTEGER ProfTime_TxBufferGC;
    4.17 -extern LARGE_INTEGER ProfTime_TxBufferFree;
    4.18 -extern LARGE_INTEGER ProfTime_RxBufferAlloc;
    4.19 -extern LARGE_INTEGER ProfTime_RxBufferFree;
    4.20 -extern LARGE_INTEGER ProfTime_ReturnPacket;
    4.21 -extern LARGE_INTEGER ProfTime_RxBufferCheck;
    4.22 -extern LARGE_INTEGER ProfTime_RxBufferCheckTopHalf;
    4.23 -extern LARGE_INTEGER ProfTime_RxBufferCheckBotHalf;
    4.24 -extern LARGE_INTEGER ProfTime_Linearize;
    4.25 -extern LARGE_INTEGER ProfTime_SendPackets;
    4.26 -extern LARGE_INTEGER ProfTime_SendQueuedPackets;
    4.27 -
    4.28 -extern int ProfCount_TxBufferGC;
    4.29 -extern int ProfCount_TxBufferFree;
    4.30 -extern int ProfCount_RxBufferAlloc;
    4.31 -extern int ProfCount_RxBufferFree;
    4.32 -extern int ProfCount_ReturnPacket;
    4.33 -extern int ProfCount_RxBufferCheck;
    4.34 -extern int ProfCount_Linearize;
    4.35 -extern int ProfCount_SendPackets;
    4.36 -extern int ProfCount_PacketsPerSendPackets;
    4.37 -extern int ProfCount_SendQueuedPackets;
    4.38 -
    4.39 -extern int ProfCount_TxPacketsTotal;
    4.40 -extern int ProfCount_TxPacketsCsumOffload;
    4.41 -extern int ProfCount_TxPacketsLargeOffload;
    4.42 -extern int ProfCount_RxPacketsTotal;
    4.43 -extern int ProfCount_RxPacketsCsumOffload;
    4.44 -extern int ProfCount_CallsToIndicateReceive;
    4.45 -
    4.46  NDIS_STATUS
    4.47  XenNet_RxBufferCheck(struct xennet_info *xi);
    4.48  
     5.1 --- a/xenpci/evtchn.c	Thu Jul 24 19:53:37 2008 +1000
     5.2 +++ b/xenpci/evtchn.c	Fri Jul 25 11:17:41 2008 +1000
     5.3 @@ -57,6 +57,8 @@ EvtChn_DpcBounce(PRKDPC Dpc, PVOID Conte
     5.4    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
     5.5  }
     5.6  
     5.7 +BOOLEAN no_more_interrupts;
     5.8 +
     5.9  static DDKAPI BOOLEAN
    5.10  EvtChn_Interrupt(PKINTERRUPT Interrupt, PVOID Context)
    5.11  {
    5.12 @@ -73,6 +75,14 @@ EvtChn_Interrupt(PKINTERRUPT Interrupt, 
    5.13  
    5.14    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", cpu));
    5.15  
    5.16 +  if (no_more_interrupts)
    5.17 +  {
    5.18 +    KdPrint((__DRIVER_NAME "     no_more_interrupts = TRUE\n"));
    5.19 +    KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000003, 0x00000000, 0x00000000, 0x00000000);
    5.20 +  }
    5.21 +    
    5.22 +  //ASSERT(!no_more_interrupts);
    5.23 +  
    5.24    UNREFERENCED_PARAMETER(Interrupt);
    5.25  
    5.26    vcpu_info = &shared_info_area->vcpu_info[cpu];
    5.27 @@ -277,12 +287,14 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    5.28      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
    5.29    }
    5.30  
    5.31 +  no_more_interrupts = FALSE;
    5.32 +  KeMemoryBarrier();
    5.33 +
    5.34    hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, xpdd->irq_number);
    5.35  
    5.36    for (i = 0; i < MAX_VIRT_CPUS; i++)
    5.37 -  {
    5.38      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 0;
    5.39 -  }
    5.40 +
    5.41    
    5.42    FUNCTION_EXIT();
    5.43    
    5.44 @@ -292,7 +304,7 @@ EvtChn_Init(PXENPCI_DEVICE_DATA xpdd)
    5.45  NTSTATUS
    5.46  EvtChn_ConnectInterrupt(PXENPCI_DEVICE_DATA xpdd)
    5.47  {
    5.48 -  NTSTATUS status;
    5.49 +  NTSTATUS status = STATUS_SUCCESS;
    5.50    
    5.51    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
    5.52  
    5.53 @@ -314,17 +326,22 @@ EvtChn_ConnectInterrupt(PXENPCI_DEVICE_D
    5.54      KdPrint((__DRIVER_NAME "     IoConnectInterrupt failed 0x%08x\n", status));
    5.55      return status;
    5.56    }
    5.57 +
    5.58    return status;
    5.59  }
    5.60  
    5.61  NTSTATUS
    5.62  EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd)
    5.63  {
    5.64 -#if (NTDDI_VERSION < NTDDI_WINXP)
    5.65    int i;
    5.66 -#endif
    5.67 +//  LARGE_INTEGER wait_time;
    5.68  
    5.69 -  IoDisconnectInterrupt(xpdd->interrupt);
    5.70 +  for (i = 0; i < MAX_VIRT_CPUS; i++)
    5.71 +    xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
    5.72 +  hvm_set_parameter(xpdd, HVM_PARAM_CALLBACK_IRQ, 0);
    5.73 +  KeMemoryBarrier();
    5.74 +  no_more_interrupts = TRUE;
    5.75 +  KeMemoryBarrier();
    5.76  
    5.77  #if (NTDDI_VERSION >= NTDDI_WINXP)
    5.78    KeFlushQueuedDpcs();
    5.79 @@ -338,5 +355,13 @@ EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd
    5.80    }
    5.81  #endif
    5.82  
    5.83 +/*
    5.84 +KdPrint((__DRIVER_NAME "     Starting fake delay (IRQL = %d)\n", KeGetCurrentIrql()));
    5.85 +wait_time.QuadPart = 1000 * (-1 * 10 * 1000);
    5.86 +KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
    5.87 +KdPrint((__DRIVER_NAME "     Done with fake delay\n"));
    5.88 +*/
    5.89 +  //IoDisconnectInterrupt(xpdd->interrupt);
    5.90 +
    5.91    return STATUS_SUCCESS;
    5.92  }
     6.1 --- a/xenpci/xenbus.c	Thu Jul 24 19:53:37 2008 +1000
     6.2 +++ b/xenpci/xenbus.c	Fri Jul 25 11:17:41 2008 +1000
     6.3 @@ -344,14 +344,12 @@ XenBus_Init(PXENPCI_DEVICE_DATA xpdd)
     6.4  
     6.5    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
     6.6  
     6.7 -  KeInitializeSpinLock(&xpdd->WatchLock);
     6.8 +  ExInitializeFastMutex(&xpdd->watch_mutex);
     6.9    ExInitializeFastMutex(&xpdd->xenbus_mutex);
    6.10  
    6.11    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
    6.12    {
    6.13      xpdd->XenBus_WatchEntries[i].Active = 0;
    6.14 -    xpdd->XenBus_WatchEntries[i].Running = 0;
    6.15 -    KeInitializeEvent(&xpdd->XenBus_WatchEntries[i].CompleteEvent, SynchronizationEvent, FALSE);  
    6.16    }
    6.17  
    6.18    KeInitializeEvent(&xpdd->XenBus_ReadThreadEvent, SynchronizationEvent, FALSE);
    6.19 @@ -395,28 +393,76 @@ XenBus_Stop(PXENPCI_DEVICE_DATA xpdd)
    6.20  }
    6.21  #endif
    6.22  
    6.23 +char *
    6.24 +XenBus_SendRemWatch(
    6.25 +  PVOID context,
    6.26 +  xenbus_transaction_t xbt,
    6.27 +  const char *path,
    6.28 +  const int index)
    6.29 +{
    6.30 +  struct xsd_sockmsg *rep;
    6.31 +  char *msg;
    6.32 +  char Token[20];
    6.33 +  struct write_req req[2];
    6.34 +
    6.35 +  req[0].data = path;
    6.36 +  req[0].len = (ULONG)strlen(path) + 1;
    6.37 +
    6.38 +  RtlStringCbPrintfA(Token, ARRAY_SIZE(Token), "%d", index);
    6.39 +  req[1].data = Token;
    6.40 +  req[1].len = (ULONG)strlen(Token) + 1;
    6.41 +
    6.42 +  rep = xenbus_msg_reply(context, XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
    6.43 +
    6.44 +  msg = errmsg(rep);
    6.45 +  if (msg)
    6.46 +    return msg;
    6.47 +
    6.48 +  ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
    6.49 +
    6.50 +  return NULL;
    6.51 +}
    6.52 +
    6.53  NTSTATUS
    6.54  XenBus_StopThreads(PXENPCI_DEVICE_DATA xpdd)
    6.55  {
    6.56    //KWAIT_BLOCK WaitBlockArray[2];
    6.57 +  int i;
    6.58    PVOID WaitArray[2];
    6.59  
    6.60 +  FUNCTION_ENTER();
    6.61 +  
    6.62    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    6.63  
    6.64 +  /* we need to remove the watches as a watch firing could lead to a XenBus_Read/Write/Printf */
    6.65 +  ExAcquireFastMutex(&xpdd->watch_mutex);
    6.66 +  for (i = 0; i < MAX_WATCH_ENTRIES; i++) {
    6.67 +    if (xpdd->XenBus_WatchEntries[i].Active)
    6.68 +      XenBus_SendRemWatch(xpdd, XBT_NIL, xpdd->XenBus_WatchEntries[i].Path, i);
    6.69 +  }
    6.70 +  ExReleaseFastMutex(&xpdd->watch_mutex);
    6.71 +
    6.72    xpdd->XenBus_ShuttingDown = TRUE;
    6.73 +  KeMemoryBarrier();
    6.74  
    6.75 +KdPrint((__DRIVER_NAME "     Setting ReadThreadEvent\n"));
    6.76    KeSetEvent(&xpdd->XenBus_ReadThreadEvent, IO_NO_INCREMENT, FALSE);
    6.77 +KdPrint((__DRIVER_NAME "     Setting WatchThreadEvent\n"));
    6.78    KeSetEvent(&xpdd->XenBus_WatchThreadEvent, IO_NO_INCREMENT, FALSE);
    6.79    ObReferenceObjectByHandle(xpdd->XenBus_ReadThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &WaitArray[0], NULL);
    6.80    ObReferenceObjectByHandle(xpdd->XenBus_WatchThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &WaitArray[1], NULL);
    6.81 +KdPrint((__DRIVER_NAME "     Waiting for ReadThread\n"));
    6.82    KeWaitForSingleObject(WaitArray[0], Executive, KernelMode, FALSE, NULL);
    6.83 +KdPrint((__DRIVER_NAME "     Waiting for WatchThread\n"));
    6.84    KeWaitForSingleObject(WaitArray[1], Executive, KernelMode, FALSE, NULL);
    6.85 +KdPrint((__DRIVER_NAME "     Done\n"));
    6.86 +  
    6.87    xpdd->XenBus_ShuttingDown = FALSE;
    6.88  
    6.89    ZwClose(xpdd->XenBus_WatchThreadHandle);
    6.90    ZwClose(xpdd->XenBus_ReadThreadHandle);
    6.91  
    6.92 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.93 +  FUNCTION_EXIT();
    6.94  
    6.95    return STATUS_SUCCESS;
    6.96  }
    6.97 @@ -548,14 +594,15 @@ XenBus_WatchThreadProc(PVOID StartContex
    6.98    int index;
    6.99    PXENBUS_WATCH_ENTRY entry;
   6.100    PXENPCI_DEVICE_DATA xpdd = StartContext;
   6.101 -  KIRQL OldIrql;
   6.102  
   6.103    for(;;)
   6.104    {
   6.105      KeWaitForSingleObject(&xpdd->XenBus_WatchThreadEvent, Executive, KernelMode, FALSE, NULL);
   6.106 +      ExAcquireFastMutex(&xpdd->watch_mutex);
   6.107      if (xpdd->XenBus_ShuttingDown)
   6.108      {
   6.109        KdPrint((__DRIVER_NAME "     Shutdown detected in WatchThreadProc\n"));
   6.110 +      ExReleaseFastMutex(&xpdd->watch_mutex);
   6.111        PsTerminateSystemThread(0);
   6.112      }
   6.113      while (xpdd->XenBus_WatchRingReadIndex != xpdd->XenBus_WatchRingWriteIndex)
   6.114 @@ -565,26 +612,15 @@ XenBus_WatchThreadProc(PVOID StartContex
   6.115        index = atoi(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Token);
   6.116  
   6.117        entry = &xpdd->XenBus_WatchEntries[index];
   6.118 -      KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
   6.119        if (!entry->Active || !entry->ServiceRoutine)
   6.120        {
   6.121 -        KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.122          KdPrint((__DRIVER_NAME "     No watch for index %d\n", index));
   6.123          continue;
   6.124        }
   6.125 -      if (entry->RemovePending)
   6.126 -      {
   6.127 -        KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.128 -        KdPrint((__DRIVER_NAME "     Not calling watch - remove is pending\n"));
   6.129 -        continue;
   6.130 -      }        
   6.131 -      entry->Running = 1;
   6.132 -      KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.133        entry->Count++;
   6.134        entry->ServiceRoutine(xpdd->XenBus_WatchRing[xpdd->XenBus_WatchRingReadIndex].Path, entry->ServiceContext);
   6.135 -      entry->Running = 0;
   6.136 -      KeSetEvent(&entry->CompleteEvent, IO_NO_INCREMENT, FALSE);
   6.137      }
   6.138 +    ExReleaseFastMutex(&xpdd->watch_mutex);
   6.139    }
   6.140  }    
   6.141  
   6.142 @@ -663,7 +699,6 @@ XenBus_AddWatch(
   6.143    char *msg;
   6.144    int i;
   6.145    PXENBUS_WATCH_ENTRY w_entry;
   6.146 -  KIRQL OldIrql;
   6.147  
   6.148  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   6.149  
   6.150 @@ -671,7 +706,7 @@ XenBus_AddWatch(
   6.151  
   6.152    ASSERT(strlen(Path) < ARRAY_SIZE(w_entry->Path));
   6.153  
   6.154 -  KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
   6.155 +  ExAcquireFastMutex(&xpdd->watch_mutex);
   6.156  
   6.157    for (i = 0; i < MAX_WATCH_ENTRIES; i++)
   6.158      if (xpdd->XenBus_WatchEntries[i].Active == 0)
   6.159 @@ -680,7 +715,7 @@ XenBus_AddWatch(
   6.160    if (i == MAX_WATCH_ENTRIES)
   6.161    {
   6.162      KdPrint((__DRIVER_NAME " +++ No more watch slots left\n"));
   6.163 -    KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.164 +    ExReleaseFastMutex(&xpdd->watch_mutex);
   6.165      return NULL;
   6.166    }
   6.167  
   6.168 @@ -693,7 +728,7 @@ XenBus_AddWatch(
   6.169    w_entry->Count = 0;
   6.170    w_entry->Active = 1;
   6.171  
   6.172 -  KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.173 +  ExReleaseFastMutex(&xpdd->watch_mutex);
   6.174  
   6.175    msg = XenBus_SendAddWatch(xpdd, xbt, Path, i);
   6.176  
   6.177 @@ -718,17 +753,13 @@ XenBus_RemWatch(
   6.178    PVOID ServiceContext)
   6.179  {
   6.180    PXENPCI_DEVICE_DATA xpdd = Context;
   6.181 -  struct xsd_sockmsg *rep;
   6.182    char *msg;
   6.183    int i;
   6.184 -  char Token[20];
   6.185 -  struct write_req req[2];
   6.186 -  KIRQL OldIrql;
   6.187  
   6.188  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   6.189    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
   6.190  
   6.191 -  KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
   6.192 +  ExAcquireFastMutex(&xpdd->watch_mutex);
   6.193  
   6.194    // check that Path < 128 chars
   6.195  
   6.196 @@ -742,50 +773,21 @@ XenBus_RemWatch(
   6.197  
   6.198    if (i == MAX_WATCH_ENTRIES)
   6.199    {
   6.200 -    KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.201 +    ExReleaseFastMutex(&xpdd->watch_mutex);
   6.202      KdPrint((__DRIVER_NAME "     Watch not set - can't remove\n"));
   6.203      return NULL;
   6.204    }
   6.205  
   6.206 -  if (xpdd->XenBus_WatchEntries[i].RemovePending)
   6.207 -  {
   6.208 -    KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.209 -    KdPrint((__DRIVER_NAME "     Remove already pending - can't remove\n"));
   6.210 -    return NULL;
   6.211 -  }
   6.212 -  KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.213 -
   6.214 -  while (xpdd->XenBus_WatchEntries[i].Running)
   6.215 -    KeWaitForSingleObject(&xpdd->XenBus_WatchEntries[i].CompleteEvent, Executive, KernelMode, FALSE, NULL);
   6.216 -
   6.217 -  KeAcquireSpinLock(&xpdd->WatchLock, &OldIrql);
   6.218 -
   6.219    xpdd->XenBus_WatchEntries[i].Active = 0;
   6.220 -  xpdd->XenBus_WatchEntries[i].RemovePending = 0;
   6.221    xpdd->XenBus_WatchEntries[i].Path[0] = 0;
   6.222  
   6.223 -  KeReleaseSpinLock(&xpdd->WatchLock, OldIrql);
   6.224 -
   6.225 -  req[0].data = Path;
   6.226 -  req[0].len = (ULONG)strlen(Path) + 1;
   6.227 -
   6.228 -  RtlStringCbPrintfA(Token, ARRAY_SIZE(Token), "%d", i);
   6.229 -  req[1].data = Token;
   6.230 -  req[1].len = (ULONG)strlen(Token) + 1;
   6.231 +  ExReleaseFastMutex(&xpdd->watch_mutex);
   6.232  
   6.233 -  rep = xenbus_msg_reply(xpdd, XS_UNWATCH, xbt, req, ARRAY_SIZE(req));
   6.234 -
   6.235 -  msg = errmsg(rep);
   6.236 -  if (msg)
   6.237 -  {
   6.238 -    return msg;
   6.239 -  }
   6.240 -
   6.241 -  ExFreePoolWithTag(rep, XENPCI_POOL_TAG);
   6.242 -
   6.243 +  msg = XenBus_SendRemWatch(Context, xbt, Path, i);
   6.244 +  
   6.245  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   6.246  
   6.247 -  return NULL;
   6.248 +  return msg;
   6.249  }
   6.250  
   6.251  
     7.1 --- a/xenpci/xenpci.h	Thu Jul 24 19:53:37 2008 +1000
     7.2 +++ b/xenpci/xenpci.h	Fri Jul 25 11:17:41 2008 +1000
     7.3 @@ -96,9 +96,9 @@ typedef struct _XENBUS_WATCH_ENTRY {
     7.4    PVOID ServiceContext;
     7.5    int Count;
     7.6    int Active;
     7.7 -  int RemovePending;
     7.8 -  int Running;
     7.9 -  KEVENT CompleteEvent;
    7.10 +  //int RemovePending;
    7.11 +  //int Running;
    7.12 +  //KEVENT CompleteEvent;
    7.13  } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
    7.14  
    7.15  #define NR_EVENTS 1024
    7.16 @@ -215,7 +215,7 @@ typedef struct {
    7.17    int nr_live_reqs;
    7.18    XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
    7.19  
    7.20 -  KSPIN_LOCK WatchLock;
    7.21 +  FAST_MUTEX watch_mutex;
    7.22    FAST_MUTEX xenbus_mutex;
    7.23    KSPIN_LOCK grant_lock;
    7.24  
     8.1 --- a/xenpci/xenpci_fdo.c	Thu Jul 24 19:53:37 2008 +1000
     8.2 +++ b/xenpci/xenpci_fdo.c	Fri Jul 25 11:17:41 2008 +1000
     8.3 @@ -30,16 +30,8 @@ static VOID
     8.4  XenBus_BalloonHandler(char *Path, PVOID Data);
     8.5  #endif
     8.6  
     8.7 -/*
     8.8 -static VOID
     8.9 -XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
    8.10 -*/
    8.11 -
    8.12  #pragma warning(disable : 4200) // zero-sized array
    8.13  
    8.14 -//CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
    8.15 -//CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
    8.16 -
    8.17  NTSTATUS
    8.18  XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp)
    8.19  {
    8.20 @@ -305,10 +297,17 @@ XenBus_ShutdownIoCancel(PDEVICE_OBJECT d
    8.21    FUNCTION_EXIT();
    8.22  }
    8.23  
    8.24 +#define SPIN_STATE_NONE 0
    8.25 +#define SPIN_STATE_DPC1 1
    8.26 +#define SPIN_STATE_HIGH 2
    8.27 +#define SPIN_STATE_DPC2 3
    8.28 +
    8.29  struct {
    8.30 -  volatile ULONG do_spin;
    8.31 -  volatile LONG nr_spinning;
    8.32 -  KEVENT stopped_spinning_event;
    8.33 +  volatile ULONG spin_state;
    8.34 +  volatile LONG nr_spinning_dpc1;
    8.35 +  volatile LONG nr_spinning_high;
    8.36 +  volatile LONG nr_spinning_dpc2;
    8.37 +  KEVENT spin_event;
    8.38  } typedef SUSPEND_INFO, *PSUSPEND_INFO;
    8.39  
    8.40  /* runs at PASSIVE_LEVEL */
    8.41 @@ -324,22 +323,21 @@ XenPci_CompleteResume(PDEVICE_OBJECT dev
    8.42  
    8.43    xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
    8.44  
    8.45 -  while (suspend_info->nr_spinning != 0)
    8.46 +  while (suspend_info->nr_spinning_dpc2 != 0)
    8.47    {
    8.48 -    KdPrint((__DRIVER_NAME "     %d processors are still spinning\n", suspend_info->nr_spinning));
    8.49 -    KeWaitForSingleObject(&suspend_info->stopped_spinning_event, Executive, KernelMode, FALSE, NULL);
    8.50 +    KdPrint((__DRIVER_NAME "     %d processors are still spinning at dpc2\n", suspend_info->nr_spinning_dpc2));
    8.51 +    KeWaitForSingleObject(&suspend_info->spin_event, Executive, KernelMode, FALSE, NULL);
    8.52    }
    8.53 -  KdPrint((__DRIVER_NAME "     all other processors have stopped spinning\n"));
    8.54 +  KdPrint((__DRIVER_NAME "     all other processors have stopped spinning at dpc2\n"));
    8.55  
    8.56    /* this has to be done at PASSIVE_LEVEL */
    8.57 -  EvtChn_ConnectInterrupt(xpdd);
    8.58 +  //EvtChn_ConnectInterrupt(xpdd);
    8.59  
    8.60    XenBus_Resume(xpdd);
    8.61  
    8.62    for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
    8.63    {
    8.64      XenPci_Pdo_Resume(child->context->common.pdo);
    8.65 -    child->context->device_state.resume_state = RESUME_STATE_FRONTEND_RESUME;
    8.66      // how can we signal children that they are ready to restart again?
    8.67      // maybe we can fake an interrupt?
    8.68    }
    8.69 @@ -374,44 +372,69 @@ XenPci_Suspend(
    8.70  
    8.71    if (KeGetCurrentProcessorNumber() != 0)
    8.72    {
    8.73 -    KeRaiseIrql(HIGH_LEVEL, &old_irql);
    8.74 -    KdPrint((__DRIVER_NAME "     spinning...\n"));
    8.75 -    InterlockedIncrement(&suspend_info->nr_spinning);
    8.76 -    KeMemoryBarrier();
    8.77 -    while(suspend_info->do_spin)
    8.78 +    KdPrint((__DRIVER_NAME "     CPU %d spinning at dpc1...\n", KeGetCurrentProcessorNumber()));
    8.79 +    InterlockedIncrement(&suspend_info->nr_spinning_dpc1);
    8.80 +    while(suspend_info->spin_state == SPIN_STATE_DPC1)
    8.81      {
    8.82        KeStallExecutionProcessor(1);
    8.83        KeMemoryBarrier();
    8.84        /* can't call HYPERVISOR_yield() here as the stubs will be reset and we will crash */
    8.85      }
    8.86 -    KeMemoryBarrier();
    8.87 -    InterlockedDecrement(&suspend_info->nr_spinning);    
    8.88 -    KdPrint((__DRIVER_NAME "     ...done spinning\n"));
    8.89 -    FUNCTION_MSG(("(CPU = %d)\n", KeGetCurrentProcessorNumber()));
    8.90 +    InterlockedDecrement(&suspend_info->nr_spinning_dpc1);    
    8.91 +    KdPrint((__DRIVER_NAME "     CPU %d done spinning at dpc1\n", KeGetCurrentProcessorNumber()));
    8.92 +    KeRaiseIrql(HIGH_LEVEL, &old_irql);
    8.93 +    KdPrint((__DRIVER_NAME "     CPU %d spinning at high...\n", KeGetCurrentProcessorNumber()));
    8.94 +    InterlockedIncrement(&suspend_info->nr_spinning_high);
    8.95 +    while(suspend_info->spin_state == SPIN_STATE_HIGH)
    8.96 +    {
    8.97 +      KeStallExecutionProcessor(1);
    8.98 +      KeMemoryBarrier();
    8.99 +      /* can't call HYPERVISOR_yield() here as the stubs will be reset and we will crash */
   8.100 +    }
   8.101 +    InterlockedDecrement(&suspend_info->nr_spinning_high);    
   8.102 +    KdPrint((__DRIVER_NAME "     CPU %d done spinning at high\n", KeGetCurrentProcessorNumber()));
   8.103      KeLowerIrql(old_irql);
   8.104 -    KeSetEvent(&suspend_info->stopped_spinning_event, IO_NO_INCREMENT, FALSE);
   8.105 +
   8.106 +    KdPrint((__DRIVER_NAME "     CPU %d spinning at dpc2...\n", KeGetCurrentProcessorNumber()));
   8.107 +    InterlockedIncrement(&suspend_info->nr_spinning_dpc2);
   8.108 +    while(suspend_info->spin_state == SPIN_STATE_DPC2)
   8.109 +    {
   8.110 +      KeStallExecutionProcessor(1);
   8.111 +      KeMemoryBarrier();
   8.112 +      /* can't call HYPERVISOR_yield() here as the stubs will be reset and we will crash */
   8.113 +    }
   8.114 +    InterlockedDecrement(&suspend_info->nr_spinning_dpc2);
   8.115 +    KdPrint((__DRIVER_NAME "     CPU %d done spinning at dpc2\n", KeGetCurrentProcessorNumber()));
   8.116 +    KeSetEvent(&suspend_info->spin_event, IO_NO_INCREMENT, FALSE);
   8.117      FUNCTION_EXIT();
   8.118      return;
   8.119    }
   8.120    ActiveProcessorCount = (ULONG)KeNumberProcessors;
   8.121  
   8.122 -  KeRaiseIrql(HIGH_LEVEL, &old_irql);
   8.123 -  
   8.124 -  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
   8.125 -  while (suspend_info->nr_spinning < (LONG)ActiveProcessorCount - 1)
   8.126 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin at dpc1\n"));
   8.127 +  while (suspend_info->nr_spinning_dpc1 < (LONG)ActiveProcessorCount - 1)
   8.128    {
   8.129        HYPERVISOR_yield(xpdd);
   8.130        KeMemoryBarrier();
   8.131    }
   8.132 -  KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
   8.133 -
   8.134 +  KdPrint((__DRIVER_NAME "     all other processors are spinning at dpc1\n"));
   8.135 +  KeRaiseIrql(HIGH_LEVEL, &old_irql);
   8.136 +  
   8.137 +  suspend_info->spin_state = SPIN_STATE_HIGH;
   8.138    xpdd->suspend_state = SUSPEND_STATE_HIGH_IRQL;
   8.139    KeMemoryBarrier();
   8.140 -  
   8.141 +
   8.142 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin at high\n"));
   8.143 +  while (suspend_info->nr_spinning_high < (LONG)ActiveProcessorCount - 1)
   8.144 +  {
   8.145 +      HYPERVISOR_yield(xpdd);
   8.146 +      KeMemoryBarrier();
   8.147 +  }
   8.148 +  KdPrint((__DRIVER_NAME "     all other processors are spinning at high\n"));
   8.149    KdPrint((__DRIVER_NAME "     calling suspend\n"));
   8.150    cancelled = hvm_shutdown(Context, SHUTDOWN_suspend);
   8.151    KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
   8.152 -
   8.153 +  
   8.154    XenPci_Init(xpdd);
   8.155    
   8.156    GntTbl_InitMap(Context);
   8.157 @@ -423,13 +446,20 @@ XenPci_Suspend(
   8.158    {
   8.159      child->context->device_state.resume_state = RESUME_STATE_BACKEND_RESUME;
   8.160    }
   8.161 -
   8.162    KeLowerIrql(old_irql);
   8.163    xpdd->suspend_state = SUSPEND_STATE_RESUMING;
   8.164 +  suspend_info->spin_state = SPIN_STATE_DPC2;
   8.165    KeMemoryBarrier();
   8.166    
   8.167 +  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin at dpc2\n"));
   8.168 +  while (suspend_info->nr_spinning_dpc2 < (LONG)ActiveProcessorCount - 1)
   8.169 +  {
   8.170 +      HYPERVISOR_yield(xpdd);
   8.171 +      KeMemoryBarrier();
   8.172 +  }
   8.173 +  KdPrint((__DRIVER_NAME "     all other processors are spinning at dpc2\n"));
   8.174    KdPrint((__DRIVER_NAME "     waiting for all other processors to stop spinning\n"));
   8.175 -  suspend_info->do_spin = 0;
   8.176 +  suspend_info->spin_state = SPIN_STATE_NONE;
   8.177    KeMemoryBarrier();
   8.178  
   8.179  	work_item = IoAllocateWorkItem(xpdd->common.fdo);
   8.180 @@ -468,26 +498,24 @@ XenPci_BeginSuspend(PDEVICE_OBJECT devic
   8.181  
   8.182      suspend_info = ExAllocatePoolWithTag(NonPagedPool, sizeof(SUSPEND_INFO), XENPCI_POOL_TAG);
   8.183      RtlZeroMemory(suspend_info, sizeof(SUSPEND_INFO));
   8.184 -    KeInitializeEvent(&suspend_info->stopped_spinning_event, SynchronizationEvent, FALSE);
   8.185 -    suspend_info->do_spin = 1;
   8.186 +    KeInitializeEvent(&suspend_info->spin_event, SynchronizationEvent, FALSE);
   8.187  
   8.188 -    for (i = 0; i < MAX_VIRT_CPUS; i++)
   8.189 -    {
   8.190 -      xpdd->shared_info_area->vcpu_info[i].evtchn_upcall_mask = 1;
   8.191 -    }
   8.192 -    KeMemoryBarrier();
   8.193      EvtChn_Shutdown(xpdd);
   8.194  
   8.195      //ActiveProcessorCount = KeQueryActiveProcessorCount(&ActiveProcessorMask); // this is for Vista+
   8.196      ActiveProcessorCount = (ULONG)KeNumberProcessors;
   8.197      KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
   8.198 +    suspend_info->spin_state = SPIN_STATE_DPC1;
   8.199      for (i = 0; i < ActiveProcessorCount; i++)
   8.200      {
   8.201        Dpc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), XENPCI_POOL_TAG);
   8.202        KeInitializeDpc(Dpc, XenPci_Suspend, xpdd);
   8.203        KeSetTargetProcessorDpc(Dpc, (CCHAR)i);
   8.204 +      KdPrint((__DRIVER_NAME "     queuing Dpc for CPU %d\n", i));
   8.205        KeInsertQueueDpc(Dpc, suspend_info, NULL);
   8.206      }
   8.207 +    KdPrint((__DRIVER_NAME "     All Dpc's queued\n"));
   8.208 +    KeMemoryBarrier();
   8.209      KeLowerIrql(OldIrql);
   8.210    }
   8.211    FUNCTION_EXIT();
   8.212 @@ -553,7 +581,6 @@ XenBus_DummyXenbusThreadProc(PVOID Start
   8.213    PXENPCI_DEVICE_DATA xpdd = StartContext;
   8.214    char *value;
   8.215    char *err;
   8.216 -  LARGE_INTEGER wait_time;
   8.217    int thread_id;
   8.218    
   8.219    thread_id = (int)PsGetCurrentThreadId();
   8.220 @@ -1039,16 +1066,45 @@ XenPci_Pnp_FilterResourceRequirementsCal
   8.221    NTSTATUS status = STATUS_SUCCESS;
   8.222    //PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   8.223    PIRP irp = context;
   8.224 -  PIO_RESOURCE_REQUIREMENTS_LIST irrl;
   8.225 -  ULONG irl;
   8.226 -  ULONG ird;
   8.227 +#if 0
   8.228 +  PIO_RESOURCE_REQUIREMENTS_LIST old_irrl;
   8.229 +  PIO_RESOURCE_REQUIREMENTS_LIST new_irrl;
   8.230 +  //ULONG irl;
   8.231 +  //ULONG ird;
   8.232 +  PIO_RESOURCE_LIST irl;
   8.233 +  PIO_RESOURCE_DESCRIPTOR ird;
   8.234 +#endif
   8.235  
   8.236    UNREFERENCED_PARAMETER(device_object);
   8.237  
   8.238    FUNCTION_ENTER();
   8.239    FUNCTION_MSG(("IoStatus.status = %08X\n", irp->IoStatus.Status));
   8.240 +
   8.241 +#if 0  
   8.242 +  /* this assumes that AlternativeLists == 1 */
   8.243 +  old_irrl = (PIO_RESOURCE_REQUIREMENTS_LIST)irp->IoStatus.Information;
   8.244 +  new_irrl = ExAllocatePoolWithTag(NonPagedPool, old_irrl->ListSize + sizeof(IO_RESOURCE_DESCRIPTOR) * 1, XENPCI_POOL_TAG);
   8.245 +  memcpy(new_irrl, old_irrl, old_irrl->ListSize);
   8.246    
   8.247 -  irrl = (PIO_RESOURCE_REQUIREMENTS_LIST)irp->IoStatus.Information;
   8.248 +  irl = &new_irrl->List[0];
   8.249 +  ird = &irl->Descriptors[irl->Count++];
   8.250 +  RtlZeroMemory(ird, sizeof(IO_RESOURCE_DESCRIPTOR));
   8.251 +  ird->Option = 0;
   8.252 +  ird->Type = CmResourceTypeInterrupt;
   8.253 +  ird->ShareDisposition = CmResourceShareDeviceExclusive;
   8.254 +  ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
   8.255 +  ird->u.Interrupt.MinimumVector = 16;
   8.256 +  ird->u.Interrupt.MaximumVector = 63;
   8.257 +/*
   8.258 +  ird->u.AffinityPolicy = IrqPolicyMachineDefault;
   8.259 +  ird->u.PriorityPolicy = IrqPriorityNormal;
   8.260 +  ird->u.TargetedProcessors = 0;
   8.261 +*/
   8.262 +
   8.263 +  irp->IoStatus.Information = (ULONG_PTR)new_irrl;
   8.264 +  // free old_irrl
   8.265 +#endif
   8.266 +/*
   8.267    for (irl = 0; irl < irrl->AlternativeLists; irl++)
   8.268    {
   8.269      for (ird = 0; ird < irrl->List[irl].Count; ird++)
   8.270 @@ -1059,6 +1115,7 @@ XenPci_Pnp_FilterResourceRequirementsCal
   8.271        }
   8.272      }
   8.273    }
   8.274 +*/
   8.275    irp->IoStatus.Status = status;
   8.276    IoCompleteRequest (irp, IO_NO_INCREMENT);
   8.277    
     9.1 --- a/xenpci/xenpci_pdo.c	Thu Jul 24 19:53:37 2008 +1000
     9.2 +++ b/xenpci/xenpci_pdo.c	Fri Jul 25 11:17:41 2008 +1000
     9.3 @@ -150,27 +150,27 @@ XenPci_BackEndStateHandler(char *path, P
     9.4    switch (xppdd->backend_state)
     9.5    {
     9.6    case XenbusStateUnknown:
     9.7 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown\n"));  
     9.8 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Unknown (%s)\n", path));  
     9.9      break;
    9.10  
    9.11    case XenbusStateInitialising:
    9.12 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising\n"));  
    9.13 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialising (%s)\n", path));  
    9.14      break;
    9.15  
    9.16    case XenbusStateInitWait:
    9.17 -    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait\n"));  
    9.18 +    KdPrint((__DRIVER_NAME "     Backend State Changed to InitWait (%s)\n", path));  
    9.19      break;
    9.20  
    9.21    case XenbusStateInitialised:
    9.22 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised\n"));
    9.23 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Initialised (%s)\n", path));  
    9.24      break;
    9.25  
    9.26    case XenbusStateConnected:
    9.27 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected\n"));  
    9.28 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Connected (%s)\n", path));    
    9.29      break;
    9.30  
    9.31    case XenbusStateClosing:
    9.32 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing\n"));
    9.33 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closing (%s)\n", path));  
    9.34      if (xpdd->suspend_state == SUSPEND_STATE_NONE)
    9.35      {
    9.36        if (xppdd->common.device_usage_paging
    9.37 @@ -198,11 +198,11 @@ XenPci_BackEndStateHandler(char *path, P
    9.38      break;
    9.39  
    9.40    case XenbusStateClosed:
    9.41 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed\n"));  
    9.42 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Closed (%s)\n", path));  
    9.43      break;
    9.44  
    9.45    default:
    9.46 -    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d\n", xppdd->backend_state));
    9.47 +    KdPrint((__DRIVER_NAME "     Backend State Changed to Undefined = %d (%s)\n", xppdd->backend_state, path));
    9.48      break;
    9.49    }
    9.50  
    9.51 @@ -240,8 +240,8 @@ XenPci_ChangeFrontendState(PXENPCI_PDO_D
    9.52    XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
    9.53  
    9.54    remaining = maximum_wait_ms;
    9.55 -  /* we can't rely on xppdd->backend_state here - events can occasionally be missed on startup or resume! */
    9.56 -  while (XenPci_ReadBackendState(xppdd) != backend_state_response)
    9.57 +
    9.58 +  while (xppdd->backend_state != backend_state_response)
    9.59    {
    9.60      thiswait = min((LONG)remaining, 1000); // 1 second or remaining time, whichever is less
    9.61      timeout.QuadPart = (LONGLONG)-1 * thiswait * 1000 * 10;
    9.62 @@ -709,15 +709,16 @@ XenPci_Pdo_Resume(PDEVICE_OBJECT device_
    9.63    old_backend_state = xppdd->backend_state;
    9.64    status = XenPci_GetBackendAndAddWatch(device_object);
    9.65    if (!NT_SUCCESS(status)) {
    9.66 +    KdPrint((__DRIVER_NAME "     Failed to remove old watch\n"));
    9.67      FUNCTION_ERROR_EXIT();
    9.68      return status;
    9.69    }
    9.70    
    9.71    if (xppdd->common.current_pnp_state == Started && old_backend_state == XenbusStateClosed)
    9.72 -  {
    9.73 -  
    9.74 +  {  
    9.75      if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000) != STATUS_SUCCESS)
    9.76      {
    9.77 +      KdPrint((__DRIVER_NAME "     Failed to change frontend state to Initialising\n"));
    9.78        // this is probably an unrecoverable situation...
    9.79        FUNCTION_ERROR_EXIT();
    9.80        return STATUS_UNSUCCESSFUL;
    9.81 @@ -740,17 +741,24 @@ XenPci_Pdo_Resume(PDEVICE_OBJECT device_
    9.82      if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
    9.83      {
    9.84        // this is definitely an unrecoverable situation...
    9.85 +      KdPrint((__DRIVER_NAME "     Failed to change frontend state to connected\n"));
    9.86        FUNCTION_ERROR_EXIT();
    9.87        return STATUS_UNSUCCESSFUL;
    9.88      }
    9.89    }
    9.90 +  else
    9.91 +  {
    9.92 +    KdPrint((__DRIVER_NAME "     Not resuming - current_pnp_state = %d, old_backend_state = %d\n", xppdd->common.current_pnp_state, old_backend_state));
    9.93 +  }
    9.94 +  KeMemoryBarrier();
    9.95 +  xppdd->device_state.resume_state = RESUME_STATE_FRONTEND_RESUME;
    9.96  
    9.97    FUNCTION_EXIT();
    9.98  
    9.99    return STATUS_SUCCESS;
   9.100  } 
   9.101  
   9.102 -/* called at DISPATCH_LEVEL */
   9.103 +/* called at PASSIVE_LEVEL */
   9.104  NTSTATUS
   9.105  XenPci_Pdo_Suspend(PDEVICE_OBJECT device_object)
   9.106  {
   9.107 @@ -890,7 +898,17 @@ XenPci_QueryResourceRequirements(PDEVICE
   9.108    PIO_RESOURCE_REQUIREMENTS_LIST irrl;
   9.109    PIO_RESOURCE_DESCRIPTOR ird;
   9.110    ULONG length;
   9.111 -  ULONG available_interrupts[] = {3, 4, 5, 10, 11, 14};
   9.112 +  //ULONG available_interrupts[] = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; //{3, 4, 5, 10, 11, 14};
   9.113 +  ULONG available_interrupts[] = {
   9.114 +    //62, 61, 60, 59, 58, 57, 56,
   9.115 +    //55, 54, 53, 52, 51, 50, 49, 48,
   9.116 +    47, 46, 45, 44, 43, 42, 41, 40,
   9.117 +    39, 38, 37, 36, 35, 34, 33, 32,
   9.118 +    31, 30, 29, 28, 27, 26, 25, 24,
   9.119 +    23, 22, 21, 20, 19, 18, 17, 16,
   9.120 +    //15, 14, 13, 12, 11, 10, 8,
   9.121 +    //7, 6, 5, 4, 3, 1
   9.122 +  };
   9.123    int i;
   9.124  
   9.125    UNREFERENCED_PARAMETER(device_object);
   9.126 @@ -903,7 +921,7 @@ XenPci_QueryResourceRequirements(PDEVICE
   9.127      XENPCI_POOL_TAG);
   9.128    
   9.129    irrl->ListSize = length;
   9.130 -  irrl->InterfaceType = Internal;
   9.131 +  irrl->InterfaceType = PCIBus;
   9.132    irrl->BusNumber = 0;
   9.133    irrl->SlotNumber = 0;
   9.134    irrl->AlternativeLists = 1;
   9.135 @@ -918,7 +936,13 @@ XenPci_QueryResourceRequirements(PDEVICE
   9.136      ird = &irrl->List[0].Descriptors[irrl->List[0].Count++];
   9.137      ird->Option = i?IO_RESOURCE_ALTERNATIVE:0;
   9.138      ird->Type = CmResourceTypeInterrupt;
   9.139 -    ird->ShareDisposition = CmResourceShareShared;
   9.140 +    if (available_interrupts[i] >= 16)
   9.141 +    {
   9.142 +      ird->Option |= IO_RESOURCE_PREFERRED;
   9.143 +      ird->ShareDisposition = CmResourceShareDeviceExclusive;
   9.144 +    }
   9.145 +    else
   9.146 +      ird->ShareDisposition = CmResourceShareShared;
   9.147      ird->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
   9.148      ird->u.Interrupt.MinimumVector = available_interrupts[i];
   9.149      ird->u.Interrupt.MaximumVector = available_interrupts[i];