win-pvdrivers

changeset 983:d9da5f8f7431

better management of sector size
author James Harper <james.harper@bendigoit.com.au>
date Fri Sep 21 10:08:28 2012 +1000 (2012-09-21)
parents b96f14f62b50
children aefd5458e6c3
files xenvbd/xenvbd_storport.c
line diff
     1.1 --- a/xenvbd/xenvbd_storport.c	Sun Jun 17 14:57:35 2012 +1000
     1.2 +++ b/xenvbd/xenvbd_storport.c	Fri Sep 21 10:08:28 2012 +1000
     1.3 @@ -259,7 +259,7 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
     1.4        if (strcmp(setting, "sectors") == 0)
     1.5          xvdd->total_sectors = parse_numeric_string(value);
     1.6        else if (strcmp(setting, "sector-size") == 0)
     1.7 -        xvdd->bytes_per_sector = (ULONG)parse_numeric_string(value);
     1.8 +        xvdd->hw_bytes_per_sector = (ULONG)parse_numeric_string(value);
     1.9        else if (strcmp(setting, "device-type") == 0)
    1.10        {
    1.11          if (strcmp(value, "disk") == 0)
    1.12 @@ -325,30 +325,29 @@ XenVbd_InitFromConfig(PXENVBD_DEVICE_DAT
    1.13        || xvdd->sring == NULL
    1.14        || xvdd->event_channel == 0
    1.15        || xvdd->total_sectors == 0
    1.16 -      || xvdd->bytes_per_sector == 0))
    1.17 +      || xvdd->hw_bytes_per_sector == 0))
    1.18    {
    1.19      KdPrint((__DRIVER_NAME "     Missing settings\n"));
    1.20      FUNCTION_EXIT();
    1.21      return SP_RETURN_BAD_CONFIG;
    1.22    }
    1.23  
    1.24 -  if (xvdd->inactive)
    1.25 +  if (xvdd->inactive) {
    1.26      KdPrint((__DRIVER_NAME "     Device is inactive\n"));
    1.27 -  else
    1.28 -  {
    1.29 -    if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM)
    1.30 -    {
    1.31 +  } else {
    1.32 +    if (xvdd->device_type == XENVBD_DEVICETYPE_CDROM) {
    1.33        /* CD/DVD drives must have bytes_per_sector = 2048. */
    1.34        xvdd->bytes_per_sector = 2048;
    1.35 +      xvdd->hw_bytes_per_sector = 2048;
    1.36 +    } else {
    1.37 +      xvdd->bytes_per_sector = 512;
    1.38      }
    1.39 -
    1.40      /* for some reason total_sectors is measured in 512 byte sectors always, so correct this to be in bytes_per_sectors */
    1.41      xvdd->total_sectors /= xvdd->bytes_per_sector / 512;
    1.42  
    1.43      xvdd->shadow_free = 0;
    1.44      memset(xvdd->shadows, 0, sizeof(blkif_shadow_t) * SHADOW_ENTRIES);
    1.45 -    for (i = 0; i < SHADOW_ENTRIES; i++)
    1.46 -    {
    1.47 +    for (i = 0; i < SHADOW_ENTRIES; i++) {
    1.48        xvdd->shadows[i].req.id = i;
    1.49        /* make sure leftover real requests's are never confused with dump mode requests */
    1.50        if (dump_mode)
    1.51 @@ -439,6 +438,7 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    1.52  {
    1.53    PSCSI_REQUEST_BLOCK srb;
    1.54    srb_list_entry_t *srb_entry;
    1.55 +  /* sector_number and block_count are the adjusted-to-512-byte-sector values */
    1.56    ULONGLONG sector_number;
    1.57    ULONG block_count;
    1.58    blkif_shadow_t *shadow;
    1.59 @@ -491,13 +491,12 @@ XenVbd_PutQueuedSrbsOnRing(PXENVBD_DEVIC
    1.60        system_address = (PUCHAR)srb->DataBuffer + srb_entry->offset;
    1.61      }
    1.62      block_count = decode_cdb_length(srb);
    1.63 +    sector_number = decode_cdb_sector(srb);
    1.64      block_count *= xvdd->bytes_per_sector / 512;
    1.65 -    sector_number = decode_cdb_sector(srb);
    1.66      sector_number *= xvdd->bytes_per_sector / 512;
    1.67  
    1.68 -    ASSERT(block_count * xvdd->bytes_per_sector == srb->DataTransferLength);
    1.69 +    ASSERT(block_count * 512 == srb->DataTransferLength);
    1.70      
    1.71 -    //KdPrint((__DRIVER_NAME "     srb sector_number = %d, block_count = %d\n", (ULONG)sector_number, block_count));
    1.72      
    1.73      sector_number += srb_entry->offset / 512;
    1.74      block_count -= srb_entry->offset / 512;
    1.75 @@ -1428,7 +1427,6 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
    1.76  //      KdPrint((__DRIVER_NAME "     (LUN = %d, EVPD = %d, Page Code = %02X)\n", srb->Cdb[1] >> 5, srb->Cdb[1] & 1, srb->Cdb[2]));
    1.77  //      KdPrint((__DRIVER_NAME "     (Length = %d)\n", srb->DataTransferLength));
    1.78        
    1.79 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
    1.80        data_buffer = srb->DataBuffer;
    1.81        RtlZeroMemory(data_buffer, srb->DataTransferLength);
    1.82        srb_status = SRB_STATUS_SUCCESS;
    1.83 @@ -1590,7 +1588,6 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
    1.84        //KdPrint((__DRIVER_NAME "       LUN = %d, RelAdr = %d\n", srb->Cdb[1] >> 4, srb->Cdb[1] & 1));
    1.85        //KdPrint((__DRIVER_NAME "       LBA = %02x%02x%02x%02x\n", srb->Cdb[2], srb->Cdb[3], srb->Cdb[4], srb->Cdb[5]));
    1.86        //KdPrint((__DRIVER_NAME "       PMI = %d\n", srb->Cdb[8] & 1));
    1.87 -      //data_buffer = LongLongToPtr(ScsiPortGetPhysicalAddress(xvdd, srb, srb->DataBuffer, &data_buffer_length).QuadPart);
    1.88        data_buffer = srb->DataBuffer;
    1.89        RtlZeroMemory(data_buffer, srb->DataTransferLength);
    1.90        data_buffer[0] = (unsigned char)((xvdd->total_sectors - 1) >> 56) & 0xff;
    1.91 @@ -1605,7 +1602,28 @@ XenVbd_HwStorStartIo(PVOID DeviceExtensi
    1.92        data_buffer[9] = (unsigned char)(xvdd->bytes_per_sector >> 16) & 0xff;
    1.93        data_buffer[10] = (unsigned char)(xvdd->bytes_per_sector >> 8) & 0xff;
    1.94        data_buffer[11] = (unsigned char)(xvdd->bytes_per_sector >> 0) & 0xff;
    1.95 -      data_transfer_length = 12;
    1.96 +      data_buffer[12] = 0;
    1.97 +      switch (xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector) {
    1.98 +      case 1:
    1.99 +        data_buffer[13] = 0; /* 512 byte hardware sectors */
   1.100 +        break;
   1.101 +      case 2:
   1.102 +        data_buffer[13] = 1; /* 1024 byte hardware sectors */
   1.103 +        break;
   1.104 +      case 3:
   1.105 +        data_buffer[13] = 2; /* 2048 byte hardware sectors */
   1.106 +        break;
   1.107 +      case 4:
   1.108 +        data_buffer[13] = 2; /* 4096 byte hardware sectors */
   1.109 +        break;
   1.110 +      default:
   1.111 +        data_buffer[13] = 0; /* 512 byte hardware sectors */
   1.112 +        KdPrint((__DRIVER_NAME "     Unknown logical blocks per physical block %d (%d / %d)\n", xvdd->hw_bytes_per_sector / xvdd->bytes_per_sector, xvdd->hw_bytes_per_sector, xvdd->bytes_per_sector));
   1.113 +        break;
   1.114 +      }
   1.115 +      data_buffer[14] = 0;
   1.116 +      data_buffer[15] = 0;
   1.117 +      data_transfer_length = 16;
   1.118        srb->ScsiStatus = 0;
   1.119        srb_status = SRB_STATUS_SUCCESS;
   1.120        break;