win-pvdrivers

changeset 783:644e5ddb1b47

Handle SCSI INQUIRY command better in xenvbd
author James Harper <james.harper@bendigoit.com.au>
date Mon Feb 15 20:53:57 2010 +1100 (2010-02-15)
parents 6304eb6bb690
children 744be619e07c
files xenvbd/xenvbd.c
line diff
     1.1 --- a/xenvbd/xenvbd.c	Mon Feb 15 19:46:45 2010 +1100
     1.2 +++ b/xenvbd/xenvbd.c	Mon Feb 15 20:53:57 2010 +1100
     1.3 @@ -982,6 +982,7 @@ XenVbd_HwScsiStartIo(PVOID DeviceExtensi
     1.4    //ULONG data_buffer_length;
     1.5    PCDB cdb;
     1.6    PXENVBD_DEVICE_DATA xvdd = DeviceExtension;
     1.7 +  ULONG data_transfer_length = srb->DataTransferLength;
     1.8  
     1.9  
    1.10  if (xvdd->aligned_buffer_in_use)
    1.11 @@ -1064,15 +1065,23 @@ if (xvdd->aligned_buffer_in_use)
    1.12        case XENVBD_DEVICETYPE_DISK:
    1.13          if ((srb->Cdb[1] & 1) == 0)
    1.14          {
    1.15 -          PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
    1.16 -          id->DeviceType = DIRECT_ACCESS_DEVICE;
    1.17 -          id->Versions = 3;
    1.18 -          id->ResponseDataFormat = 0;
    1.19 -          id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
    1.20 -          id->CommandQueue = 1;
    1.21 -          memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
    1.22 -          memcpy(id->ProductId, scsi_disk_model, 16); // product id
    1.23 -          memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
    1.24 +          if (srb->Cdb[2])
    1.25 +          {
    1.26 +            srb->SrbStatus = SRB_STATUS_ERROR;
    1.27 +          }
    1.28 +          else
    1.29 +          {
    1.30 +            PINQUIRYDATA id = (PINQUIRYDATA)data_buffer;
    1.31 +            id->DeviceType = DIRECT_ACCESS_DEVICE;
    1.32 +            id->Versions = 3;
    1.33 +            id->ResponseDataFormat = 2; /* not sure about this but WHQL complains otherwise */
    1.34 +            id->AdditionalLength = FIELD_OFFSET(INQUIRYDATA, VendorSpecific) - FIELD_OFFSET(INQUIRYDATA, AdditionalLength);
    1.35 +            id->CommandQueue = 1;
    1.36 +            memcpy(id->VendorId, scsi_device_manufacturer, 8); // vendor id
    1.37 +            memcpy(id->ProductId, scsi_disk_model, 16); // product id
    1.38 +            memcpy(id->ProductRevisionLevel, "0000", 4); // product revision level
    1.39 +            data_transfer_length = sizeof(INQUIRYDATA);
    1.40 +          }
    1.41          }
    1.42          else
    1.43          {
    1.44 @@ -1085,6 +1094,7 @@ if (xvdd->aligned_buffer_in_use)
    1.45              data_buffer[3] = 2;
    1.46              data_buffer[4] = 0x00;
    1.47              data_buffer[5] = 0x80;
    1.48 +            data_transfer_length = 6;
    1.49              break;
    1.50            case 0x80:
    1.51              data_buffer[0] = DIRECT_ACCESS_DEVICE;
    1.52 @@ -1092,6 +1102,7 @@ if (xvdd->aligned_buffer_in_use)
    1.53              data_buffer[2] = 0x00;
    1.54              data_buffer[3] = 8;
    1.55              memset(&data_buffer[4], ' ', 8);
    1.56 +            data_transfer_length = 12;
    1.57              break;
    1.58            default:
    1.59              //KdPrint((__DRIVER_NAME "     Unknown Page %02x requested\n", srb->Cdb[2]));
    1.60 @@ -1318,6 +1329,11 @@ if (xvdd->aligned_buffer_in_use)
    1.61      }
    1.62      else if (srb->SrbStatus != SRB_STATUS_PENDING)
    1.63      {
    1.64 +      if (srb->SrbStatus == SRB_STATUS_SUCCESS && data_transfer_length < srb->DataTransferLength)
    1.65 +      {
    1.66 +        srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
    1.67 +        srb->DataTransferLength = data_transfer_length;
    1.68 +      }
    1.69        xvdd->last_sense_key = SCSI_SENSE_NO_SENSE;
    1.70        xvdd->last_additional_sense_code = SCSI_ADSENSE_NO_SENSE;
    1.71        ScsiPortNotification(RequestComplete, DeviceExtension, srb);