win-pvdrivers

changeset 291:873944504204 wdm 0.9.7

Fixed a bug which would prevent formatting (NTFS only I think) of xenvbd devices, and possibly cause some corruption although unlikely.
Fixed a bug which would cause a BSoD if 'xm block-detach' was used.
author James Harper <james.harper@bendigoit.com.au>
date Sat Jun 07 22:19:18 2008 +1000 (2008-06-07)
parents a5d5a0376f96
children 43840aae5817
files common.inc installer.nsi xennet/xennet_rx.c xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c xenvbd/scsiport.c xenvbd/xenvbd.c xenvbd/xenvbd.h
line diff
     1.1 --- a/common.inc	Wed Jun 04 14:21:09 2008 +1000
     1.2 +++ b/common.inc	Sat Jun 07 22:19:18 2008 +1000
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.9.6.1
     1.5 +VERSION=0.9.7.0
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  MSC_WARNING_LEVEL=/W4
     1.8  INCLUDES = ..\common\include;..\common\include\public
     2.1 --- a/installer.nsi	Wed Jun 04 14:21:09 2008 +1000
     2.2 +++ b/installer.nsi	Sat Jun 07 22:19:18 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.6"
     2.8 +!define Version "0.9.7"
     2.9  #!define Version "$%VERSION%"
    2.10  Name "${AppName}"
    2.11  InstallDir "$PROGRAMFILES\${AppName}"
     3.1 --- a/xennet/xennet_rx.c	Wed Jun 04 14:21:09 2008 +1000
     3.2 +++ b/xennet/xennet_rx.c	Sat Jun 07 22:19:18 2008 +1000
     3.3 @@ -543,6 +543,8 @@ XenNet_RxBufferFree(struct xennet_info *
     3.4    int i;
     3.5    PMDL mdl;
     3.6  
     3.7 +  XenFreelist_Dispose(&xi->rx_freelist);
     3.8 +
     3.9    ASSERT(!xi->connected);
    3.10  
    3.11    for (i = 0; i < NET_RX_RING_SIZE; i++)
     4.1 --- a/xenpci/xenpci.c	Wed Jun 04 14:21:09 2008 +1000
     4.2 +++ b/xenpci/xenpci.c	Sat Jun 07 22:19:18 2008 +1000
     4.3 @@ -185,16 +185,6 @@ XenPci_AddDevice(PDRIVER_OBJECT DriverOb
     4.4    
     4.5    fdo->Flags &= ~DO_DEVICE_INITIALIZING;
     4.6  
     4.7 -#if 0
     4.8 -  WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFilePaging, TRUE);
     4.9 -  WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileHibernation, TRUE);
    4.10 -  WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileDump, TRUE);
    4.11 -
    4.12 -  busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
    4.13 -  busInfo.LegacyBusType = Internal;
    4.14 -  busInfo.BusNumber = 0;
    4.15 -#endif
    4.16 -
    4.17    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__"\n"));
    4.18    return status;
    4.19  }
     5.1 --- a/xenpci/xenpci.h	Wed Jun 04 14:21:09 2008 +1000
     5.2 +++ b/xenpci/xenpci.h	Sat Jun 07 22:19:18 2008 +1000
     5.3 @@ -222,7 +222,9 @@ typedef struct {
     5.4  
     5.5  typedef struct {  
     5.6    XENPCI_COMMON common;
     5.7 +  PDEVICE_OBJECT bus_pdo;
     5.8    PDEVICE_OBJECT bus_fdo;
     5.9 +  BOOLEAN ReportedMissing;
    5.10    char path[128];
    5.11    char device[128];
    5.12    ULONG index;
     6.1 --- a/xenpci/xenpci_fdo.c	Wed Jun 04 14:21:09 2008 +1000
     6.2 +++ b/xenpci/xenpci_fdo.c	Sat Jun 07 22:19:18 2008 +1000
     6.3 @@ -523,6 +523,8 @@ XenPci_DeviceWatchHandler(char *path, PV
     6.4  {
     6.5    char **bits;
     6.6    int count;
     6.7 +  char *err;
     6.8 +  char *value;
     6.9    PXENPCI_DEVICE_DATA xpdd = context;
    6.10  
    6.11    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.12 @@ -533,9 +535,19 @@ XenPci_DeviceWatchHandler(char *path, PV
    6.13  
    6.14    if (count == 3)
    6.15    {
    6.16 -    /* we probably have to be a bit smarter here and do nothing if xenpci isn't running yet */
    6.17 -    KdPrint((__DRIVER_NAME "     Invalidating Device Relations\n"));
    6.18 -    IoInvalidateDeviceRelations(xpdd->common.pdo, BusRelations);
    6.19 +    err = XenBus_Read(xpdd, XBT_NIL, path, &value);
    6.20 +    if (err)
    6.21 +    {
    6.22 +      /* obviously path no longer exists, in which case the removal is being taken care of elsewhere and we shouldn't invalidate now */
    6.23 +      XenPci_FreeMem(err);
    6.24 +    }
    6.25 +    else
    6.26 +    {
    6.27 +      XenPci_FreeMem(value);
    6.28 +      /* we probably have to be a bit smarter here and do nothing if xenpci isn't running yet */
    6.29 +      KdPrint((__DRIVER_NAME "     Invalidating Device Relations\n"));
    6.30 +      IoInvalidateDeviceRelations(xpdd->common.pdo, BusRelations);
    6.31 +    }
    6.32    }
    6.33    FreeSplitString(bits, count);
    6.34  
    6.35 @@ -738,7 +750,7 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    6.36    PIRP irp = context;
    6.37    int device_count = 0;
    6.38    PDEVICE_RELATIONS dev_relations;
    6.39 -  PXEN_CHILD child;
    6.40 +  PXEN_CHILD child, old_child;
    6.41    //char *response;
    6.42    char *msg;
    6.43    char **devices;
    6.44 @@ -746,6 +758,7 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    6.45    int i, j;
    6.46    CHAR path[128];
    6.47    PDEVICE_OBJECT pdo;
    6.48 +  
    6.49    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.50  
    6.51    msg = XenBus_List(xpdd, XBT_NIL, "device", &devices);
    6.52 @@ -801,12 +814,14 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    6.53              child->context = xppdd = pdo->DeviceExtension;
    6.54              xppdd->common.fdo = NULL;
    6.55              xppdd->common.pdo = pdo;
    6.56 +            ObReferenceObject(pdo);
    6.57              xppdd->common.lower_do = NULL;
    6.58              INIT_PNP_STATE(&xppdd->common);
    6.59              xppdd->common.device_usage_paging = 0;
    6.60              xppdd->common.device_usage_dump = 0;
    6.61              xppdd->common.device_usage_hibernation = 0;
    6.62 -            xppdd->bus_fdo = device_object;
    6.63 +            xppdd->bus_fdo = xpdd->common.fdo;
    6.64 +            xppdd->bus_pdo = xpdd->common.pdo;
    6.65              RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), path);
    6.66              RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), devices[i]);
    6.67              xppdd->index = atoi(instances[j]);
    6.68 @@ -827,18 +842,29 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    6.69      for (child = (PXEN_CHILD)xpdd->child_list.Flink, device_count = 0; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
    6.70      {
    6.71        if (child->state == CHILD_STATE_ADDED)
    6.72 +      {
    6.73 +        ObReferenceObject(child->context->common.pdo);
    6.74          dev_relations->Objects[device_count++] = child->context->common.pdo;
    6.75 +      }
    6.76      }
    6.77      dev_relations->Count = device_count;
    6.78  
    6.79 -    for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
    6.80 +    child = (PXEN_CHILD)xpdd->child_list.Flink;
    6.81 +    while (child != (PXEN_CHILD)&xpdd->child_list)
    6.82      {
    6.83        if (child->state == CHILD_STATE_DELETED)
    6.84        {
    6.85          KdPrint((__DRIVER_NAME "     Removing deleted child from device list\n" ));
    6.86 -        child->entry.Flink;
    6.87 -        ExFreePoolWithTag(child->entry.Blink, XENPCI_POOL_TAG);
    6.88 +        old_child = child;
    6.89 +        child = (PXEN_CHILD)child->entry.Flink;
    6.90 +        RemoveEntryList((PLIST_ENTRY)old_child);
    6.91 +        xppdd = old_child->context;
    6.92 +        xppdd->ReportedMissing = TRUE;
    6.93 +        ObDereferenceObject(xppdd->common.pdo);
    6.94 +        ExFreePoolWithTag(old_child, XENPCI_POOL_TAG);
    6.95        }
    6.96 +      else
    6.97 +        child = (PXEN_CHILD)child->entry.Flink;
    6.98      }
    6.99      
   6.100      status = STATUS_SUCCESS;
     7.1 --- a/xenpci/xenpci_pdo.c	Wed Jun 04 14:21:09 2008 +1000
     7.2 +++ b/xenpci/xenpci_pdo.c	Sat Jun 07 22:19:18 2008 +1000
     7.3 @@ -106,11 +106,15 @@ XenPci_BackEndStateHandler(char *Path, P
     7.4    err = XenBus_Read(xpdd, XBT_NIL, Path, &value);
     7.5    if (err)
     7.6    {
     7.7 -    KdPrint(("Failed to read %s\n", path, err));
     7.8 -    return;
     7.9 +    KdPrint(("Failed to read %s, assuming closed\n", path, err));
    7.10 +    new_backend_state = XenbusStateClosed;
    7.11 +    XenPci_FreeMem(err);
    7.12    }
    7.13 -  new_backend_state = atoi(value);
    7.14 -  XenPci_FreeMem(value);
    7.15 +  else
    7.16 +  {
    7.17 +    new_backend_state = atoi(value);
    7.18 +    XenPci_FreeMem(value);
    7.19 +  }
    7.20  
    7.21    if (xppdd->backend_state == new_backend_state)
    7.22    {
    7.23 @@ -618,31 +622,42 @@ XenPci_Pnp_RemoveDevice(PDEVICE_OBJECT d
    7.24  
    7.25    DUMP_CURRENT_PNP_STATE(xppdd);
    7.26  
    7.27 -  status = XenPci_ShutdownDevice(xppdd);
    7.28 -
    7.29 -  if (xppdd->xenbus_request != NULL)
    7.30 +  if (xppdd->common.current_pnp_state != Removed)
    7.31    {
    7.32 -    in_ptr = xppdd->xenbus_request;
    7.33 -    while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
    7.34 +    status = XenPci_ShutdownDevice(xppdd);
    7.35 +
    7.36 +    if (xppdd->xenbus_request != NULL)
    7.37      {
    7.38 -      switch (type)
    7.39 +      in_ptr = xppdd->xenbus_request;
    7.40 +      while((type = GET_XEN_INIT_REQ(&in_ptr, &setting, &value)) != XEN_INIT_TYPE_END)
    7.41        {
    7.42 -      case XEN_INIT_TYPE_RING: /* frontend ring */
    7.43 -        GntTbl_EndAccess(xpdd, xppdd->grant_refs[rings], FALSE);
    7.44 -        FreePages(xppdd->mdls[rings]);
    7.45 -        xppdd->mdls[rings] = NULL;
    7.46 -        rings++;
    7.47 -        break;
    7.48 -      case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
    7.49 -      case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
    7.50 -        EvtChn_Unbind(xpdd, xppdd->event_channels[event_channels++]);
    7.51 -        break;
    7.52 +        switch (type)
    7.53 +        {
    7.54 +        case XEN_INIT_TYPE_RING: /* frontend ring */
    7.55 +          GntTbl_EndAccess(xpdd, xppdd->grant_refs[rings], FALSE);
    7.56 +          FreePages(xppdd->mdls[rings]);
    7.57 +          xppdd->mdls[rings] = NULL;
    7.58 +          rings++;
    7.59 +          break;
    7.60 +        case XEN_INIT_TYPE_EVENT_CHANNEL: /* frontend event channel */
    7.61 +        case XEN_INIT_TYPE_EVENT_CHANNEL_IRQ: /* frontend event channel bound to irq */
    7.62 +          EvtChn_Unbind(xpdd, xppdd->event_channels[event_channels++]);
    7.63 +          break;
    7.64 +        }
    7.65        }
    7.66 +      ExFreePoolWithTag(xppdd->xenbus_request, XENPCI_POOL_TAG);
    7.67 +      xppdd->xenbus_request = NULL;
    7.68      }
    7.69 +    /* Remove watch on backend state */
    7.70 +    RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
    7.71 +    XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
    7.72 +    SET_PNP_STATE(&xppdd->common, Removed);
    7.73 +    IoInvalidateDeviceRelations(xppdd->bus_pdo, BusRelations);
    7.74    }
    7.75 -  /* Remove watch on backend state */
    7.76 -  RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/state", xppdd->backend_path);
    7.77 -  XenBus_RemWatch(xpdd, XBT_NIL, path, XenPci_BackEndStateHandler, xppdd);
    7.78 +  if (xppdd->ReportedMissing)
    7.79 +  {
    7.80 +    IoDeleteDevice(xppdd->common.pdo);
    7.81 +  }
    7.82    
    7.83    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (status = %08x)\n", status));
    7.84  
     8.1 --- a/xenvbd/scsiport.c	Wed Jun 04 14:21:09 2008 +1000
     8.2 +++ b/xenvbd/scsiport.c	Sat Jun 07 22:19:18 2008 +1000
     8.3 @@ -239,12 +239,18 @@ XenVbd_HwScsiFindAdapter(PVOID DeviceExt
     8.4    }
     8.5    if (xvdd->device_type == XENVBD_DEVICETYPE_UNKNOWN
     8.6      || sring == NULL
     8.7 -    || xvdd->event_channel == 0)
     8.8 +    || xvdd->event_channel == 0
     8.9 +    || xvdd->total_sectors == 0
    8.10 +    || xvdd->bytes_per_sector == 0)
    8.11    {
    8.12      KdPrint((__DRIVER_NAME "     Missing settings\n"));
    8.13      KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    8.14      return SP_RETURN_BAD_CONFIG;
    8.15    }
    8.16 +  
    8.17 +  /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
    8.18 +  xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
    8.19 +  
    8.20    ConfigInfo->MaximumTransferLength = BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE;
    8.21    ConfigInfo->NumberOfPhysicalBreaks = BLKIF_MAX_SEGMENTS_PER_REQUEST - 1;
    8.22    ConfigInfo->ScatterGather = TRUE;
    8.23 @@ -361,12 +367,15 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
    8.24    PUCHAR ptr;
    8.25    int notify;
    8.26  
    8.27 -// can use SRB_STATUS_BUSY to push the SRB back to windows...
    8.28 -
    8.29  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    8.30  
    8.31 -  ASSERT(!xvdd->pending_srb);
    8.32 -  
    8.33 +  if (srb_offset == 0 && xvdd->split_request_in_progress)
    8.34 +  {
    8.35 +    KdPrint((__DRIVER_NAME "     Split request in progress - deferring\n"));
    8.36 +    srb->SrbStatus = SRB_STATUS_BUSY;
    8.37 +    ScsiPortNotification(RequestComplete, xvdd, srb);
    8.38 +    return;
    8.39 +  }
    8.40    block_count = (srb->Cdb[7] << 8) | srb->Cdb[8];
    8.41    block_count *= xvdd->bytes_per_sector / 512;
    8.42    if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
    8.43 @@ -379,9 +388,12 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
    8.44      ptr = srb->DataBuffer;
    8.45      transfer_length = block_count * 512;
    8.46    }
    8.47 +
    8.48    if (xvdd->grant_free <= ADDRESS_AND_SIZE_TO_SPAN_PAGES(ptr, transfer_length))
    8.49    {
    8.50 -    xvdd->pending_srb = srb;
    8.51 +    KdPrint((__DRIVER_NAME "     No enough grants - deferring\n"));
    8.52 +    srb->SrbStatus = SRB_STATUS_BUSY;
    8.53 +    ScsiPortNotification(RequestComplete, xvdd, srb);
    8.54      return;
    8.55    }
    8.56    
    8.57 @@ -405,7 +417,9 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
    8.58      shadow->req.sector_number += srb_offset / 512; //xvdd->bytes_per_sector;
    8.59      KdPrint((__DRIVER_NAME "     Using unaligned buffer - DataBuffer = %p, SrbExtension = %p, total length = %d, offset = %d, length = %d, sector = %d\n", srb->DataBuffer, srb->SrbExtension, block_count * 512, shadow->offset, shadow->length, shadow->req.sector_number));
    8.60      if (srb->Cdb[0] == SCSIOP_WRITE)
    8.61 +    {
    8.62        memcpy(ptr, ((PUCHAR)srb->DataBuffer) + srb_offset, shadow->length);
    8.63 +    }
    8.64    }
    8.65    else
    8.66    {
    8.67 @@ -437,9 +451,14 @@ XenVbd_PutSrbOnRing(PXENVBD_DEVICE_DATA 
    8.68      xvdd->vectors.EvtChn_Notify(xvdd->vectors.context, xvdd->event_channel);
    8.69  
    8.70    /* we don't want another srb if we had to double buffer this one, it will put things out of order */
    8.71 -  if (xvdd->shadow_free && srb_offset + shadow->length == block_count * 512); // * xvdd->bytes_per_sector )
    8.72 +  if (xvdd->shadow_free && srb_offset + shadow->length == block_count * 512) // * xvdd->bytes_per_sector )
    8.73    {
    8.74      ScsiPortNotification(NextLuRequest, xvdd, 0, 0, 0);
    8.75 +    xvdd->split_request_in_progress = FALSE;
    8.76 +  }
    8.77 +  else
    8.78 +  {
    8.79 +    xvdd->split_request_in_progress = TRUE;
    8.80    }
    8.81  
    8.82    //KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    8.83 @@ -450,9 +469,12 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
    8.84  {
    8.85    PCDB cdb;
    8.86    PMODE_PARAMETER_HEADER parameter_header;
    8.87 +  PMODE_PARAMETER_BLOCK param_block;
    8.88 +  PMODE_FORMAT_PAGE format_page;
    8.89    UCHAR page_code;
    8.90    ULONG offset;
    8.91    UCHAR buffer[256];
    8.92 +  BOOLEAN valid_page = FALSE;
    8.93  
    8.94    UNREFERENCED_PARAMETER(xvdd);
    8.95  
    8.96 @@ -469,16 +491,61 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
    8.97    parameter_header->DeviceSpecificParameter = 0;
    8.98    parameter_header->BlockDescriptorLength = 0;
    8.99    offset += sizeof(MODE_PARAMETER_HEADER);
   8.100 -  parameter_header->ModeDataLength = (UCHAR)(offset - 4);
   8.101 -  srb->DataTransferLength = min(srb->DataTransferLength, offset);
   8.102 -  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
   8.103 -  KdPrint((__DRIVER_NAME "     DataTransferLength = %d\n", srb->DataTransferLength));
   8.104 -  KdPrint((__DRIVER_NAME "     ModeDataLength = %d\n", parameter_header->ModeDataLength));
   8.105 -  if (offset != srb->DataTransferLength)
   8.106 +  
   8.107 +  if (!cdb->MODE_SENSE.Dbd)
   8.108 +  {
   8.109 +    parameter_header->BlockDescriptorLength += sizeof(MODE_PARAMETER_BLOCK);
   8.110 +    param_block = (PMODE_PARAMETER_BLOCK)&buffer[offset];
   8.111 +    if (xvdd->device_type == XENVBD_DEVICETYPE_DISK)
   8.112 +    {
   8.113 +      if (xvdd->total_sectors >> 32) 
   8.114 +      {
   8.115 +        param_block->DensityCode = 0xff;
   8.116 +        param_block->NumberOfBlocks[0] = 0xff;
   8.117 +        param_block->NumberOfBlocks[1] = 0xff;
   8.118 +        param_block->NumberOfBlocks[2] = 0xff;
   8.119 +      }
   8.120 +      else
   8.121 +      {
   8.122 +        param_block->DensityCode = (UCHAR)((xvdd->total_sectors >> 24) & 0xff);
   8.123 +        param_block->NumberOfBlocks[0] = (UCHAR)((xvdd->total_sectors >> 16) & 0xff);
   8.124 +        param_block->NumberOfBlocks[1] = (UCHAR)((xvdd->total_sectors >> 8) & 0xff);
   8.125 +        param_block->NumberOfBlocks[2] = (UCHAR)((xvdd->total_sectors >> 0) & 0xff);
   8.126 +      }
   8.127 +      param_block->BlockLength[0] = (UCHAR)((xvdd->bytes_per_sector >> 16) & 0xff);
   8.128 +      param_block->BlockLength[1] = (UCHAR)((xvdd->bytes_per_sector >> 8) & 0xff);
   8.129 +      param_block->BlockLength[2] = (UCHAR)((xvdd->bytes_per_sector >> 0) & 0xff);
   8.130 +    }
   8.131 +    offset += sizeof(MODE_PARAMETER_BLOCK);
   8.132 +  }
   8.133 +  if (xvdd->device_type == XENVBD_DEVICETYPE_DISK && (page_code == MODE_PAGE_FORMAT_DEVICE || page_code == MODE_SENSE_RETURN_ALL))
   8.134 +  {
   8.135 +    valid_page = TRUE;
   8.136 +    format_page = (PMODE_FORMAT_PAGE)&buffer[offset];
   8.137 +    format_page->PageCode = MODE_PAGE_FORMAT_DEVICE;
   8.138 +    format_page->PageLength = sizeof(MODE_FORMAT_PAGE) - FIELD_OFFSET(MODE_FORMAT_PAGE, PageLength);
   8.139 +    /* 256 sectors per track */
   8.140 +    format_page->SectorsPerTrack[0] = 0x01;
   8.141 +    format_page->SectorsPerTrack[1] = 0x00;
   8.142 +    /* xxx bytes per sector */
   8.143 +    format_page->BytesPerPhysicalSector[0] = (UCHAR)(xvdd->bytes_per_sector >> 8);
   8.144 +    format_page->BytesPerPhysicalSector[1] = (UCHAR)(xvdd->bytes_per_sector & 0xff);
   8.145 +    format_page->HardSectorFormating = TRUE;
   8.146 +    format_page->SoftSectorFormating = TRUE;
   8.147 +    offset += sizeof(MODE_FORMAT_PAGE);
   8.148 +  }
   8.149 +  parameter_header->ModeDataLength = (UCHAR)(offset - 1);
   8.150 +  if (!valid_page && page_code != MODE_SENSE_RETURN_ALL)
   8.151 +  {
   8.152 +    srb->SrbStatus = SRB_STATUS_ERROR;
   8.153 +  }
   8.154 +  else if(offset < srb->DataTransferLength)
   8.155      srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
   8.156    else
   8.157      srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.158 +  srb->DataTransferLength = min(srb->DataTransferLength, offset);
   8.159    srb->ScsiStatus = 0;
   8.160 +  memcpy(srb->DataBuffer, buffer, srb->DataTransferLength);
   8.161    
   8.162    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
   8.163  
   8.164 @@ -486,7 +553,7 @@ XenVbd_FillModePage(PXENVBD_DEVICE_DATA 
   8.165  }
   8.166  
   8.167  static VOID
   8.168 -XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, BOOLEAN sense_key)
   8.169 +XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvdd, PSCSI_REQUEST_BLOCK srb, UCHAR sense_key, UCHAR additional_sense_code)
   8.170  {
   8.171    PSENSE_DATA sd = srb->SenseInfoBuffer;
   8.172   
   8.173 @@ -499,6 +566,7 @@ XenVbd_MakeSense(PXENVBD_DEVICE_DATA xvd
   8.174    sd->Valid = 1;
   8.175    sd->SenseKey = sense_key;
   8.176    sd->AdditionalSenseLength = sizeof(SENSE_DATA) - FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
   8.177 +  sd->AdditionalSenseCode = additional_sense_code;
   8.178    return;
   8.179  }
   8.180  
   8.181 @@ -507,7 +575,7 @@ XenVbd_MakeAutoSense(PXENVBD_DEVICE_DATA
   8.182  {
   8.183    if (srb->SrbStatus == SRB_STATUS_SUCCESS || srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
   8.184      return;
   8.185 -  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key);
   8.186 +  XenVbd_MakeSense(xvdd, srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
   8.187    srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
   8.188  }
   8.189  
   8.190 @@ -581,6 +649,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.191            srb->SrbStatus = SRB_STATUS_ERROR;
   8.192            srb->ScsiStatus = 0x02;
   8.193            xvdd->last_sense_key = SCSI_SENSE_MEDIUM_ERROR;
   8.194 +          xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   8.195            XenVbd_MakeAutoSense(xvdd, srb);
   8.196          }
   8.197          for (j = 0; j < shadow->req.nr_segments; j++)
   8.198 @@ -592,11 +661,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.199          if (PtrToUlong(srb->DataBuffer) & 511) /* use SrbExtension intead of DataBuffer if DataBuffer is not aligned to sector size */
   8.200          {
   8.201            if (srb->Cdb[0] == SCSIOP_READ)
   8.202 -          {
   8.203 -            memcpy(((PUCHAR)srb->DataBuffer) + shadow->offset, srb->SrbExtension, shadow->length);
   8.204 -            //KdPrint((__DRIVER_NAME "     (RD) memcpy(%p, %p, %d)\n", ((PUCHAR)srb->DataBuffer) + shadow->offset, srb->SrbExtension, shadow->length));
   8.205 -          }
   8.206 -          //KdPrint((__DRIVER_NAME "     (Get) id = %d, DataBuffer = %p, SrbExtension = %p, total length = %d, offset = %d, length = %d\n", (ULONG)shadow->req.id, srb->DataBuffer, srb->SrbExtension, block_count * xvdd->bytes_per_sector, shadow->offset, shadow->length));
   8.207 +            memcpy(((PUCHAR)srb->DataBuffer) + shadow->offset, GET_PAGE_ALIGNED(srb->SrbExtension), shadow->length);
   8.208            offset = shadow->offset + shadow->length;
   8.209            put_shadow_on_freelist(xvdd, shadow);
   8.210            if (offset == block_count * xvdd->bytes_per_sector)
   8.211 @@ -613,6 +678,7 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.212          {
   8.213            put_shadow_on_freelist(xvdd, shadow);
   8.214            ScsiPortNotification(RequestComplete, xvdd, srb);
   8.215 +#if 0
   8.216            if (xvdd->pending_srb)
   8.217            {
   8.218              srb = xvdd->pending_srb;
   8.219 @@ -620,7 +686,8 @@ XenVbd_HwScsiInterrupt(PVOID DeviceExten
   8.220              XenVbd_PutSrbOnRing(xvdd, srb, 0);
   8.221            }
   8.222            else
   8.223 -            ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   8.224 +#endif
   8.225 +          ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   8.226          }
   8.227        }
   8.228      }
   8.229 @@ -678,7 +745,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.230      switch(cdb->CDB6GENERIC.OperationCode)
   8.231      {
   8.232      case SCSIOP_TEST_UNIT_READY:
   8.233 -//      KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
   8.234 +      //KdPrint((__DRIVER_NAME "     Command = TEST_UNIT_READY\n"));
   8.235        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.236        Srb->ScsiStatus = 0;
   8.237        break;
   8.238 @@ -785,13 +852,26 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.239        }
   8.240        break;
   8.241      case SCSIOP_READ_CAPACITY:
   8.242 -      //KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
   8.243 +      KdPrint((__DRIVER_NAME "     Command = READ_CAPACITY\n"));
   8.244 +      //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", Srb->Cdb[1] >> 4, Srb->Cdb[1] & 1));
   8.245 +      //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", Srb->Cdb[2], Srb->Cdb[3], Srb->Cdb[4], Srb->Cdb[5]));
   8.246 +      //KdPrint((__DRIVER_NAME "       PMI = %d\n", Srb->Cdb[8] & 1));
   8.247        DataBuffer = Srb->DataBuffer;
   8.248        RtlZeroMemory(DataBuffer, Srb->DataTransferLength);
   8.249 -      DataBuffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
   8.250 -      DataBuffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
   8.251 -      DataBuffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
   8.252 -      DataBuffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
   8.253 +      if ((xvdd->total_sectors - 1) >> 32)
   8.254 +      {
   8.255 +        DataBuffer[0] = 0xff;
   8.256 +        DataBuffer[1] = 0xff;
   8.257 +        DataBuffer[2] = 0xff;
   8.258 +        DataBuffer[3] = 0xff;
   8.259 +      }
   8.260 +      else
   8.261 +      {
   8.262 +        DataBuffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 24) & 0xff;
   8.263 +        DataBuffer[1] = (unsigned char)((xvdd->total_sectors - 1) >> 16) & 0xff;
   8.264 +        DataBuffer[2] = (unsigned char)((xvdd->total_sectors - 1) >> 8) & 0xff;
   8.265 +        DataBuffer[3] = (unsigned char)((xvdd->total_sectors - 1) >> 0) & 0xff;
   8.266 +      }
   8.267        DataBuffer[4] = (unsigned char)(xvdd->bytes_per_sector >> 24) & 0xff;
   8.268        DataBuffer[5] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
   8.269        DataBuffer[6] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
   8.270 @@ -800,8 +880,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.271        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.272        break;
   8.273      case SCSIOP_MODE_SENSE:
   8.274 -      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x10, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
   8.275 -      KdPrint((__DRIVER_NAME "     Length = %d\n", Srb->DataTransferLength));
   8.276 +      KdPrint((__DRIVER_NAME "     Command = MODE_SENSE (DBD = %d, PC = %d, Page Code = %02x)\n", Srb->Cdb[1] & 0x08, Srb->Cdb[2] & 0xC0, Srb->Cdb[2] & 0x3F));
   8.277        XenVbd_FillModePage(xvdd, Srb);
   8.278        break;
   8.279      case SCSIOP_WRITE:
   8.280 @@ -819,7 +898,8 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.281        Srb->SrbStatus = SRB_STATUS_SUCCESS;;
   8.282        break;
   8.283      case SCSIOP_REQUEST_SENSE:
   8.284 -      XenVbd_MakeSense(xvdd, Srb, xvdd->last_sense_key);
   8.285 +      KdPrint((__DRIVER_NAME "     Command = REQUEST_SENSE\n"));
   8.286 +      XenVbd_MakeSense(xvdd, Srb, xvdd->last_sense_key, xvdd->last_additional_sense_code);
   8.287        Srb->SrbStatus = SRB_STATUS_SUCCESS;
   8.288        break;      
   8.289      case SCSIOP_READ_TOC:
   8.290 @@ -884,8 +964,12 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.291      }
   8.292      if (Srb->SrbStatus == SRB_STATUS_ERROR)
   8.293      {
   8.294 +      KdPrint((__DRIVER_NAME "     EXECUTE_SCSI Command = %02X returned error %02x\n", Srb->Cdb[0], xvdd->last_sense_key));
   8.295        if (xvdd->last_sense_key == SCSI_SENSE_NO_SENSE)
   8.296 +      {
   8.297          xvdd->last_sense_key = SCSI_SENSE_ILLEGAL_REQUEST;
   8.298 +        xvdd->last_additional_sense_code = SCSI_ADSENSE_INVALID_CDB;
   8.299 +      }
   8.300        Srb->ScsiStatus = 0x02;
   8.301        XenVbd_MakeAutoSense(xvdd, Srb);
   8.302        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   8.303 @@ -894,6 +978,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
   8.304      else if (Srb->SrbStatus != SRB_STATUS_PENDING)
   8.305      {
   8.306        xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
   8.307 +      xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
   8.308        ScsiPortNotification(RequestComplete, DeviceExtension, Srb);
   8.309        ScsiPortNotification(NextLuRequest, DeviceExtension, 0, 0, 0);
   8.310      }
     9.1 --- a/xenvbd/xenvbd.c	Wed Jun 04 14:21:09 2008 +1000
     9.2 +++ b/xenvbd/xenvbd.c	Sat Jun 07 22:19:18 2008 +1000
     9.3 @@ -111,7 +111,7 @@ XenVbd_Pnp(PDEVICE_OBJECT device_object,
     9.4      status = XenVbd_Pnp_Original(device_object, irp);
     9.5  
     9.6      break;
     9.7 -
     9.8 +#if 0
     9.9    case IRP_MN_QUERY_STOP_DEVICE:
    9.10      KdPrint((__DRIVER_NAME "     IRP_MN_QUERY_STOP_DEVICE\n"));
    9.11      status = XenVbd_Pnp_Original(device_object, irp);
    9.12 @@ -146,9 +146,10 @@ XenVbd_Pnp(PDEVICE_OBJECT device_object,
    9.13      KdPrint((__DRIVER_NAME "     IRP_MN_SURPRISE_REMOVAL\n"));
    9.14      status = XenVbd_Pnp_Original(device_object, irp);
    9.15      break;
    9.16 +#endif
    9.17  
    9.18    default:
    9.19 -    KdPrint((__DRIVER_NAME "     Unknown Minor = %d\n", stack->MinorFunction));
    9.20 +    //KdPrint((__DRIVER_NAME "     Unknown Minor = %d\n", stack->MinorFunction));
    9.21      status = XenVbd_Pnp_Original(device_object, irp);
    9.22      break;
    9.23    }
    10.1 --- a/xenvbd/xenvbd.h	Wed Jun 04 14:21:09 2008 +1000
    10.2 +++ b/xenvbd/xenvbd.h	Sat Jun 07 22:19:18 2008 +1000
    10.3 @@ -108,13 +108,15 @@ struct
    10.4    int ring_detect_state;
    10.5    BOOLEAN use_other;
    10.6    UCHAR last_sense_key;
    10.7 +  UCHAR last_additional_sense_code;
    10.8    blkif_response_t tmp_rep;
    10.9    XENVBD_DEVICETYPE device_type;
   10.10    DISK_GEOMETRY Geometry;
   10.11    ULONG bytes_per_sector;
   10.12    ULONGLONG total_sectors;
   10.13    XENPCI_VECTORS vectors;
   10.14 -  PSCSI_REQUEST_BLOCK pending_srb;
   10.15 +  //PSCSI_REQUEST_BLOCK pending_srb;
   10.16 +  BOOLEAN split_request_in_progress;
   10.17  } typedef XENVBD_DEVICE_DATA, *PXENVBD_DEVICE_DATA;
   10.18  
   10.19  VOID