win-pvdrivers

changeset 450:605747e0db9c

Added some flexibility into the frontend state transitions.
Added and collected ioport info to xpdd struct
More logging for save/restore/migrate hangs
author James Harper <james.harper@bendigoit.com.au>
date Thu Nov 13 17:27:05 2008 +1100 (2008-11-13)
parents 6159eac26b1a
children 1275f2e97b60
files xenpci/evtchn.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
line diff
     1.1 --- a/xenpci/evtchn.c	Thu Nov 13 17:19:28 2008 +1100
     1.2 +++ b/xenpci/evtchn.c	Thu Nov 13 17:27:05 2008 +1100
     1.3 @@ -93,14 +93,11 @@ to CPU != 0, but we should always use vc
     1.4    BOOLEAN deferred = FALSE;
     1.5    int i;
     1.6  
     1.7 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", KeGetCurrentProcessorNumber()));
     1.8 -
     1.9 -  if (xpdd->interrupts_masked)
    1.10 +  if (xpdd->log_interrupts)
    1.11    {
    1.12 -    KdPrint((__DRIVER_NAME "     unhandled interrupt\n"));
    1.13 -    return TRUE;
    1.14 +    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ " (cpu = %d)\n", KeGetCurrentProcessorNumber()));
    1.15    }
    1.16 -    
    1.17 +
    1.18    UNREFERENCED_PARAMETER(Interrupt);
    1.19  
    1.20    for (i = 0; i < ARRAY_SIZE(xpdd->evtchn_pending_pvt); i++)
    1.21 @@ -116,6 +113,12 @@ to CPU != 0, but we should always use vc
    1.22  
    1.23    vcpu_info->evtchn_upcall_pending = 0;
    1.24  
    1.25 +  if (xpdd->interrupts_masked)
    1.26 +  {
    1.27 +    KdPrint((__DRIVER_NAME "     unhandled interrupt\n"));
    1.28 +    return TRUE;
    1.29 +  }
    1.30 +  
    1.31    evt_words = (xen_ulong_t)xchg((volatile xen_long_t *)&vcpu_info->evtchn_pending_sel, 0);
    1.32  
    1.33    while (bit_scan_forward(&evt_word, evt_words))
    1.34 @@ -160,8 +163,10 @@ to CPU != 0, but we should always use vc
    1.35      }
    1.36    }
    1.37  
    1.38 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.39 -
    1.40 +  if (xpdd->log_interrupts)
    1.41 +  {
    1.42 +    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    1.43 +  }
    1.44    return handled && !deferred;
    1.45  }
    1.46  
     2.1 --- a/xenpci/xenpci.h	Thu Nov 13 17:19:28 2008 +1100
     2.2 +++ b/xenpci/xenpci.h	Thu Nov 13 17:27:05 2008 +1100
     2.3 @@ -189,6 +189,9 @@ typedef struct {
     2.4    ULONG platform_mmio_len;
     2.5    ULONG platform_mmio_alloc;
     2.6    USHORT platform_mmio_flags;
     2.7 +  
     2.8 +  ULONG platform_ioport_addr;
     2.9 +  ULONG platform_ioport_len;
    2.10  
    2.11    char *hypercall_stubs;
    2.12  
    2.13 @@ -242,6 +245,8 @@ typedef struct {
    2.14    ULONG shutdown_cons;
    2.15    ULONG shutdown_start; /* the start of the most recent message on the ring */
    2.16    PIRP shutdown_irp;
    2.17 +  
    2.18 +  BOOLEAN log_interrupts;
    2.19  } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
    2.20  
    2.21  typedef struct {  
     3.1 --- a/xenpci/xenpci_fdo.c	Thu Nov 13 17:19:28 2008 +1100
     3.2 +++ b/xenpci/xenpci_fdo.c	Thu Nov 13 17:27:05 2008 +1100
     3.3 @@ -334,8 +334,6 @@ XenPci_CompleteResume(PDEVICE_OBJECT dev
     3.4    for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
     3.5    {
     3.6      XenPci_Pdo_Resume(child->context->common.pdo);
     3.7 -    // how can we signal children that they are ready to restart again?
     3.8 -    // maybe we can fake an interrupt?
     3.9    }
    3.10  
    3.11    xpdd->suspend_state = SUSPEND_STATE_NONE;
    3.12 @@ -357,8 +355,6 @@ XenPci_Suspend(
    3.13    KIRQL old_irql;
    3.14    int cancelled = 0;
    3.15    PXEN_CHILD child;
    3.16 -  LARGE_INTEGER spin_abort_time;
    3.17 -  LARGE_INTEGER current_time;
    3.18    
    3.19    //PUCHAR gnttbl_backup[PAGE_SIZE * NR_GRANT_FRAMES];
    3.20  
    3.21 @@ -366,30 +362,17 @@ XenPci_Suspend(
    3.22    UNREFERENCED_PARAMETER(SystemArgument2);
    3.23  
    3.24    FUNCTION_ENTER();
    3.25 -  FUNCTION_MSG(("(CPU = %d)\n", KeGetCurrentProcessorNumber()));
    3.26 +  FUNCTION_MSG("(CPU = %d)\n", KeGetCurrentProcessorNumber());
    3.27  
    3.28    if (KeGetCurrentProcessorNumber() != 0)
    3.29    {
    3.30      KdPrint((__DRIVER_NAME "     CPU %d spinning...\n", KeGetCurrentProcessorNumber()));
    3.31 -    KeQuerySystemTime(&spin_abort_time);
    3.32 -    spin_abort_time.QuadPart += 10 * 1000 * 10000;
    3.33      KeRaiseIrql(HIGH_LEVEL, &old_irql);
    3.34      InterlockedIncrement(&suspend_info->nr_spinning);
    3.35      while(suspend_info->do_spin && !suspend_info->abort_spin)
    3.36      {
    3.37        KeStallExecutionProcessor(1);
    3.38        KeMemoryBarrier();
    3.39 -      KeQuerySystemTime(&current_time);
    3.40 -      if (current_time.QuadPart > spin_abort_time.QuadPart)
    3.41 -      {
    3.42 -        suspend_info->abort_spin = TRUE;
    3.43 -        KeMemoryBarrier();
    3.44 -        InterlockedDecrement(&suspend_info->nr_spinning);
    3.45 -        KdPrint((__DRIVER_NAME "     CPU %d waited long enough - aborting\n", KeGetCurrentProcessorNumber()));
    3.46 -KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000003, 0x00000000, 0x00000000, 0x00000000);
    3.47 -        return;
    3.48 -      }
    3.49 -      /* can't call HYPERVISOR_yield() here as the stubs will be reset and we will crash */
    3.50      }
    3.51      if (suspend_info->abort_spin)
    3.52      {
    3.53 @@ -399,16 +382,12 @@ KeBugCheckEx(('X' << 16)|('E' << 8)|('N'
    3.54      }
    3.55      KeLowerIrql(old_irql);
    3.56      InterlockedDecrement(&suspend_info->nr_spinning);
    3.57 -    KdPrint((__DRIVER_NAME "     CPU %d done spinning\n", KeGetCurrentProcessorNumber()));
    3.58      KeSetEvent(&suspend_info->spin_event, IO_NO_INCREMENT, FALSE);
    3.59      FUNCTION_EXIT();
    3.60      return;
    3.61    }
    3.62    ActiveProcessorCount = (ULONG)KeNumberProcessors;
    3.63  
    3.64 -  KdPrint((__DRIVER_NAME "     waiting for all other processors to spin\n"));
    3.65 -  KeQuerySystemTime(&spin_abort_time);
    3.66 -  spin_abort_time.QuadPart += 10 * 1000 * 10000;
    3.67    KeRaiseIrql(HIGH_LEVEL, &old_irql);
    3.68    xpdd->suspend_state = SUSPEND_STATE_HIGH_IRQL;
    3.69    while (suspend_info->nr_spinning < (LONG)ActiveProcessorCount - 1 && !suspend_info->abort_spin)
    3.70 @@ -416,16 +395,6 @@ KeBugCheckEx(('X' << 16)|('E' << 8)|('N'
    3.71      KeStallExecutionProcessor(1);
    3.72      //HYPERVISOR_yield(xpdd);
    3.73      KeMemoryBarrier();
    3.74 -
    3.75 -    KeQuerySystemTime(&current_time);
    3.76 -    if (current_time.QuadPart > spin_abort_time.QuadPart)
    3.77 -    {
    3.78 -      suspend_info->abort_spin = TRUE;
    3.79 -      KeMemoryBarrier();
    3.80 -      KdPrint((__DRIVER_NAME "     CPU %d waited long enough - aborting\n", KeGetCurrentProcessorNumber()));
    3.81 -KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000003, 0x00000002, 0x00000000, 0x00000000);
    3.82 -      return;
    3.83 -    }
    3.84    }
    3.85    if (suspend_info->abort_spin)
    3.86    {
    3.87 @@ -433,8 +402,6 @@ KeBugCheckEx(('X' << 16)|('E' << 8)|('N'
    3.88  KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000003, 0x00000003, 0x00000000, 0x00000000);
    3.89      return;
    3.90    }
    3.91 -  KdPrint((__DRIVER_NAME "     all other processors are spinning\n"));
    3.92 -  KdPrint((__DRIVER_NAME "     calling suspend\n"));
    3.93    cancelled = hvm_shutdown(Context, SHUTDOWN_suspend);
    3.94    KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
    3.95    
    3.96 @@ -454,12 +421,6 @@ KeBugCheckEx(('X' << 16)|('E' << 8)|('N'
    3.97    suspend_info->do_spin = FALSE;
    3.98    KeMemoryBarrier();  
    3.99    KeSetEvent(&suspend_info->resume_event, IO_NO_INCREMENT, FALSE);
   3.100 -
   3.101 -/*
   3.102 -	work_item = IoAllocateWorkItem(xpdd->common.fdo);
   3.103 -  KdPrint((__DRIVER_NAME "     work_item = %x\n", work_item));
   3.104 -	IoQueueWorkItem(work_item, XenPci_CompleteResume, DelayedWorkQueue, suspend_info);
   3.105 -*/  
   3.106    FUNCTION_EXIT();
   3.107  }
   3.108  
   3.109 @@ -515,7 +476,10 @@ XenPci_BeginSuspend(PDEVICE_OBJECT devic
   3.110      KdPrint((__DRIVER_NAME "     All Dpc's queued\n"));
   3.111      KeMemoryBarrier();
   3.112      KeLowerIrql(OldIrql);
   3.113 +    KdPrint((__DRIVER_NAME "     Waiting for resume_event\n"));
   3.114      KeWaitForSingleObject(&suspend_info->resume_event, Executive, KernelMode, FALSE, NULL);
   3.115 +    KdPrint((__DRIVER_NAME "     Got resume_event\n"));
   3.116 +    //xpdd->log_interrupts = TRUE;
   3.117      XenPci_CompleteResume(device_object, suspend_info);
   3.118    }
   3.119    FUNCTION_EXIT();
   3.120 @@ -627,17 +591,32 @@ XenPci_SysrqHandler(char *path, PVOID co
   3.121    {
   3.122    case 0:
   3.123      break;
   3.124 -  case 'B':
   3.125 +  case 'B': /* cause a bug check */
   3.126      KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000001, 0x00000000, 0x00000000, 0x00000000);
   3.127      break;
   3.128 -#if 0
   3.129 -  case 'X':
   3.130 -    break;
   3.131 -#endif
   3.132 +  case 'X': /* stop delivering events */
   3.133 +  	xpdd->interrupts_masked = TRUE;
   3.134 +    break;    
   3.135    case 'C':
   3.136      /* show some debugging info */
   3.137    	XenPci_DumpPdoConfigs(xpdd);
   3.138      break;
   3.139 +  case 'M':
   3.140 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'H');
   3.141 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'e');
   3.142 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'l');
   3.143 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'l');
   3.144 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'o');
   3.145 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, ' ');
   3.146 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'w');
   3.147 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'o');
   3.148 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'r');
   3.149 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'l');
   3.150 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'd');
   3.151 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, ' ');
   3.152 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, 'X');
   3.153 +    WRITE_PORT_UCHAR((PUCHAR)xpdd->platform_ioport_addr, '\n');
   3.154 +    break;
   3.155    default:
   3.156      KdPrint(("     Unhandled sysrq letter %c\n", letter));
   3.157      break;
   3.158 @@ -655,7 +634,7 @@ XenPci_DeviceWatchHandler(char *path, PV
   3.159    char *value;
   3.160    PXENPCI_DEVICE_DATA xpdd = context;
   3.161  
   3.162 -//  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.163 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.164  
   3.165  //  KdPrint((__DRIVER_NAME "     path = %s\n", path));
   3.166    bits = SplitString(path, '/', 4, &count);
   3.167 @@ -679,7 +658,7 @@ XenPci_DeviceWatchHandler(char *path, PV
   3.168    }
   3.169    FreeSplitString(bits, count);
   3.170  
   3.171 -//  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.172 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.173  }
   3.174  
   3.175  static DDKAPI VOID
   3.176 @@ -690,7 +669,7 @@ XenPci_Pnp_StartDeviceCallback(PDEVICE_O
   3.177    PIRP irp = context;
   3.178    char *response;
   3.179  
   3.180 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.181 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.182    
   3.183    XenPci_Init(xpdd);
   3.184  
   3.185 @@ -702,17 +681,17 @@ XenPci_Pnp_StartDeviceCallback(PDEVICE_O
   3.186    XenBus_Init(xpdd);
   3.187  
   3.188    response = XenBus_AddWatch(xpdd, XBT_NIL, SYSRQ_PATH, XenPci_SysrqHandler, xpdd);
   3.189 -  KdPrint((__DRIVER_NAME "     sysrqwatch response = '%s'\n", response)); 
   3.190 +  KdPrint((__DRIVER_NAME "     sysrqwatch response = '%s'\n", response));
   3.191    
   3.192    response = XenBus_AddWatch(xpdd, XBT_NIL, SHUTDOWN_PATH, XenPci_ShutdownHandler, xpdd);
   3.193 -  KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response)); 
   3.194 +  KdPrint((__DRIVER_NAME "     shutdown watch response = '%s'\n", response));
   3.195  
   3.196    response = XenBus_AddWatch(xpdd, XBT_NIL, "device", XenPci_DeviceWatchHandler, xpdd);
   3.197 -  KdPrint((__DRIVER_NAME "     device watch response = '%s'\n", response)); 
   3.198 +  KdPrint((__DRIVER_NAME "     device watch response = '%s'\n", response));
   3.199  
   3.200  #if 0
   3.201    response = XenBus_AddWatch(xpdd, XBT_NIL, BALLOON_PATH, XenPci_BalloonHandler, Device);
   3.202 -  KdPrint((__DRIVER_NAME "     balloon watch response = '%s'\n", response)); 
   3.203 +  KdPrint((__DRIVER_NAME "     balloon watch response = '%s'\n", response));
   3.204  #endif
   3.205  
   3.206    status = IoSetDeviceInterfaceState(&xpdd->interface_name, TRUE);
   3.207 @@ -725,7 +704,7 @@ XenPci_Pnp_StartDeviceCallback(PDEVICE_O
   3.208    
   3.209    IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.210  
   3.211 -  //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
   3.212 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   3.213  }
   3.214  
   3.215  static NTSTATUS
   3.216 @@ -758,7 +737,7 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   3.217      case CmResourceTypeInterrupt:
   3.218        KdPrint((__DRIVER_NAME "     irq_number = %03x\n", res_descriptor->u.Interrupt.Vector));
   3.219        xpdd->irq_number = res_descriptor->u.Interrupt.Vector;
   3.220 -      //memcpy(&InterruptRaw, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   3.221 +      //memcpy(&InterruptRaw, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
   3.222        break;
   3.223      }
   3.224    }
   3.225 @@ -770,6 +749,9 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   3.226      res_descriptor = &res_list->PartialDescriptors[i];
   3.227      switch (res_descriptor->Type) {
   3.228      case CmResourceTypePort:
   3.229 +      KdPrint((__DRIVER_NAME "     IoPort Address(%x) Length: %d\n", res_descriptor->u.Port.Start.LowPart, res_descriptor->u.Port.Length));
   3.230 +      xpdd->platform_ioport_addr = res_descriptor->u.Port.Start.LowPart;
   3.231 +      xpdd->platform_ioport_len = res_descriptor->u.Port.Length;
   3.232        break;
   3.233      case CmResourceTypeMemory:
   3.234        KdPrint((__DRIVER_NAME "     Memory mapped CSR:(%x:%x) Length:(%d)\n", res_descriptor->u.Memory.Start.LowPart, res_descriptor->u.Memory.Start.HighPart, res_descriptor->u.Memory.Length));
   3.235 @@ -790,7 +772,7 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
   3.236        //memcpy(&InterruptTranslated, res_descriptor, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
   3.237        break;
   3.238      case CmResourceTypeDevicePrivate:
   3.239 -      KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", res_descriptor->u.DevicePrivate.Data[0], res_descriptor->u.DevicePrivate.Data[1], res_descriptor->u.DevicePrivate.Data[2] ));
   3.240 +      KdPrint((__DRIVER_NAME "     Private Data: 0x%02x 0x%02x 0x%02x\n", res_descriptor->u.DevicePrivate.Data[0], res_descriptor->u.DevicePrivate.Data[1], res_descriptor->u.DevicePrivate.Data[2]));
   3.241        break;
   3.242      default:
   3.243        KdPrint((__DRIVER_NAME "     Unhandled resource type (0x%x)\n", res_descriptor->Type));
   3.244 @@ -1030,7 +1012,7 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
   3.245      {
   3.246        if (child->state == CHILD_STATE_DELETED)
   3.247        {
   3.248 -        KdPrint((__DRIVER_NAME "     Removing deleted child from device list\n" ));
   3.249 +        KdPrint((__DRIVER_NAME "     Removing deleted child from device list\n"));
   3.250          old_child = child;
   3.251          child = (PXEN_CHILD)child->entry.Flink;
   3.252          RemoveEntryList((PLIST_ENTRY)old_child);
   3.253 @@ -1097,6 +1079,7 @@ static DDKAPI VOID
   3.254  XenPci_Pnp_FilterResourceRequirementsCallback(PDEVICE_OBJECT device_object, PVOID context)
   3.255  {
   3.256    NTSTATUS status = STATUS_SUCCESS;
   3.257 +  //PXENPCI_DEVICE_DATA xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.258    PIRP irp = context;
   3.259    PIO_RESOURCE_REQUIREMENTS_LIST irrl;
   3.260    PIO_RESOURCE_LIST irl;
   3.261 @@ -1109,14 +1092,16 @@ XenPci_Pnp_FilterResourceRequirementsCal
   3.262  
   3.263    /* this assumes that AlternativeLists == 1 */
   3.264    irrl = (PIO_RESOURCE_REQUIREMENTS_LIST)irp->IoStatus.Information;
   3.265 +  KdPrint(("AlternativeLists = %d\n", irrl->AlternativeLists));
   3.266    irl = &irrl->List[0];
   3.267    for (i = 0; i < irl->Count; i++)
   3.268    {
   3.269      ird = &irl->Descriptors[i];
   3.270 -    if (ird->Type == CmResourceTypeInterrupt && ird->ShareDisposition != CmResourceShareShared)
   3.271 +    if (ird->Type == CmResourceTypeInterrupt)
   3.272      {
   3.273 -      //ird->ShareDisposition = CmResourceShareShared;
   3.274 -      //KdPrint((__DRIVER_NAME "     Set interrupt to shared\n"));
   3.275 +      /* IRQ's < 16 (eg ISA interrupts) don't work reliably, so don't allow them. */
   3.276 +      KdPrint(("MinimumVector = %d, MaximumVector = %d\n", ird->u.Interrupt.MinimumVector, ird->u.Interrupt.MaximumVector));
   3.277 +      ird->u.Interrupt.MinimumVector = 16;
   3.278      }
   3.279    }
   3.280    irp->IoStatus.Status = status;
   3.281 @@ -1209,12 +1194,10 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
   3.282  {
   3.283    NTSTATUS status;
   3.284    PIO_STACK_LOCATION stack;
   3.285 -  PXENPCI_DEVICE_DATA xpdd;
   3.286 +  PXENPCI_DEVICE_DATA xpdd = device_object->DeviceExtension;;
   3.287  
   3.288    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   3.289  
   3.290 -  xpdd = (PXENPCI_DEVICE_DATA)device_object->DeviceExtension;
   3.291 -
   3.292    stack = IoGetCurrentIrpStackLocation(irp);
   3.293  
   3.294    switch (stack->MinorFunction)
   3.295 @@ -1297,7 +1280,7 @@ XenPci_Pnp_Fdo(PDEVICE_OBJECT device_obj
   3.296        irp->IoStatus.Status = STATUS_SUCCESS;
   3.297        break;
   3.298      default:
   3.299 -      KdPrint((__DRIVER_NAME "     type = unsupported (%d)\n", stack->Parameters.UsageNotification.Type));      
   3.300 +      KdPrint((__DRIVER_NAME "     type = unsupported (%d)\n", stack->Parameters.UsageNotification.Type));
   3.301        irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
   3.302        IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.303        return STATUS_NOT_SUPPORTED;
   3.304 @@ -1460,7 +1443,7 @@ XenPci_SystemControl_Fdo(PDEVICE_OBJECT 
   3.305    UNREFERENCED_PARAMETER(device_object);
   3.306  
   3.307    stack = IoGetCurrentIrpStackLocation(irp);
   3.308 -  KdPrint((__DRIVER_NAME "     Minor = %d\n", stack->MinorFunction));
   3.309 +  DbgPrint(__DRIVER_NAME "     Minor = %d\n", stack->MinorFunction);
   3.310    IoSkipCurrentIrpStackLocation(irp);
   3.311    status = IoCallDriver(common->lower_do, irp);
   3.312  
     4.1 --- a/xenpci/xenpci_pdo.c	Thu Nov 13 17:19:28 2008 +1100
     4.2 +++ b/xenpci/xenpci_pdo.c	Thu Nov 13 17:27:05 2008 +1100
     4.3 @@ -222,6 +222,7 @@ struct dummy_sring {
     4.4  Called at PASSIVE_LEVEL
     4.5  Called during restore
     4.6  */
     4.7 +
     4.8  static NTSTATUS
     4.9  XenPci_ChangeFrontendState(PXENPCI_PDO_DEVICE_DATA xppdd, ULONG frontend_state_set, ULONG backend_state_response, ULONG maximum_wait_ms)
    4.10  {
    4.11 @@ -233,8 +234,6 @@ XenPci_ChangeFrontendState(PXENPCI_PDO_D
    4.12    
    4.13    //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    4.14  
    4.15 -  /* Tell backend we're going down */
    4.16 -  //strcpy(path, xppdd->path);
    4.17    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->path);
    4.18    XenBus_Printf(xpdd, XBT_NIL, path, "%d", frontend_state_set);
    4.19  
    4.20 @@ -472,7 +471,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    4.21    PUCHAR out_ptr; //, out_start;
    4.22    XENPCI_VECTORS vectors;
    4.23    ULONG event_channel;
    4.24 -  BOOLEAN run = FALSE;
    4.25 +  ULONG run_type = 0;
    4.26    PMDL ring;
    4.27    grant_ref_t gref;
    4.28    BOOLEAN done_xenbus_init = FALSE;
    4.29 @@ -521,7 +520,8 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    4.30      switch (type)
    4.31      {
    4.32      case XEN_INIT_TYPE_RUN:
    4.33 -      run = TRUE;
    4.34 +      run_type++;
    4.35 +      break;
    4.36      case XEN_INIT_TYPE_WRITE_STRING: /* frontend setting = value */
    4.37        //KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_WRITE_STRING - %s = %s\n", setting, value));
    4.38        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/%s", xppdd->path, setting);
    4.39 @@ -583,9 +583,10 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    4.40    {
    4.41      goto error;
    4.42    }
    4.43 -  if (run)
    4.44 +  // If XEN_INIT_TYPE_RUN was specified more than once then we skip XenbusStateInitialised here and go straight to XenbusStateConnected at the end
    4.45 +  if (run_type == 1)
    4.46    {
    4.47 -    if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
    4.48 +    if (XenPci_ChangeFrontendState(xppdd, XenbusStateInitialised, XenbusStateConnected, 30000) != STATUS_SUCCESS)
    4.49      {
    4.50        status = STATUS_UNSUCCESSFUL;
    4.51        goto error;
    4.52 @@ -637,8 +638,20 @@ XenPci_XenConfigDeviceSpecifyBuffers(PVO
    4.53      }
    4.54    }
    4.55    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL);
    4.56 +
    4.57 +  if (run_type)
    4.58 +  {
    4.59 +    if (XenPci_ChangeFrontendState(xppdd, XenbusStateConnected, XenbusStateConnected, 30000) != STATUS_SUCCESS)
    4.60 +    {
    4.61 +      status = STATUS_UNSUCCESSFUL;
    4.62 +      goto error;
    4.63 +    }
    4.64 +  }
    4.65 +  FUNCTION_EXIT();
    4.66 +  return status;
    4.67    
    4.68  error:
    4.69 +  XenPci_ChangeFrontendState(xppdd, XenbusStateInitialising, XenbusStateInitWait, 30000);
    4.70    FUNCTION_EXIT_STATUS(status);
    4.71  
    4.72    return status;