Implemented SRB_FUNCTION_IO_CONTROL/IOCTL_SCSI_MINIPORT_IDENTIFY. Modified: trunk/reactos/drivers/storage/atapi/atapi.c _____
Modified: trunk/reactos/drivers/storage/atapi/atapi.c --- trunk/reactos/drivers/storage/atapi/atapi.c 2005-10-05 18:24:24 UTC (rev 18274) +++ trunk/reactos/drivers/storage/atapi/atapi.c 2005-10-05 18:36:10 UTC (rev 18275) @@ -52,6 +52,8 @@
#include <ddk/srb.h> #include <ddk/scsi.h> #include <ddk/ntddscsi.h> +#include <ddk/ntdddisk.h> +#include <ddk/ntddstor.h>
#include "atapi.h"
@@ -936,6 +938,60 @@ } break;
+ case SRB_FUNCTION_IO_CONTROL: + { + PSRB_IO_CONTROL SrbIoControl = (PSRB_IO_CONTROL)Srb->DataBuffer; + if (!_strnicmp((char*)SrbIoControl->Signature, "ScsiDisk", 8)) + { + switch (SrbIoControl->ControlCode) + { + default: + Result = SRB_STATUS_INVALID_REQUEST; + break; + + case IOCTL_SCSI_MINIPORT_IDENTIFY: + { + PSENDCMDOUTPARAMS OutParams = (PSENDCMDOUTPARAMS)((ULONG_PTR)Srb->DataBuffer + sizeof(SRB_IO_CONTROL)); + SENDCMDINPARAMS InParams = *(PSENDCMDINPARAMS)OutParams; + + + RtlZeroMemory(OutParams, Srb->DataTransferLength - sizeof(SRB_IO_CONTROL)); + + if (InParams.irDriveRegs.bCommandReg != IDE_CMD_IDENT_ATA_DRV) + { + DPRINT1("bCommandReg: %x\n", InParams.irDriveRegs.bCommandReg); + OutParams->DriverStatus.bIDEError = 1; + Result = SRB_STATUS_INVALID_REQUEST; + break; + } + + if (InParams.bDriveNumber > 1 || + (DevExt->DeviceFlags[InParams.bDriveNumber] & (DEVICE_PRESENT|DEVICE_ATAPI)) != DEVICE_PRESENT) + { + OutParams->DriverStatus.bIDEError = 1; + Result = SRB_STATUS_NO_DEVICE; + break; + } + + if (Srb->DataTransferLength > sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDOUTPARAMS) - 1) + { + OutParams->cBufferSize = min(IDENTIFY_BUFFER_SIZE, Srb->DataTransferLength - (sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDOUTPARAMS) - 1)); + RtlCopyMemory(OutParams->bBuffer, &DevExt->DeviceParams[InParams.bDriveNumber], OutParams->cBufferSize); + } + + Result = SRB_STATUS_SUCCESS; + break; + } + } + } + else + { + Result = SRB_STATUS_INVALID_REQUEST; + } + + break; + } + default: Result = SRB_STATUS_INVALID_REQUEST; break; @@ -1176,6 +1232,12 @@ { DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_NO_FLUSH; } + + /* Don't flush CD/DVD drives */ + if (((DeviceExtension->DeviceParams[UnitNumber].ConfigBits >> 8) & 0x1F) == READ_ONLY_DIRECT_ACCESS_DEVICE) + { + DeviceExtension->DeviceFlags[UnitNumber] |= DEVICE_NO_FLUSH; + } DeviceFound = TRUE; } else @@ -1292,6 +1354,9 @@ { LONG i; ULONG mode; + char SerialNumber[20]; + char FirmwareRev[8]; + char ModelNumber[40];
/* Get the Drive Identify block from drive or die */ if (AtapiPolledRead(CommandPort, @@ -1310,9 +1375,12 @@ }
/* Report on drive parameters if debug mode */ - IDESwapBytePairs(DrvParms->SerialNumber, 20); - IDESwapBytePairs(DrvParms->FirmwareRev, 8); - IDESwapBytePairs(DrvParms->ModelNumber, 40); + memcpy(SerialNumber, DrvParms->SerialNumber, 20); + memcpy(FirmwareRev, DrvParms->FirmwareRev, 8); + memcpy(ModelNumber, DrvParms->ModelNumber, 40); + IDESwapBytePairs((PUCHAR)SerialNumber, 20); + IDESwapBytePairs((PUCHAR)FirmwareRev, 8); + IDESwapBytePairs((PUCHAR)ModelNumber, 40); DPRINT("Config:%04x Cyls:%5d Heads:%2d Sectors/Track:%3d Gaps:%02d %02d\n", DrvParms->ConfigBits, DrvParms->LogicalCyls, @@ -1323,13 +1391,13 @@ DPRINT("Bytes/PLO:%3d Vendor Cnt:%2d Serial number:[%.20s]\n", DrvParms->BytesInPLO, DrvParms->VendorUniqueCnt, - DrvParms->SerialNumber); + SerialNumber); DPRINT("Cntlr type:%2d BufSiz:%5d ECC bytes:%3d Firmware Rev:[%.8s]\n", DrvParms->ControllerType, DrvParms->BufferSize * IDE_SECTOR_BUF_SZ, DrvParms->ECCByteCnt, - DrvParms->FirmwareRev); - DPRINT("Model:[%.40s]\n", DrvParms->ModelNumber); + FirmwareRev); + DPRINT("Model:[%.40s]\n", ModelNumber); DPRINT("RWMultMax?:%04x RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n", (DrvParms->RWMultImplemented), (DrvParms->RWMultCurrent) & 0xff, @@ -1897,7 +1965,6 @@ { PIDE_DRIVE_IDENTIFY DeviceParams; PINQUIRYDATA InquiryData; - ULONG i;
DPRINT("SCSIOP_INQUIRY: DeviceExtension %p TargetId: %lu\n", DeviceExtension, Srb->TargetId); @@ -1906,10 +1973,7 @@ DeviceParams = &DeviceExtension->DeviceParams[Srb->TargetId];
/* clear buffer */ - for (i = 0; i < Srb->DataTransferLength; i++) - { - ((PUCHAR)Srb->DataBuffer)[i] = 0; - } + memset(Srb->DataBuffer, 0, Srb->DataTransferLength);
/* set device class */ if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_ATAPI) @@ -1917,12 +1981,6 @@ /* get it from the ATAPI configuration word */ InquiryData->DeviceType = (DeviceParams->ConfigBits >> 8) & 0x1F; DPRINT("Device class: %u\n", InquiryData->DeviceType); - - /* Don't flush CD/DVD drives */ - if (InquiryData->DeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE) - { - DeviceExtension->DeviceFlags[Srb->TargetId] |= DEVICE_NO_FLUSH; - } } else { @@ -1937,26 +1995,13 @@ InquiryData->RemovableMedia = 1; }
- for (i = 0; i < 20; i += 2) - { - InquiryData->VendorId[i] = - ((PUCHAR)DeviceParams->ModelNumber)[i]; - InquiryData->VendorId[i+1] = - ((PUCHAR)DeviceParams->ModelNumber)[i+1]; - } + memcpy(InquiryData->VendorId, DeviceParams->ModelNumber, 20); + IDESwapBytePairs(InquiryData->VendorId, 20);
- for (i = 0; i < 4; i++) - { - InquiryData->ProductId[12+i] = ' '; - } + memcpy(&InquiryData->ProductId[12], " ", 4);
- for (i = 0; i < 4; i += 2) - { - InquiryData->ProductRevisionLevel[i] = - ((PUCHAR)DeviceParams->FirmwareRev)[i]; - InquiryData->ProductRevisionLevel[i+1] = - ((PUCHAR)DeviceParams->FirmwareRev)[i+1]; - } + memcpy(InquiryData->ProductRevisionLevel, DeviceParams->FirmwareRev, 4); + IDESwapBytePairs(InquiryData->ProductRevisionLevel, 4);
InquiryData->AdditionalLength = 31;