win-pvdrivers

changeset 425:ea14db3ca6f2

Don't disable xen drivers when gplpv isn't specified. Instead just make the xennet driver always report cable disconnected, and xenvbd not enumerate any disks.
author James Harper <james.harper@bendigoit.com.au>
date Thu Sep 04 22:31:38 2008 +1000 (2008-09-04)
parents 37ed25854efa
children 9b712742b8e8
files dirs installer.nsi xenhide/xenhide.c xennet/xennet.c xennet/xennet.h xennet/xennet_oid.c xenpci/xenpci_pdo.c xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/dirs	Thu Sep 04 22:26:18 2008 +1000
     1.2 +++ b/dirs	Thu Sep 04 22:31:38 2008 +1000
     1.3 @@ -1,1 +1,1 @@
     1.4 -DIRS=xenpci xenhide xenvbd xennet xenscsi xenstub xenconfig
     1.5 \ No newline at end of file
     1.6 +DIRS=xenpci xenhide xenvbd xennet xenscsi xenstub xenconfig copyconfig
     1.7 \ No newline at end of file
     2.1 --- a/installer.nsi	Thu Sep 04 22:26:18 2008 +1000
     2.2 +++ b/installer.nsi	Thu Sep 04 22:31:38 2008 +1000
     2.3 @@ -3,7 +3,7 @@
     2.4  
     2.5  !define AppName "Xen PV Drivers"
     2.6  !define StartMenu "$SMPROGRAMS\${AppName}"
     2.7 -!define Version "0.9.11-pre13"
     2.8 +!define Version "0.9.11-pre14"
     2.9  #!define Version "$%VERSION%"
    2.10  Name "${AppName}"
    2.11  InstallDir "$PROGRAMFILES\${AppName}"
    2.12 @@ -276,6 +276,7 @@ Var NewArch
    2.13  Function .onSelChange
    2.14    Push $0
    2.15    
    2.16 +  StrCpy $newarch $arch
    2.17    StrCmp $arch "win2k" check_xp
    2.18    SectionGetFlags ${win2k} $0
    2.19    IntOp $0 $0 & ${SF_SELECTED}
    2.20 @@ -321,35 +322,65 @@ FunctionEnd
    2.21  Function SelectSection
    2.22    Push $0
    2.23  
    2.24 -  StrCmp $arch "win2k" check_xp
    2.25 +  StrCmp $arch "win2k" set_win2k
    2.26    SectionGetFlags ${win2k} $0
    2.27    IntOp $0 $0 & ${SECTION_OFF}
    2.28    SectionSetFlags ${win2k} $0
    2.29 +  goto check_xp
    2.30 +set_win2k:
    2.31 +  SectionGetFlags ${win2k} $0
    2.32 +  IntOp $0 $0 | ${SF_SELECTED}
    2.33 +  SectionSetFlags ${win2k} $0  
    2.34  check_xp:
    2.35 -  StrCmp $arch "winxp" check_2k3x32
    2.36 +  StrCmp $arch "winxp" set_winxp
    2.37    SectionGetFlags ${winxp} $0
    2.38    IntOp $0 $0 & ${SECTION_OFF}
    2.39    SectionSetFlags ${winxp} $0
    2.40 +  goto check_2k3x32
    2.41 +set_winxp:
    2.42 +  SectionGetFlags ${winxp} $0
    2.43 +  IntOp $0 $0 | ${SF_SELECTED}
    2.44 +  SectionSetFlags ${winxp} $0  
    2.45  check_2k3x32:
    2.46 -  StrCmp $arch "win2k3x32" check_2k3x64
    2.47 +  StrCmp $arch "win2k3x32" set_2k3x32
    2.48    SectionGetFlags ${win2k3x32} $0
    2.49    IntOp $0 $0 & ${SECTION_OFF}
    2.50    SectionSetFlags ${win2k3x32} $0
    2.51 +  goto check_2k3x64
    2.52 +set_2k3x32:
    2.53 +  SectionGetFlags ${win2k3x32} $0
    2.54 +  IntOp $0 $0 | ${SF_SELECTED}
    2.55 +  SectionSetFlags ${win2k3x32} $0  
    2.56  check_2k3x64:
    2.57 -  StrCmp $arch "win2k3x64" check_2k8x32
    2.58 +  StrCmp $arch "win2k3x64" set_2k3x64
    2.59    SectionGetFlags ${win2k3x64} $0
    2.60    IntOp $0 $0 & ${SECTION_OFF}
    2.61    SectionSetFlags ${win2k3x64} $0
    2.62 +  goto check_2k8x32
    2.63 +set_2k3x64:
    2.64 +  SectionGetFlags ${win2k3x64} $0
    2.65 +  IntOp $0 $0 | ${SF_SELECTED}
    2.66 +  SectionSetFlags ${win2k3x64} $0  
    2.67  check_2k8x32:
    2.68 -  StrCmp $arch "win2k8x32" check_2k8x64
    2.69 +  StrCmp $arch "win2k8x32" set_2k8x32
    2.70    SectionGetFlags ${win2k8x32} $0
    2.71    IntOp $0 $0 & ${SECTION_OFF}
    2.72    SectionSetFlags ${win2k8x32} $0
    2.73 +  goto check_2k8x64
    2.74 +set_2k8x32:
    2.75 +  SectionGetFlags ${win2k8x32} $0
    2.76 +  IntOp $0 $0 | ${SF_SELECTED}
    2.77 +  SectionSetFlags ${win2k8x32} $0  
    2.78  check_2k8x64:
    2.79 -  StrCmp $arch "win2k8x64" done
    2.80 +  StrCmp $arch "win2k8x64" set_2k8x64
    2.81    SectionGetFlags ${win2k8x64} $0
    2.82    IntOp $0 $0 & ${SECTION_OFF}
    2.83    SectionSetFlags ${win2k8x64} $0
    2.84 +  goto done
    2.85 +set_2k8x64:
    2.86 +  SectionGetFlags ${win2k8x64} $0
    2.87 +  IntOp $0 $0 | ${SF_SELECTED}
    2.88 +  SectionSetFlags ${win2k8x64} $0  
    2.89  done:
    2.90    Pop $0
    2.91  
     3.1 --- a/xenhide/xenhide.c	Thu Sep 04 22:26:18 2008 +1000
     3.2 +++ b/xenhide/xenhide.c	Thu Sep 04 22:31:38 2008 +1000
     3.3 @@ -409,6 +409,96 @@ XenHide_SendAndWaitForIrp(PDEVICE_OBJECT
     3.4  }
     3.5  
     3.6  static NTSTATUS
     3.7 +XenHide_QueueWorkItem(PDEVICE_OBJECT device_object, PIO_WORKITEM_ROUTINE routine, PVOID context)
     3.8 +{
     3.9 +  PIO_WORKITEM work_item;
    3.10 +  NTSTATUS status = STATUS_SUCCESS;
    3.11 +
    3.12 +  work_item = IoAllocateWorkItem(device_object);
    3.13 +  IoQueueWorkItem(work_item, routine, DelayedWorkQueue, context);
    3.14 +	
    3.15 +  return status;
    3.16 +}
    3.17 +
    3.18 +static VOID
    3.19 +XenHide_Pnp_StartDeviceCallback(PDEVICE_OBJECT device_object, PVOID context)
    3.20 +{
    3.21 +  NTSTATUS status = STATUS_SUCCESS;
    3.22 +  PIRP irp = context;
    3.23 +  
    3.24 +  UNREFERENCED_PARAMETER(device_object);
    3.25 +
    3.26 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    3.27 +  
    3.28 +  irp->IoStatus.Status = status;
    3.29 +  
    3.30 +  IoCompleteRequest(irp, IO_NO_INCREMENT);
    3.31 +
    3.32 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
    3.33 +}
    3.34 +
    3.35 +/*
    3.36 +The FDO will take the existance of a 0 CmResourceTypeMemory resource to mean that it should not do anything.
    3.37 +In the case of xenvbd this means it will not report any disks. In the case of xennet ???
    3.38 +*/
    3.39 +static NTSTATUS
    3.40 +XenHide_Pnp_StartDevice_AddHideFlag(PDEVICE_OBJECT device_object, PIRP irp)
    3.41 +{
    3.42 +  NTSTATUS status;
    3.43 +  PIO_STACK_LOCATION stack;
    3.44 +  PCM_RESOURCE_LIST old_crl, new_crl;
    3.45 +  PCM_PARTIAL_RESOURCE_LIST prl;
    3.46 +  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
    3.47 +  ULONG old_length, new_length;
    3.48 +
    3.49 +  UNREFERENCED_PARAMETER(device_object);
    3.50 +
    3.51 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    3.52 +
    3.53 +  stack = IoGetCurrentIrpStackLocation(irp);
    3.54 +
    3.55 +  old_crl = stack->Parameters.StartDevice.AllocatedResourcesTranslated;
    3.56 +  old_length = FIELD_OFFSET(CM_RESOURCE_LIST, List) + 
    3.57 +    FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) +
    3.58 +    FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
    3.59 +    sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * old_crl->List[0].PartialResourceList.Count;
    3.60 +  new_length = old_length + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * 1;
    3.61 +  new_crl = ExAllocatePoolWithTag(PagedPool, new_length, XENHIDE_POOL_TAG);
    3.62 +  memcpy(new_crl, old_crl, old_length);
    3.63 +  prl = &new_crl->List[0].PartialResourceList;
    3.64 +  prd = &prl->PartialDescriptors[prl->Count++];
    3.65 +  prd->Type = CmResourceTypeMemory;
    3.66 +  prd->ShareDisposition = CmResourceShareDeviceExclusive;
    3.67 +  prd->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
    3.68 +  prd->u.Memory.Start.QuadPart = 0;
    3.69 +  prd->u.Memory.Length = 0;
    3.70 +  stack->Parameters.StartDevice.AllocatedResourcesTranslated = new_crl;
    3.71 +
    3.72 +  old_crl = stack->Parameters.StartDevice.AllocatedResources;
    3.73 +  new_crl = ExAllocatePoolWithTag(PagedPool, new_length, XENHIDE_POOL_TAG);
    3.74 +  memcpy(new_crl, old_crl, old_length);
    3.75 +  prl = &new_crl->List[0].PartialResourceList;
    3.76 +  prd = &prl->PartialDescriptors[prl->Count++];
    3.77 +  prd->Type = CmResourceTypeMemory;
    3.78 +  prd->ShareDisposition = CmResourceShareDeviceExclusive;
    3.79 +  prd->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
    3.80 +  prd->u.Memory.Start.QuadPart = (ULONGLONG)0;
    3.81 +  prd->u.Memory.Length = 0;
    3.82 +  stack->Parameters.StartDevice.AllocatedResources = new_crl;
    3.83 +
    3.84 +  // free the original resource lists???
    3.85 +
    3.86 +  IoMarkIrpPending(irp);
    3.87 +  status = XenHide_SendAndWaitForIrp(device_object, irp);
    3.88 +
    3.89 +  XenHide_QueueWorkItem(device_object, XenHide_Pnp_StartDeviceCallback, irp);
    3.90 +
    3.91 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
    3.92 +  
    3.93 +  return STATUS_PENDING;
    3.94 +}
    3.95 +
    3.96 +static NTSTATUS
    3.97  XenHide_Pnp(PDEVICE_OBJECT device_object, PIRP irp)
    3.98  {
    3.99    NTSTATUS status = STATUS_SUCCESS;
   3.100 @@ -429,8 +519,9 @@ XenHide_Pnp(PDEVICE_OBJECT device_object
   3.101      if (xhdd->hide_type == XENHIDE_TYPE_DEVICE)
   3.102      {
   3.103        //KdPrint((__DRIVER_NAME "     hide_type == XENHIDE_TYPE_DEVICE\n"));
   3.104 -      status = irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
   3.105 -      IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.106 +      //status = irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
   3.107 +      //IoCompleteRequest(irp, IO_NO_INCREMENT);
   3.108 +      status = XenHide_Pnp_StartDevice_AddHideFlag(device_object, irp);
   3.109      }
   3.110      else
   3.111      {
     4.1 --- a/xennet/xennet.c	Thu Sep 04 22:26:18 2008 +1000
     4.2 +++ b/xennet/xennet.c	Thu Sep 04 22:31:38 2008 +1000
     4.3 @@ -269,7 +269,7 @@ XenNet_InterruptDpc(NDIS_HANDLE Miniport
     4.4      KeMemoryBarrier();
     4.5      FUNCTION_EXIT();
     4.6    }
     4.7 -  if (xi->connected && xi->device_state->resume_state == RESUME_STATE_RUNNING)
     4.8 +  if (xi->connected && !xi->inactive && xi->device_state->resume_state == RESUME_STATE_RUNNING)
     4.9    {
    4.10      XenNet_TxBufferGC(xi);
    4.11      XenNet_RxBufferCheck(xi);
    4.12 @@ -383,12 +383,19 @@ XenNet_Init(
    4.13        break;
    4.14  
    4.15      case CmResourceTypeMemory:
    4.16 -      status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length);
    4.17 -      if (!NT_SUCCESS(status))
    4.18 +      if (prd->u.Memory.Start.QuadPart)
    4.19        {
    4.20 -        KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
    4.21 -        NdisFreeMemory(nrl, nrl_length, 0);
    4.22 -        return NDIS_STATUS_RESOURCES;
    4.23 +        status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length);
    4.24 +        if (!NT_SUCCESS(status))
    4.25 +        {
    4.26 +          KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
    4.27 +          NdisFreeMemory(nrl, nrl_length, 0);
    4.28 +          return NDIS_STATUS_RESOURCES;
    4.29 +        }
    4.30 +      }
    4.31 +      else
    4.32 +      {
    4.33 +        xi->inactive = TRUE;
    4.34        }
    4.35        break;
    4.36      }
     5.1 --- a/xennet/xennet.h	Thu Sep 04 22:26:18 2008 +1000
     5.2 +++ b/xennet/xennet.h	Thu Sep 04 22:31:38 2008 +1000
     5.3 @@ -207,6 +207,8 @@ typedef struct
     5.4  
     5.5  struct xennet_info
     5.6  {
     5.7 +  BOOLEAN inactive;
     5.8 +  
     5.9    /* Base device vars */
    5.10    PDEVICE_OBJECT pdo;
    5.11    PDEVICE_OBJECT fdo;
     6.1 --- a/xennet/xennet_oid.c	Thu Sep 04 22:26:18 2008 +1000
     6.2 +++ b/xennet/xennet_oid.c	Thu Sep 04 22:31:38 2008 +1000
     6.3 @@ -172,7 +172,7 @@ XenNet_QueryInformation(
     6.4          NDIS_MAC_OPTION_NO_LOOPBACK;
     6.5        break;
     6.6      case OID_GEN_MEDIA_CONNECT_STATUS:
     6.7 -      if (xi->connected)
     6.8 +      if (xi->connected && !xi->inactive)
     6.9          temp_data = NdisMediaStateConnected;
    6.10        else
    6.11          temp_data = NdisMediaStateDisconnected;
     7.1 --- a/xenpci/xenpci_pdo.c	Thu Sep 04 22:26:18 2008 +1000
     7.2 +++ b/xenpci/xenpci_pdo.c	Thu Sep 04 22:31:38 2008 +1000
     7.3 @@ -886,20 +886,23 @@ XenPci_Pnp_StartDevice(PDEVICE_OBJECT de
     7.4        xppdd->irq_level = (KIRQL)prd->u.Interrupt.Level;
     7.5        break;
     7.6      case CmResourceTypeMemory:
     7.7 -      KdPrint((__DRIVER_NAME "     CmResourceTypeMemory\n"));
     7.8 -      KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
     7.9 -      xppdd->config_page_phys = prd->u.Memory.Start;
    7.10 -      xppdd->config_page_length = prd->u.Memory.Length;
    7.11 -      xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
    7.12 -      xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
    7.13 -      
    7.14 -      status = XenPci_XenConfigDevice(xppdd);
    7.15 -      if (!NT_SUCCESS(status))
    7.16 +      if (prd->u.Memory.Start.QuadPart)
    7.17        {
    7.18 -        RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
    7.19 -        XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
    7.20 -        FUNCTION_ERROR_EXIT();
    7.21 -        return status;
    7.22 +        KdPrint((__DRIVER_NAME "     CmResourceTypeMemory\n"));
    7.23 +        KdPrint((__DRIVER_NAME "     Start = %08x, Length = %d\n", prd->u.Memory.Start.LowPart, prd->u.Memory.Length));
    7.24 +        xppdd->config_page_phys = prd->u.Memory.Start;
    7.25 +        xppdd->config_page_length = prd->u.Memory.Length;
    7.26 +        xppdd->requested_resources_start = xppdd->requested_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
    7.27 +        xppdd->assigned_resources_start = xppdd->assigned_resources_ptr = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENPCI_POOL_TAG);
    7.28 +        
    7.29 +        status = XenPci_XenConfigDevice(xppdd);
    7.30 +        if (!NT_SUCCESS(status))
    7.31 +        {
    7.32 +          RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
    7.33 +          XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
    7.34 +          FUNCTION_ERROR_EXIT();
    7.35 +          return status;
    7.36 +        }
    7.37        }
    7.38      }
    7.39    }
     8.1 --- a/xenvbd/xenvbd.c	Thu Sep 04 22:26:18 2008 +1000
     8.2 +++ b/xenvbd/xenvbd.c	Thu Sep 04 22:31:38 2008 +1000
     8.3 @@ -42,6 +42,7 @@ DRIVER_INITIALIZE DriverEntry;
     8.4  #endif
     8.5  
     8.6  static BOOLEAN dump_mode = FALSE;
     8.7 +static BOOLEAN global_inactive = FALSE;
     8.8  
     8.9  static blkif_shadow_t *
    8.10  get_shadow_from_freelist(PXENVBD_DEVICE_DATA xvdd)
    8.11 @@ -272,6 +273,38 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
    8.12    return SP_RETURN_FOUND;
    8.13  }
    8.14  
    8.15 +ULONG stat_interrupts = 0;
    8.16 +ULONG stat_interrupts_for_me = 0;
    8.17 +ULONG stat_reads = 0;
    8.18 +ULONG stat_writes = 0;
    8.19 +ULONG stat_unaligned_le_4096 = 0;
    8.20 +ULONG stat_unaligned_le_8192 = 0;
    8.21 +ULONG stat_unaligned_le_16384 = 0;
    8.22 +ULONG stat_unaligned_le_32768 = 0;
    8.23 +ULONG stat_unaligned_le_65536 = 0;
    8.24 +ULONG stat_unaligned_gt_65536 = 0;
    8.25 +ULONG stat_no_shadows = 0;
    8.26 +ULONG stat_no_grants = 0;
    8.27 +ULONG stat_outstanding_requests = 0;
    8.28 +
    8.29 +static VOID
    8.30 +XenVbd_DumpStats()
    8.31 +{
    8.32 +  KdPrint((__DRIVER_NAME "     stat_interrupts = %d\n", stat_interrupts));
    8.33 +  KdPrint((__DRIVER_NAME "     stat_interrupts_for_me = %d\n", stat_interrupts_for_me));
    8.34 +  KdPrint((__DRIVER_NAME "     stat_reads = %d\n", stat_reads));
    8.35 +  KdPrint((__DRIVER_NAME "     stat_writes = %d\n", stat_writes));
    8.36 +  KdPrint((__DRIVER_NAME "     stat_unaligned_le_4096 = %d\n", stat_unaligned_le_4096));
    8.37 +  KdPrint((__DRIVER_NAME "     stat_unaligned_le_8192 = %d\n", stat_unaligned_le_8192));
    8.38 +  KdPrint((__DRIVER_NAME "     stat_unaligned_le_16384 = %d\n", stat_unaligned_le_16384));
    8.39 +  KdPrint((__DRIVER_NAME "     stat_unaligned_le_32768 = %d\n", stat_unaligned_le_32768));
    8.40 +  KdPrint((__DRIVER_NAME "     stat_unaligned_le_65536 = %d\n", stat_unaligned_le_65536));
    8.41 +  KdPrint((__DRIVER_NAME "     stat_unaligned_gt_65536 = %d\n", stat_unaligned_gt_65536));
    8.42 +  KdPrint((__DRIVER_NAME "     stat_no_shadows = %d\n", stat_no_shadows));
    8.43 +  KdPrint((__DRIVER_NAME "     stat_no_grants = %d\n", stat_no_grants));
    8.44 +  KdPrint((__DRIVER_NAME "     stat_outstanding_requests = %d\n", stat_outstanding_requests));
    8.45 +}
    8.46 +
    8.47  static VOID
    8.48  XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, ULONG srb_offset)
    8.49  {
    8.50 @@ -292,18 +325,11 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
    8.51    {
    8.52      ptr = GET_PAGE_ALIGNED(srb->SrbExtension);
    8.53      transfer_length = min(block_count * 512 - srb_offset, UNALIGNED_DOUBLE_BUFFER_SIZE);
    8.54 -    if (!srb_offset)
    8.55 -    {
    8.56 -      xvdd->unaligned_requests++;
    8.57 -      xvdd->unaligned_bytes += transfer_length;
    8.58 -    }
    8.59    }
    8.60    else
    8.61    {
    8.62      ptr = srb->DataBuffer;
    8.63      transfer_length = block_count * 512;
    8.64 -    xvdd->aligned_requests++;
    8.65 -    xvdd->aligned_bytes += transfer_length;
    8.66    }
    8.67  
    8.68    if (xvdd->grant_free <= ADDRESS_AND_SIZE_TO_SPAN_PAGES(ptr, transfer_length))
    8.69 @@ -311,9 +337,33 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
    8.70      ASSERT(!xvdd->pending_srb);
    8.71      //KdPrint((__DRIVER_NAME "     No enough grants - deferring\n"));
    8.72      xvdd->pending_srb = srb;
    8.73 -    xvdd->no_free_grant_requests++;
    8.74 +    stat_no_grants++;
    8.75      return;
    8.76    }
    8.77 +
    8.78 +  if (!srb_offset)
    8.79 +  {
    8.80 +    if (PtrToUlong(srb->DataBuffer) & 511)
    8.81 +    {
    8.82 +      if (block_count * 512 <= 4096)
    8.83 +        stat_unaligned_le_4096++;
    8.84 +      else if (block_count * 512 <= 8192)
    8.85 +        stat_unaligned_le_8192++;
    8.86 +      else if (block_count * 512 <= 16384)
    8.87 +        stat_unaligned_le_16384++;
    8.88 +      else if (block_count * 512 <= 32768)
    8.89 +        stat_unaligned_le_32768++;
    8.90 +      else if (block_count * 512 <= 65536)
    8.91 +        stat_unaligned_le_65536++;
    8.92 +      else
    8.93 +        stat_unaligned_gt_65536++;
    8.94 +    }
    8.95 +    if (srb->Cdb[0] == SCSIOP_WRITE)
    8.96 +      stat_writes++;
    8.97 +    else
    8.98 +      stat_reads++;
    8.99 +    stat_outstanding_requests++;
   8.100 +  }
   8.101    
   8.102    shadow = get_shadow_from_freelist(xvdd);
   8.103    ASSERT(shadow);
   8.104 @@ -378,6 +428,8 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
   8.105      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
   8.106    }
   8.107  
   8.108 +  if (!xvdd->shadow_free)
   8.109 +    stat_no_shadows++;
   8.110    if (xvdd->shadow_free && srb_offset == 0)
   8.111      ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
   8.112  
   8.113 @@ -389,7 +441,7 @@ XenVbd_Resume(PVOID DeviceExtension)
   8.114  {
   8.115    PXENVBD_DEVICE_DATA xvdd = (PXENVBD_DEVICE_DATA)DeviceExtension;
   8.116    ULONG i;
   8.117 -  blkif_shadow_t shadows[SHADOW_ENTRIES];
   8.118 +  blkif_shadow_t shadows[MAX_SHADOW_ENTRIES];
   8.119    ULONG shadow_entries;
   8.120    blkif_shadow_t *shadow;  
   8.121  
   8.122 @@ -435,6 +487,7 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
   8.123    ULONG status;
   8.124  //  PXENPCI_XEN_DEVICE_DATA XenDeviceData;
   8.125    PACCESS_RANGE access_range;
   8.126 +  ULONG i;
   8.127  
   8.128    UNREFERENCED_PARAMETER(HwContext);
   8.129    UNREFERENCED_PARAMETER(BusInformation);
   8.130 @@ -448,31 +501,49 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
   8.131    KdPrint((__DRIVER_NAME "     BusInterruptLevel = %d\n", ConfigInfo->BusInterruptLevel));
   8.132    KdPrint((__DRIVER_NAME "     BusInterruptVector = %03x\n", ConfigInfo->BusInterruptVector));
   8.133  
   8.134 -  if (ConfigInfo->NumberOfAccessRanges != 1)
   8.135 +  if (ConfigInfo->NumberOfAccessRanges != 1 && ConfigInfo->NumberOfAccessRanges != 2)
   8.136    {
   8.137      KdPrint((__DRIVER_NAME "     NumberOfAccessRanges = %d\n", ConfigInfo->NumberOfAccessRanges));    
   8.138      return SP_RETURN_BAD_CONFIG;
   8.139    }
   8.140  
   8.141 -  access_range = &((*(ConfigInfo->AccessRanges))[0]);
   8.142 -
   8.143 -  KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
   8.144 -    access_range->RangeStart.LowPart, access_range->RangeLength));
   8.145 +  xvdd->inactive = global_inactive;
   8.146 +  
   8.147 +  for (i = 0; i < ConfigInfo->NumberOfAccessRanges; i++)
   8.148 +  {
   8.149 +    access_range = &((*(ConfigInfo->AccessRanges))[i]);
   8.150 +    if (access_range->RangeStart.QuadPart)
   8.151 +    {
   8.152 +      KdPrint((__DRIVER_NAME "     RangeStart = %08x, RangeLength = %08x\n",
   8.153 +        access_range->RangeStart.LowPart, access_range->RangeLength));
   8.154  
   8.155 -  xvdd->device_base = ScsiPortGetDeviceBase(
   8.156 -    DeviceExtension,
   8.157 -    ConfigInfo->AdapterInterfaceType,
   8.158 -    ConfigInfo->SystemIoBusNumber,
   8.159 -    access_range->RangeStart,
   8.160 -    access_range->RangeLength,
   8.161 -    !access_range->RangeInMemory);
   8.162 -  if (xvdd->device_base == NULL)
   8.163 +      xvdd->device_base = ScsiPortGetDeviceBase(
   8.164 +        DeviceExtension,
   8.165 +        ConfigInfo->AdapterInterfaceType,
   8.166 +        ConfigInfo->SystemIoBusNumber,
   8.167 +        access_range->RangeStart,
   8.168 +        access_range->RangeLength,
   8.169 +        !access_range->RangeInMemory);
   8.170 +      if (xvdd->device_base == NULL)
   8.171 +      {
   8.172 +        KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   8.173 +        KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   8.174 +        return SP_RETURN_BAD_CONFIG;
   8.175 +      }
   8.176 +    }
   8.177 +    else
   8.178 +    {
   8.179 +      xvdd->inactive = TRUE;
   8.180 +    }
   8.181 +  }
   8.182 +
   8.183 +  if (!xvdd->device_base)
   8.184    {
   8.185 -    KdPrint((__DRIVER_NAME "     Unable to map range\n"));
   8.186 +    KdPrint((__DRIVER_NAME "     Invalid config\n"));
   8.187      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));  
   8.188      return SP_RETURN_BAD_CONFIG;
   8.189    }
   8.190 -
   8.191 +  
   8.192    status = XenVbd_InitFromConfig(xvdd);
   8.193    if (status != SP_RETURN_FOUND)
   8.194      return status;
   8.195 @@ -681,12 +752,13 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.196    blkif_shadow_t *shadow;
   8.197    ULONG offset;
   8.198  
   8.199 -  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ bac"\n"));
   8.200 +  //KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   8.201  
   8.202 +  stat_interrupts++;
   8.203    /* in dump mode I think we get called on a timer, not by an actual IRQ */
   8.204    if (!dump_mode && !xvdd->vectors.EvtChn_AckEvent(xvdd->vectors.context, xvdd->event_channel))
   8.205      return FALSE; /* interrupt was not for us */
   8.206 -
   8.207 +  stat_interrupts_for_me++;
   8.208    if (xvdd->device_state->resume_state != xvdd->device_state->resume_state_ack)
   8.209    {
   8.210      FUNCTION_ENTER();
   8.211 @@ -713,7 +785,8 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.212      return FALSE;
   8.213    }
   8.214  
   8.215 -  xvdd->interrupts++;
   8.216 +  if (!(stat_interrupts_for_me & 0x3FF))
   8.217 +    XenVbd_DumpStats();
   8.218    while (more_to_do)
   8.219    {
   8.220      rp = xvdd->ring.sring->rsp_prod;
   8.221 @@ -789,6 +862,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.222            if (offset == block_count * xvdd->bytes_per_sector)
   8.223            {
   8.224              ScsiPortNotification(RequestComplete, xvdd, srb);
   8.225 +            stat_outstanding_requests--;
   8.226              ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   8.227            }
   8.228            else
   8.229 @@ -800,6 +874,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.230          {
   8.231            put_shadow_on_freelist(xvdd, shadow);
   8.232            ScsiPortNotification(RequestComplete, xvdd, srb);
   8.233 +          stat_outstanding_requests--;
   8.234            if (xvdd->pending_srb)
   8.235            {
   8.236              srb = xvdd->pending_srb;
   8.237 @@ -832,7 +907,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.238  
   8.239    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   8.240  
   8.241 -  return FALSE; /* we just don't know... */
   8.242 +  return FALSE; /* fall through to the next ISR... */
   8.243  }
   8.244  
   8.245  static BOOLEAN DDKAPI
   8.246 @@ -844,6 +919,12 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.247  
   8.248    //KdPrint((__DRIVER_NAME " --> HwScsiStartIo PathId = %d, TargetId = %d, Lun = %d\n", Srb->PathId, Srb->TargetId, Srb->Lun));
   8.249  
   8.250 +  if (xvdd->inactive)
   8.251 +  {
   8.252 +    Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
   8.253 +    return TRUE;
   8.254 +  }
   8.255 +  
   8.256    // If we haven't enumerated all the devices yet then just defer the request
   8.257    if (xvdd->ring_detect_state < 2)
   8.258    {
   8.259 @@ -1234,9 +1315,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   8.260      dump_mode = TRUE;
   8.261    if (conf_info->DiskCount && RegistryPath)
   8.262    {
   8.263 -    KdPrint((__DRIVER_NAME "     Not loaded at boot time so not loading\n"));
   8.264 -    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   8.265 -    return STATUS_UNSUCCESSFUL;
   8.266 +    global_inactive = TRUE;
   8.267 +    KdPrint((__DRIVER_NAME "     Not loaded at boot time so setting inactive\n"));
   8.268    }
   8.269    
   8.270    RtlZeroMemory(&HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
     9.1 --- a/xenvbd/xenvbd.h	Thu Sep 04 22:26:18 2008 +1000
     9.2 +++ b/xenvbd/xenvbd.h	Thu Sep 04 22:31:38 2008 +1000
     9.3 @@ -88,7 +88,8 @@ typedef struct {
     9.4    ULONG length;
     9.5  } blkif_shadow_t;
     9.6  
     9.7 -#define SHADOW_ENTRIES 16
     9.8 +#define MAX_SHADOW_ENTRIES 64
     9.9 +#define SHADOW_ENTRIES min(MAX_SHADOW_ENTRIES, min(BLK_RING_SIZE, BLK_OTHER_RING_SIZE))
    9.10  #define MAX_GRANT_ENTRIES 512
    9.11  
    9.12  typedef enum {
    9.13 @@ -106,8 +107,10 @@ typedef enum {
    9.14  
    9.15  struct
    9.16  {
    9.17 -  blkif_shadow_t shadows[SHADOW_ENTRIES];
    9.18 -  USHORT shadow_free_list[SHADOW_ENTRIES];
    9.19 +  BOOLEAN inactive;
    9.20 +  
    9.21 +  blkif_shadow_t shadows[MAX_SHADOW_ENTRIES];
    9.22 +  USHORT shadow_free_list[MAX_SHADOW_ENTRIES];
    9.23    USHORT shadow_free;
    9.24    USHORT shadow_min_free;
    9.25  
    9.26 @@ -136,13 +139,14 @@ struct
    9.27    XENPCI_VECTORS vectors;
    9.28    PXENPCI_DEVICE_STATE device_state;
    9.29    PSCSI_REQUEST_BLOCK pending_srb;
    9.30 -  
    9.31 +/*  
    9.32    ULONGLONG interrupts;
    9.33    ULONGLONG aligned_requests;
    9.34    ULONGLONG aligned_bytes;
    9.35    ULONGLONG unaligned_requests;
    9.36    ULONGLONG unaligned_bytes;
    9.37    ULONGLONG no_free_grant_requests;
    9.38 +*/
    9.39  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
    9.40  
    9.41  #endif