win-pvdrivers

changeset 162:d90e78d0e7b7 0.6.3

Fixed vbd crashes where Dom0 bit width != DomU bit width
author James Harper <james.harper@bendigoit.com.au>
date Sat Feb 02 22:48:15 2008 +1100 (2008-02-02)
parents 15e5060063c5
children 218a05ac3de0
files common/include/public/io/blkif.h common/include/public/io/protocols.h common/include/xen_windows.h doc/README.txt doc/TODO.txt makedist.bat xenenum/sources xenhide/sources xenhide/xenhide.c xennet/sources xenpci/sources xenvbd/sources xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common/include/public/io/blkif.h	Sat Feb 02 22:47:47 2008 +1100
     1.2 +++ b/common/include/public/io/blkif.h	Sat Feb 02 22:48:15 2008 +1100
     1.3 @@ -30,6 +30,10 @@
     1.4  #include "ring.h"
     1.5  #include "../grant_table.h"
     1.6  
     1.7 +#if defined(__i386__)
     1.8 +#pragma pack(4)
     1.9 +#endif
    1.10 +
    1.11  /*
    1.12   * Front->back notifications: When enqueuing a new request, sending a
    1.13   * notification can be made conditional on req_event (i.e., the generic
    1.14 @@ -71,9 +75,6 @@
    1.15   */
    1.16  #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
    1.17  
    1.18 -#if defined(__i386__)
    1.19 -#pragma pack(4)
    1.20 -#endif
    1.21  struct blkif_request_segment {
    1.22      grant_ref_t gref;        /* reference to I/O buffer frame        */
    1.23      /* @first_sect: first sector in frame to transfer (inclusive).   */
    1.24 @@ -97,9 +98,6 @@ struct blkif_response {
    1.25      int16_t         status;          /* BLKIF_RSP_???       */
    1.26  };
    1.27  typedef struct blkif_response blkif_response_t;
    1.28 -#if defined(__i386__)
    1.29 -#pragma pack()
    1.30 -#endif
    1.31  
    1.32  /*
    1.33   * STATUS RETURN CODES.
    1.34 @@ -121,6 +119,10 @@ DEFINE_RING_TYPES(blkif, struct blkif_re
    1.35  #define VDISK_REMOVABLE    0x2
    1.36  #define VDISK_READONLY     0x4
    1.37  
    1.38 +#if defined(__i386__)
    1.39 +#pragma pack()
    1.40 +#endif
    1.41 +
    1.42  #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
    1.43  
    1.44  /*
     2.1 --- a/common/include/public/io/protocols.h	Sat Feb 02 22:47:47 2008 +1100
     2.2 +++ b/common/include/public/io/protocols.h	Sat Feb 02 22:48:15 2008 +1100
     2.3 @@ -1,21 +1,21 @@
     2.4 -#ifndef __XEN_PROTOCOLS_H__
     2.5 -#define __XEN_PROTOCOLS_H__
     2.6 -
     2.7 -#define XEN_IO_PROTO_ABI_X86_32     "x86_32-abi"
     2.8 -#define XEN_IO_PROTO_ABI_X86_64     "x86_64-abi"
     2.9 -#define XEN_IO_PROTO_ABI_IA64       "ia64-abi"
    2.10 -#define XEN_IO_PROTO_ABI_POWERPC64  "powerpc64-abi"
    2.11 -
    2.12 -#if defined(__i386__)
    2.13 -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
    2.14 -#elif defined(__x86_64__)
    2.15 -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
    2.16 -#elif defined(__ia64__)
    2.17 -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
    2.18 -#elif defined(__powerpc64__)
    2.19 -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
    2.20 -#else
    2.21 -# error arch fixup needed here
    2.22 -#endif
    2.23 -
    2.24 -#endif
    2.25 +#ifndef __XEN_PROTOCOLS_H__
    2.26 +#define __XEN_PROTOCOLS_H__
    2.27 +
    2.28 +#define XEN_IO_PROTO_ABI_X86_32     "x86_32-abi"
    2.29 +#define XEN_IO_PROTO_ABI_X86_64     "x86_64-abi"
    2.30 +#define XEN_IO_PROTO_ABI_IA64       "ia64-abi"
    2.31 +#define XEN_IO_PROTO_ABI_POWERPC64  "powerpc64-abi"
    2.32 +
    2.33 +#if defined(__i386__)
    2.34 +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
    2.35 +#elif defined(__x86_64__)
    2.36 +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
    2.37 +#elif defined(__ia64__)
    2.38 +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
    2.39 +#elif defined(__powerpc64__)
    2.40 +# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
    2.41 +#else
    2.42 +# error arch fixup needed here
    2.43 +#endif
    2.44 +
    2.45 +#endif
    2.46 \ No newline at end of file
     3.1 --- a/common/include/xen_windows.h	Sat Feb 02 22:47:47 2008 +1100
     3.2 +++ b/common/include/xen_windows.h	Sat Feb 02 22:48:15 2008 +1100
     3.3 @@ -7,16 +7,12 @@
     3.4  #define __XEN_INTERFACE_VERSION__ 0x00030205
     3.5  #if defined(_AMD64_)
     3.6    #define __x86_64__
     3.7 -#else 
     3.8 -  #if defined(_IA64_)
     3.9 -    #define __ia64__
    3.10 -  #else
    3.11 -    #if defined(_X86_)
    3.12 -      #define __i386__
    3.13 -    #else
    3.14 -      #error Unknown architecture
    3.15 -    #endif
    3.16 -  #endif
    3.17 +#elif defined(_IA64_)
    3.18 +  #define __ia64__
    3.19 +#elif defined(_X86_)
    3.20 +  #define __i386__
    3.21 +#else
    3.22 +  #error Unknown architecture
    3.23  #endif
    3.24  typedef INT8 int8_t;
    3.25  typedef UINT8 uint8_t;
    3.26 @@ -25,7 +21,6 @@ typedef UINT16 uint16_t;
    3.27  typedef INT32 int32_t;
    3.28  typedef UINT32 uint32_t;
    3.29  typedef UINT64 uint64_t;
    3.30 -//typedef unsigned long pgentry_t;
    3.31  
    3.32  #include <xen.h>
    3.33  
    3.34 @@ -110,7 +105,7 @@ AllocatePages(int Pages)
    3.35      KdPrint((__DRIVER_NAME "     AllocatePages Failed at ExAllocatePoolWithTag\n"));
    3.36      return NULL;
    3.37    }
    3.38 -  KdPrint((__DRIVER_NAME " --- AllocatePages IRQL = %d, Buf = %p\n", KeGetCurrentIrql(), Buf));
    3.39 +//  KdPrint((__DRIVER_NAME " --- AllocatePages IRQL = %d, Buf = %p\n", KeGetCurrentIrql(), Buf));
    3.40    Mdl = IoAllocateMdl(Buf, Pages * PAGE_SIZE, FALSE, FALSE, NULL);
    3.41    if (Mdl == NULL)
    3.42    {
    3.43 @@ -133,7 +128,7 @@ static VOID
    3.44  FreePages(PMDL Mdl)
    3.45  {
    3.46    PVOID Buf = MmGetMdlVirtualAddress(Mdl);
    3.47 -  KdPrint((__DRIVER_NAME " --- FreePages IRQL = %d, Buf = %p\n", KeGetCurrentIrql(), Buf));
    3.48 +//  KdPrint((__DRIVER_NAME " --- FreePages IRQL = %d, Buf = %p\n", KeGetCurrentIrql(), Buf));
    3.49    IoFreeMdl(Mdl);
    3.50    ExFreePoolWithTag(Buf, ALLOCATE_PAGES_POOL_TAG);
    3.51  }
     4.1 --- a/doc/README.txt	Sat Feb 02 22:47:47 2008 +1100
     4.2 +++ b/doc/README.txt	Sat Feb 02 22:48:15 2008 +1100
     4.3 @@ -5,8 +5,7 @@ Block and Network drivers are supported,
     4.4  will respond to 'xm shutdown' and 'xm reboot' commands.
     4.5  
     4.6  My test environment is Xen 3.1.1 (64 bit Hypervisor) and Windows 2003 
     4.7 -sp2 (32 bit PAE). YMMV. There have definitely been problems reported on
     4.8 -Intel architectures.
     4.9 +sp2 (32, 32p, 64). YMMV.
    4.10  
    4.11  You can get the source using Mercurial at 
    4.12  http://xenbits.xensource.com/ext/win-pvdrivers.hg. 
    4.13 @@ -24,4 +23,3 @@ See BUILDING.txt for instructions on bui
    4.14  See INSTALLING.txt for instructions on installing the drivers. 
    4.15  
    4.16  See TODO.txt for known problems and future plans. 
    4.17 -
     5.1 --- a/doc/TODO.txt	Sat Feb 02 22:47:47 2008 +1100
     5.2 +++ b/doc/TODO.txt	Sat Feb 02 22:48:15 2008 +1100
     5.3 @@ -4,10 +4,8 @@ own too, so this code is mostly one, the
     5.4  get to that as soon as I figure out what coding style to use and where.
     5.5  
     5.6  Known problems or things that need doing to make it properly useful:
     5.7 -. Test under environments other than 32-bit PAE Windows 2003.
     5.8  . No power management
     5.9  . Almost certainly won't support migration or suspend/resume.
    5.10 -. Reports of problems on Intel systems
    5.11  . Not enough testing under SMP.
    5.12  . Probably lots of other things too.
    5.13  
    5.14 @@ -19,4 +17,3 @@ TODO:
    5.15  . Fix BSoD crash dump under vbd (currently just hangs without writing
    5.16    a dump file)
    5.17  . Correctly handle CD changes
    5.18 -. Prevent xenvbd loading if the pci ide driver is loaded (bad things will happen)
     6.1 --- a/makedist.bat	Sat Feb 02 22:47:47 2008 +1100
     6.2 +++ b/makedist.bat	Sat Feb 02 22:48:15 2008 +1100
     6.3 @@ -1,3 +1,6 @@
     6.4  @echo off
     6.5 +cmd /C "C:\WinDDK\6000\bin\setenv.bat C:\WinDDK\6000\ chk AMD64 WNET && CD \Projects\win-pvdrivers.hg && build -cZg"
     6.6 +cmd /C "C:\WinDDK\6000\bin\setenv.bat C:\WinDDK\6000\ chk WNET && CD \Projects\win-pvdrivers.hg && build -cZg"
     6.7 +cmd /C "C:\WinDDK\6000\bin\setenv.bat C:\WinDDK\6000\ chk WXP && CD \Projects\win-pvdrivers.hg && build -cZg"
     6.8  xcopy target\* dist /E /EXCLUDE:exclude.txt /D /Y
     6.9  copy doc\*.txt dist
     7.1 --- a/xenenum/sources	Sat Feb 02 22:47:47 2008 +1100
     7.2 +++ b/xenenum/sources	Sat Feb 02 22:48:15 2008 +1100
     7.3 @@ -1,7 +1,7 @@
     7.4  TARGETNAME=xenenum
     7.5  TARGETTYPE=DRIVER
     7.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     7.7 -VERSION=0.6.1.1
     7.8 +VERSION=0.6.3.0
     7.9  KMDF_VERSION=1
    7.10  MSC_WARNING_LEVEL=/W4
    7.11  INF_NAME=xenenum
     8.1 --- a/xenhide/sources	Sat Feb 02 22:47:47 2008 +1100
     8.2 +++ b/xenhide/sources	Sat Feb 02 22:48:15 2008 +1100
     8.3 @@ -1,7 +1,7 @@
     8.4  TARGETNAME=XENHIDE
     8.5  TARGETTYPE=DRIVER
     8.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     8.7 -VERSION=0.6.1.15
     8.8 +VERSION=0.6.3.0
     8.9  KMDF_VERSION=1
    8.10  MSC_WARNING_LEVEL=/W4
    8.11  INF_NAME=xenhide
     9.1 --- a/xenhide/xenhide.c	Sat Feb 02 22:47:47 2008 +1100
     9.2 +++ b/xenhide/xenhide.c	Sat Feb 02 22:48:15 2008 +1100
     9.3 @@ -72,9 +72,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
     9.4    }
     9.5    else
     9.6      ZwClose(RegHandle);
     9.7 -  KdPrint((__DRIVER_NAME "     BufLen = %d\n", BufLen));
     9.8 +//  KdPrint((__DRIVER_NAME "     BufLen = %d\n", BufLen));
     9.9    KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
    9.10 -  KdPrint((__DRIVER_NAME "     Buf = %ws\n", KeyPartialValue->Data));
    9.11 +//  KdPrint((__DRIVER_NAME "     Buf = %ws\n", KeyPartialValue->Data));
    9.12    SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
    9.13  
    9.14    AutoEnumerate = FALSE;
    9.15 @@ -274,11 +274,11 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    9.16  
    9.17      Length = sizeof(Buffer);
    9.18      IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyDeviceDescription, Length, Buffer, &Length);
    9.19 -    KdPrint((__DRIVER_NAME "     %3d - %ws\n", i, Buffer));
    9.20 +//    KdPrint((__DRIVER_NAME "     %3d - %ws\n", i, Buffer));
    9.21  
    9.22      Length = sizeof(Buffer);
    9.23      IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyPhysicalDeviceObjectName, Length, Buffer, &Length);
    9.24 -    KdPrint((__DRIVER_NAME "     %3d - %ws\n", i, Buffer));
    9.25 +//    KdPrint((__DRIVER_NAME "     %3d - %ws\n", i, Buffer));
    9.26  
    9.27      Length = sizeof(Buffer);
    9.28      IoGetDeviceProperty(Relations->Objects[i - Offset], DevicePropertyHardwareID, Length, Buffer, &Length);
    9.29 @@ -286,7 +286,7 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    9.30      StrLen = 0;
    9.31      for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
    9.32      {
    9.33 -      KdPrint((__DRIVER_NAME "         - %ws\n", Ptr));
    9.34 +//      KdPrint((__DRIVER_NAME "         - %ws\n", Ptr));
    9.35        // Qemu PCI
    9.36        if (XenHide_StringMatches(Ptr, L"PCI\\VEN_8086&DEV_7010&SUBSYS_00015853")) {
    9.37          Match = 1;
    9.38 @@ -301,7 +301,7 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    9.39      }
    9.40      if (Match)
    9.41      {
    9.42 -      KdPrint((__DRIVER_NAME "           (Match)\n"));
    9.43 +//      KdPrint((__DRIVER_NAME "           (Match)\n"));
    9.44        Offset++;
    9.45      }
    9.46    }
    10.1 --- a/xennet/sources	Sat Feb 02 22:47:47 2008 +1100
    10.2 +++ b/xennet/sources	Sat Feb 02 22:48:15 2008 +1100
    10.3 @@ -1,7 +1,7 @@
    10.4  TARGETNAME=XENNET
    10.5  TARGETTYPE=DRIVER
    10.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
    10.7 -VERSION=0.6.1.1
    10.8 +VERSION=0.6.3.0
    10.9  KMDF_VERSION=1
   10.10  MSC_WARNING_LEVEL=/W4
   10.11  INF_NAME=xennet
    11.1 --- a/xenpci/sources	Sat Feb 02 22:47:47 2008 +1100
    11.2 +++ b/xenpci/sources	Sat Feb 02 22:48:15 2008 +1100
    11.3 @@ -1,7 +1,7 @@
    11.4  TARGETNAME=XENPCI
    11.5  TARGETTYPE=DRIVER
    11.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
    11.7 -VERSION=0.6.1.18
    11.8 +VERSION=0.6.3.0
    11.9  KMDF_VERSION=1
   11.10  MSC_WARNING_LEVEL=/W4
   11.11  INF_NAME=xenpci
    12.1 --- a/xenvbd/sources	Sat Feb 02 22:47:47 2008 +1100
    12.2 +++ b/xenvbd/sources	Sat Feb 02 22:48:15 2008 +1100
    12.3 @@ -1,7 +1,7 @@
    12.4  TARGETNAME=XENVBD
    12.5  TARGETTYPE=DRIVER
    12.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
    12.7 -VERSION=0.6.1.14
    12.8 +VERSION=0.6.3.0
    12.9  KMDF_VERSION=1
   12.10  MSC_WARNING_LEVEL=/W4
   12.11  INF_NAME=xenvbd
    13.1 --- a/xenvbd/xenvbd.c	Sat Feb 02 22:47:47 2008 +1100
    13.2 +++ b/xenvbd/xenvbd.c	Sat Feb 02 22:48:15 2008 +1100
    13.3 @@ -120,6 +120,19 @@ XenVbd_Interrupt(PKINTERRUPT Interrupt, 
    13.4    return TRUE;
    13.5  }
    13.6  
    13.7 +static blkif_response_t *
    13.8 +XenVbd_GetResponse(PXENVBD_TARGET_DATA TargetData, int i)
    13.9 +{
   13.10 +  blkif_other_response_t *rep;
   13.11 +  if (!TargetData->use_other)
   13.12 +    return RING_GET_RESPONSE(&TargetData->Ring, i);
   13.13 +  rep = RING_GET_RESPONSE(&TargetData->OtherRing, i);
   13.14 +  TargetData->tmp_rep.id = rep->id;
   13.15 +  TargetData->tmp_rep.operation = rep->operation;
   13.16 +  TargetData->tmp_rep.status = rep->status;
   13.17 +  return &TargetData->tmp_rep;
   13.18 +}
   13.19 +
   13.20  static VOID
   13.21  XenVbd_HwScsiInterruptTarget(PVOID DeviceExtension)
   13.22  {
   13.23 @@ -140,36 +153,55 @@ XenVbd_HwScsiInterruptTarget(PVOID Devic
   13.24      KeMemoryBarrier();
   13.25      for (i = TargetData->Ring.rsp_cons; i != rp; i++)
   13.26      {
   13.27 -      rep = RING_GET_RESPONSE(&TargetData->Ring, i);
   13.28 +      rep = XenVbd_GetResponse(TargetData, i);
   13.29 +
   13.30  //KdPrint((__DRIVER_NAME "     rep = %p\n", rep));
   13.31  //KdPrint((__DRIVER_NAME "     rep->id = %d\n", rep->id));
   13.32 -
   13.33 -      Srb = TargetData->shadow[rep->id].Srb;
   13.34 -      BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
   13.35 -
   13.36 -      if (rep->status == BLKIF_RSP_OKAY)
   13.37 -        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   13.38 -      else
   13.39 +      switch (TargetData->ring_detect_state)
   13.40        {
   13.41 -        KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
   13.42 -        if (Srb->Cdb[0] == SCSIOP_READ)
   13.43 -          KdPrint((__DRIVER_NAME "     Operation = Read\n"));
   13.44 +      case 0:
   13.45 +        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", TargetData->ring_detect_state, rep->operation, rep->id, rep->status));
   13.46 +        TargetData->ring_detect_state = 1;
   13.47 +        break;
   13.48 +      case 1:
   13.49 +        KdPrint((__DRIVER_NAME "     ring_detect_state = %d, operation = %x, id = %lx, status = %d\n", TargetData->ring_detect_state, rep->operation, rep->id, rep->status));
   13.50 +        if (rep->operation != 0xff)
   13.51 +        {
   13.52 +          TargetData->Ring.nr_ents = BLK_OTHER_RING_SIZE;
   13.53 +          TargetData->use_other = TRUE;
   13.54 +        }
   13.55 +        TargetData->shadow[TargetData->Ring.nr_ents - 1].req.id = 0x0fffffff;
   13.56 +        DeviceData->BusChangePending = 1;
   13.57 +        TargetData->ring_detect_state = 2;
   13.58 +        break;
   13.59 +      case 2:
   13.60 +        Srb = TargetData->shadow[rep->id].Srb;
   13.61 +        BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
   13.62 +  
   13.63 +        if (rep->status == BLKIF_RSP_OKAY)
   13.64 +          Srb->SrbStatus = SRB_STATUS_SUCCESS;
   13.65          else
   13.66 -          KdPrint((__DRIVER_NAME "     Operation = Write\n"));     
   13.67 -        KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
   13.68 -        Srb->SrbStatus = SRB_STATUS_ERROR;
   13.69 +        {
   13.70 +          KdPrint((__DRIVER_NAME "     Xen Operation returned error\n"));
   13.71 +          if (Srb->Cdb[0] == SCSIOP_READ)
   13.72 +            KdPrint((__DRIVER_NAME "     Operation = Read\n"));
   13.73 +          else
   13.74 +            KdPrint((__DRIVER_NAME "     Operation = Write\n"));     
   13.75 +          KdPrint((__DRIVER_NAME "     Sector = %08X, Count = %d\n", TargetData->shadow[rep->id].req.sector_number, BlockCount));
   13.76 +          Srb->SrbStatus = SRB_STATUS_ERROR;
   13.77 +        }
   13.78 +        for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
   13.79 +          DeviceData->XenDeviceData->XenInterface.GntTbl_EndAccess(
   13.80 +            DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
   13.81 +            TargetData->shadow[rep->id].req.seg[j].gref);
   13.82 +        if (Srb->Cdb[0] == SCSIOP_READ)
   13.83 +          memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
   13.84 +  
   13.85 +        ScsiPortNotification(RequestComplete, DeviceData, Srb);
   13.86 +        ScsiPortNotification(NextLuRequest, DeviceData, Srb->PathId, Srb->TargetId, Srb->Lun);
   13.87 +
   13.88 +        ADD_ID_TO_FREELIST(TargetData, rep->id);
   13.89        }
   13.90 -      for (j = 0; j < TargetData->shadow[rep->id].req.nr_segments; j++)
   13.91 -        DeviceData->XenDeviceData->XenInterface.GntTbl_EndAccess(
   13.92 -          DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
   13.93 -          TargetData->shadow[rep->id].req.seg[j].gref);
   13.94 -      if (Srb->Cdb[0] == SCSIOP_READ)
   13.95 -        memcpy(Srb->DataBuffer, TargetData->shadow[rep->id].Buf, BlockCount * TargetData->BytesPerSector);
   13.96 -
   13.97 -      ScsiPortNotification(RequestComplete, DeviceData, Srb);
   13.98 -      ScsiPortNotification(NextLuRequest, DeviceData, Srb->PathId, Srb->TargetId, Srb->Lun);
   13.99 -
  13.100 -      ADD_ID_TO_FREELIST(TargetData, rep->id);
  13.101      }
  13.102  
  13.103      TargetData->Ring.rsp_cons = i;
  13.104 @@ -227,6 +259,8 @@ XenVbd_BackEndStateHandler(char *Path, P
  13.105    blkif_sring_t *SharedRing;
  13.106    ULONG PFN;
  13.107    ULONG i;
  13.108 +  blkif_request_t *req;
  13.109 +  int notify;
  13.110  
  13.111    KdPrint((__DRIVER_NAME " --> BackEndStateHandler\n"));
  13.112    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
  13.113 @@ -260,45 +294,67 @@ XenVbd_BackEndStateHandler(char *Path, P
  13.114      Mdl = AllocatePage();
  13.115      PFN = (ULONG)*MmGetMdlPfnArray(Mdl);
  13.116      SharedRing = (blkif_sring_t *)MmGetMdlVirtualAddress(Mdl);
  13.117 +    RtlZeroMemory(SharedRing, PAGE_SIZE);
  13.118      SHARED_RING_INIT(SharedRing);
  13.119      FRONT_RING_INIT(&TargetData->Ring, SharedRing, PAGE_SIZE);
  13.120      ref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
  13.121        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  13.122        0, PFN, FALSE);
  13.123      ASSERT((signed short)ref >= 0);
  13.124 +    TargetData->ring_detect_state = 0;
  13.125 +    TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * max(BLK_RING_SIZE, BLK_OTHER_RING_SIZE), XENVBD_POOL_TAG);
  13.126  
  13.127 -    TargetData->shadow = ExAllocatePoolWithTag(NonPagedPool, sizeof(blkif_shadow_t) * BLK_RING_SIZE, XENVBD_POOL_TAG);
  13.128 -
  13.129 -    memset(TargetData->shadow, 0, sizeof(blkif_shadow_t) * BLK_RING_SIZE);
  13.130 -    for (i = 0; i < BLK_RING_SIZE; i++)
  13.131 +    memset(TargetData->shadow, 0, sizeof(blkif_shadow_t) * max(BLK_RING_SIZE, BLK_OTHER_RING_SIZE));
  13.132 +    for (i = 0; i < max(BLK_RING_SIZE, BLK_OTHER_RING_SIZE); i++)
  13.133      {
  13.134        TargetData->shadow[i].req.id = i + 1;
  13.135        TargetData->shadow[i].Mdl = AllocatePages(BUF_PAGES_PER_SRB); // stupid that we have to do this!
  13.136        TargetData->shadow[i].Buf = MmGetMdlVirtualAddress(TargetData->shadow[i].Mdl);
  13.137      }
  13.138      TargetData->shadow_free = 0;
  13.139 -    TargetData->shadow[BLK_RING_SIZE - 1].req.id = 0x0fffffff;
  13.140 +
  13.141 +    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  13.142 +    RtlStringCbCatA(TmpPath, 128, "/protocol");
  13.143 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  13.144 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  13.145 +      XBT_NIL, TmpPath, "%s", XEN_IO_PROTO_ABI_NATIVE);
  13.146  
  13.147      RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  13.148      RtlStringCbCatA(TmpPath, 128, "/ring-ref");
  13.149 -    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", ref);
  13.150 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  13.151 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  13.152 +      XBT_NIL, TmpPath, "%d", ref);
  13.153  
  13.154      RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  13.155      RtlStringCbCatA(TmpPath, 128, "/event-channel");
  13.156 -    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
  13.157 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  13.158 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  13.159 +      XBT_NIL, TmpPath, "%d", TargetData->EventChannel);
  13.160  
  13.161      RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  13.162 -    RtlStringCbCatA(TmpPath, 128, "/protocol");
  13.163 -    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%s", XEN_IO_PROTO_ABI_NATIVE);
  13.164 -//    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%s", XEN_IO_PROTO_ABI_X86_64);
  13.165 -  
  13.166 -    RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  13.167      RtlStringCbCatA(TmpPath, 128, "/state");
  13.168 -    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
  13.169 +    DeviceData->XenDeviceData->XenInterface.XenBus_Printf(
  13.170 +      DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context, 
  13.171 +      XBT_NIL, TmpPath, "%d", XenbusStateInitialised);
  13.172  
  13.173 +/*
  13.174      KdPrint((__DRIVER_NAME "     sizeof(blkif_request) = %d\n", sizeof(struct blkif_request)));
  13.175 -    KdPrint((__DRIVER_NAME "     sizeof( blkif_request_segment) = %d\n", sizeof(struct blkif_request_segment)));
  13.176 +    KdPrint((__DRIVER_NAME "     sizeof(blkif_request_segment) = %d\n", sizeof(struct blkif_request_segment)));
  13.177      KdPrint((__DRIVER_NAME "     sizeof(blkif_response) = %d\n", sizeof(struct blkif_response)));
  13.178 +    KdPrint((__DRIVER_NAME "     operation = %d\n", (int)((char *)(&req.operation) - (char *)(&req))));
  13.179 +    KdPrint((__DRIVER_NAME "     nr_segments = %d\n", (int)((char *)(&req.nr_segments) - (char *)(&req))));
  13.180 +    KdPrint((__DRIVER_NAME "     handle = %d\n", (int)((char *)(&req.handle) - (char *)(&req))));
  13.181 +    KdPrint((__DRIVER_NAME "     id = %d\n", (int)((char *)(&req.id) - (char *)(&req))));
  13.182 +    KdPrint((__DRIVER_NAME "     sector_number = %d\n", (int)((char *)(&req.sector_number) - (char *)(&req))));
  13.183 +    KdPrint((__DRIVER_NAME "     seg = %d\n", (int)((char *)(&req.seg) - (char *)(&req))));
  13.184 +
  13.185 +    KdPrint((__DRIVER_NAME "     id = %d\n", (int)((char *)(&rep.id) - (char *)(&rep))));
  13.186 +    KdPrint((__DRIVER_NAME "     operation = %d\n", (int)((char *)(&rep.operation) - (char *)(&rep))));
  13.187 +    KdPrint((__DRIVER_NAME "     status = %d\n", (int)((char *)(&rep.status) - (char *)(&rep))));
  13.188 +
  13.189 +    KdPrint((__DRIVER_NAME "     sizeof(union blkif_sring_entry) = %d\n", sizeof(union blkif_sring_entry)));
  13.190 +    KdPrint((__DRIVER_NAME "     %d\n", (int)((char *)(&entries[1]) - (char *)(&entries[0]))));
  13.191 +*/
  13.192      KdPrint((__DRIVER_NAME "     Set Frontend state to Initialised\n"));
  13.193      break;
  13.194  
  13.195 @@ -374,8 +430,31 @@ XenVbd_BackEndStateHandler(char *Path, P
  13.196      TargetData->Geometry.Cylinders.QuadPart = TargetData->TotalSectors / TargetData->Geometry.SectorsPerTrack / TargetData->Geometry.TracksPerCylinder;
  13.197      KdPrint((__DRIVER_NAME "     Geometry C/H/S = %d/%d/%d\n", TargetData->Geometry.Cylinders.LowPart, TargetData->Geometry.TracksPerCylinder, TargetData->Geometry.SectorsPerTrack));
  13.198      
  13.199 -// now ask windows to rescan the scsi bus...
  13.200 -    DeviceData->BusChangePending = 1;
  13.201 +    req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
  13.202 +    req->operation = 0xff;
  13.203 +    req->nr_segments = 0;
  13.204 +    for (i = 0; i < req->nr_segments; i++)
  13.205 +    {
  13.206 +      req->seg[i].gref = 0xffffffff;
  13.207 +      req->seg[i].first_sect = 0xff;
  13.208 +      req->seg[i].last_sect = 0xff;
  13.209 +    }
  13.210 +    TargetData->Ring.req_prod_pvt++;
  13.211 +    req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
  13.212 +    req->operation = 0xff;
  13.213 +    req->nr_segments = 0;
  13.214 +    for (i = 0; i < req->nr_segments; i++)
  13.215 +    {
  13.216 +      req->seg[i].gref = 0xffffffff;
  13.217 +      req->seg[i].first_sect = 0xff;
  13.218 +      req->seg[i].last_sect = 0xff;
  13.219 +    }
  13.220 +    TargetData->Ring.req_prod_pvt++;
  13.221 +    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&TargetData->Ring, notify);
  13.222 +    if (notify)
  13.223 +      DeviceData->XenDeviceData->XenInterface.EvtChn_Notify(
  13.224 +        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  13.225 +        TargetData->EventChannel);
  13.226  
  13.227      RtlStringCbCopyA(TmpPath, 128, TargetData->Path);
  13.228      RtlStringCbCatA(TmpPath, 128, "/state");
  13.229 @@ -384,6 +463,9 @@ XenVbd_BackEndStateHandler(char *Path, P
  13.230      KdPrint((__DRIVER_NAME "     Set Frontend state to Connected\n"));
  13.231      InterlockedIncrement(&DeviceData->EnumeratedDevices);
  13.232      KdPrint((__DRIVER_NAME "     Added a device\n"));  
  13.233 +
  13.234 +// now ask windows to rescan the scsi bus...
  13.235 +//    DeviceData->BusChangePending = 1;
  13.236      break;
  13.237  
  13.238    case XenbusStateClosing:
  13.239 @@ -609,7 +691,6 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
  13.240          DeviceData->TotalInitialDevices++;
  13.241        }  
  13.242      }
  13.243 -    //ScsiPortNotification(BusChangeDetected, DeviceData, 0);
  13.244    }
  13.245  
  13.246    *Again = FALSE;
  13.247 @@ -712,15 +793,38 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
  13.248    return 0;
  13.249  }
  13.250  
  13.251 +static VOID
  13.252 +XenVbd_PutRequest(PXENVBD_TARGET_DATA TargetData, blkif_request_t *req)
  13.253 +{
  13.254 +  blkif_other_request_t *other_req;
  13.255 +
  13.256 +  if (!TargetData->use_other)
  13.257 +  {
  13.258 +    *RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt) = *req;
  13.259 +  }
  13.260 +  else
  13.261 +  {  
  13.262 +    other_req = RING_GET_REQUEST(&TargetData->OtherRing, TargetData->Ring.req_prod_pvt);
  13.263 +    other_req->operation = req->operation;
  13.264 +    other_req->nr_segments = req->nr_segments;
  13.265 +    other_req->handle = req->handle;
  13.266 +    other_req->id = req->id;
  13.267 +    other_req->sector_number = req->sector_number;
  13.268 +    memcpy(other_req->seg, req->seg, sizeof(struct blkif_request_segment) * req->nr_segments);
  13.269 +  }
  13.270 +  TargetData->Ring.req_prod_pvt++;
  13.271 +}
  13.272 +
  13.273  // Call with device lock held
  13.274  static VOID
  13.275  XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA TargetData, PSCSI_REQUEST_BLOCK Srb)
  13.276  {
  13.277    //PUCHAR DataBuffer;
  13.278 -  blkif_request_t *req;
  13.279    int i;
  13.280    int BlockCount;
  13.281    PXENVBD_DEVICE_DATA DeviceData = (PXENVBD_DEVICE_DATA)TargetData->DeviceData;
  13.282 +  blkif_shadow_t *shadow;
  13.283 +  int id;
  13.284  
  13.285  // can use SRB_STATUS_BUSY to push the SRB back to windows...
  13.286  
  13.287 @@ -732,54 +836,39 @@ XenVbd_PutSrbOnRing(PXENVBD_TARGET_DATA 
  13.288      // TODO: Fail badly here
  13.289    }
  13.290  
  13.291 -  req = RING_GET_REQUEST(&TargetData->Ring, TargetData->Ring.req_prod_pvt);
  13.292 -
  13.293 -  req->sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
  13.294 -  BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
  13.295 -
  13.296 -  req->id = GET_ID_FROM_FREELIST(TargetData);
  13.297 -
  13.298 -//KdPrint((__DRIVER_NAME "     req = %p\n", req));
  13.299 -//KdPrint((__DRIVER_NAME "     req->id = %ld\n", req->id));
  13.300 -//KdPrint((__DRIVER_NAME "     ((blkif_response *)req)->id = %ld\n", req->id));
  13.301 -
  13.302 -  if (req->id == 0x0fffffff)
  13.303 +  id = GET_ID_FROM_FREELIST(TargetData);
  13.304 +  if (id == 0x0fffffff)
  13.305    {
  13.306      KdPrint((__DRIVER_NAME "     Something is horribly wrong in PutSrbOnRing\n"));
  13.307    }
  13.308  
  13.309 -  req->handle = 0;
  13.310 -  req->operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  13.311 -  TargetData->shadow[req->id].Srb = Srb;
  13.312 +  shadow = &TargetData->shadow[id];
  13.313 +  shadow->req.id = id;
  13.314  
  13.315 -//  KdPrint((__DRIVER_NAME "     DataBuffer = %08X\n", Srb->DataBuffer));
  13.316 -//  KdPrint((__DRIVER_NAME "     BlockCount = %08X\n", BlockCount));
  13.317 +  shadow->req.sector_number = (Srb->Cdb[2] << 24) | (Srb->Cdb[3] << 16) | (Srb->Cdb[4] << 8) | Srb->Cdb[5];
  13.318 +  BlockCount = (Srb->Cdb[7] << 8) | Srb->Cdb[8];
  13.319 +  shadow->req.handle = 0;
  13.320 +  shadow->req.operation = (Srb->Cdb[0] == SCSIOP_READ)?BLKIF_OP_READ:BLKIF_OP_WRITE;
  13.321 +  shadow->Srb = Srb;
  13.322  
  13.323 -  req->nr_segments = (UINT8)((BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE);
  13.324 -//  KdPrint((__DRIVER_NAME "     req->nr_segments = %08X\n", req->nr_segments));
  13.325 +  shadow->req.nr_segments = (UINT8)((BlockCount * TargetData->BytesPerSector + PAGE_SIZE - 1) / PAGE_SIZE);
  13.326  
  13.327 -
  13.328 -  for (i = 0; i < req->nr_segments; i++)
  13.329 +  for (i = 0; i < shadow->req.nr_segments; i++)
  13.330    {
  13.331 -//KdPrint((__DRIVER_NAME "     (ULONG)MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i] = %d\n", (ULONG)MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i]));
  13.332 -//KdBreakPoint();
  13.333 -    req->seg[i].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
  13.334 +    shadow->req.seg[i].gref = DeviceData->XenDeviceData->XenInterface.GntTbl_GrantAccess(
  13.335        DeviceData->XenDeviceData->XenInterface.InterfaceHeader.Context,
  13.336 -      0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[req->id].Mdl)[i], FALSE);
  13.337 -//KdPrint((__DRIVER_NAME "     req->seg[i].gref = %d\n", req->seg[i].gref));
  13.338 -//KdBreakPoint();
  13.339 -    ASSERT((signed short)req->seg[i].gref >= 0);
  13.340 -    req->seg[i].first_sect = 0;
  13.341 -    if (i == req->nr_segments - 1)
  13.342 -      req->seg[i].last_sect = (UINT8)((BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector));
  13.343 +      0, (ULONG)MmGetMdlPfnArray(TargetData->shadow[shadow->req.id].Mdl)[i], FALSE);
  13.344 +    ASSERT((signed short)shadow->req.seg[i].gref >= 0);
  13.345 +    shadow->req.seg[i].first_sect = 0;
  13.346 +    if (i == shadow->req.nr_segments - 1)
  13.347 +      shadow->req.seg[i].last_sect = (UINT8)((BlockCount - 1) % (PAGE_SIZE / TargetData->BytesPerSector));
  13.348      else
  13.349 -      req->seg[i].last_sect = (UINT8)(PAGE_SIZE / TargetData->BytesPerSector - 1);
  13.350 -//    KdPrint((__DRIVER_NAME "     Page %d, first_sect = %d, last_sect = %d\n", i, req->seg[i].first_sect, req->seg[i].last_sect));
  13.351 +      shadow->req.seg[i].last_sect = (UINT8)(PAGE_SIZE / TargetData->BytesPerSector - 1);
  13.352    }
  13.353    if (Srb->Cdb[0] == SCSIOP_WRITE)
  13.354 -    memcpy(TargetData->shadow[req->id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
  13.355 -  TargetData->shadow[req->id].req = *req;
  13.356 -  TargetData->Ring.req_prod_pvt++;
  13.357 +    memcpy(TargetData->shadow[shadow->req.id].Buf, Srb->DataBuffer, BlockCount * TargetData->BytesPerSector);
  13.358 +
  13.359 +  XenVbd_PutRequest(TargetData, &shadow->req);
  13.360  
  13.361  //  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
  13.362  }
    14.1 --- a/xenvbd/xenvbd.h	Sat Feb 02 22:47:47 2008 +1100
    14.2 +++ b/xenvbd/xenvbd.h	Sat Feb 02 22:48:15 2008 +1100
    14.3 @@ -28,6 +28,31 @@
    14.4  
    14.5  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    14.6  #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
    14.7 +#define BLK_OTHER_RING_SIZE __RING_SIZE((blkif_other_sring_t *)0, PAGE_SIZE)
    14.8 +
    14.9 +#if defined(__x86_64__)
   14.10 +#pragma pack(push, 4)
   14.11 +#endif
   14.12 +struct blkif_other_request {
   14.13 +  uint8_t operation;
   14.14 +  uint8_t nr_segments;
   14.15 +  blkif_vdev_t handle;
   14.16 +  uint64_t id;
   14.17 +  blkif_sector_t sector_number;
   14.18 +  struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
   14.19 +};
   14.20 +struct blkif_other_response {
   14.21 +  uint64_t id;
   14.22 +  uint8_t operation;
   14.23 +  int16_t status;
   14.24 +};
   14.25 +#if defined(__x86_64__)
   14.26 +#pragma pack(pop)
   14.27 +#endif
   14.28 +
   14.29 +typedef struct blkif_other_request blkif_other_request_t;
   14.30 +typedef struct blkif_other_response blkif_other_response_t;
   14.31 +DEFINE_RING_TYPES(blkif_other, struct blkif_other_request, struct blkif_other_response);
   14.32  
   14.33  typedef struct {
   14.34    blkif_request_t req;
   14.35 @@ -55,7 +80,6 @@ struct
   14.36    BOOLEAN PendingInterrupt;
   14.37    PVOID DeviceData; // how can we create a forward definition for this???
   14.38    evtchn_port_t EventChannel;
   14.39 -  //blkif_sring_t *SharedRing;
   14.40    blkif_shadow_t *shadow;
   14.41    uint64_t shadow_free;
   14.42    ULONG RingBufPFN;
   14.43 @@ -64,7 +88,13 @@ struct
   14.44    char Path[128];
   14.45    int DeviceIndex;
   14.46    char BackendPath[128];
   14.47 -  blkif_front_ring_t Ring;
   14.48 +  union {
   14.49 +    blkif_front_ring_t Ring;
   14.50 +    blkif_other_front_ring_t OtherRing;
   14.51 +  };
   14.52 +  int ring_detect_state;
   14.53 +  BOOLEAN use_other;
   14.54 +  blkif_response_t tmp_rep;
   14.55    XENVBD_DEVICETYPE DeviceType;
   14.56    DISK_GEOMETRY Geometry;
   14.57    ULONG BytesPerSector;