* Return true if intialization was successful
*/
BOOLEAN
+NTAPI
AhciPortInitialize (
- __in PAHCI_PORT_EXTENSION PortExtension
+ __in PVOID DeviceExtension
)
{
+ PAHCI_PORT_EXTENSION PortExtension;
AHCI_PORT_CMD cmd;
- ULONG mappedLength, portNumber;
PAHCI_MEMORY_REGISTERS abar;
+ ULONG mappedLength, portNumber, ticks;
PAHCI_ADAPTER_EXTENSION adapterExtension;
STOR_PHYSICAL_ADDRESS commandListPhysical, receivedFISPhysical;
AhciDebugPrint("AhciPortInitialize()\n");
+ PortExtension = (PAHCI_PORT_EXTENSION)DeviceExtension;
adapterExtension = PortExtension->AdapterExtension;
abar = adapterExtension->ABAR_Address;
portNumber = PortExtension->PortNumber;
cmd.Status = StorPortReadRegisterUlong(adapterExtension, &PortExtension->Port->CMD);
if ((cmd.FR != 0) || (cmd.CR != 0) || (cmd.FRE != 0) || (cmd.ST != 0))
{
- AhciDebugPrint("\tPort is not idle: %x\n", cmd);
+ cmd.ST = 0;
+ cmd.FRE = 0;
+
+ ticks = 3;
+ do
+ {
+ StorPortStallExecution(50000);
+ cmd.Status = StorPortReadRegisterUlong(adapterExtension, &PortExtension->Port->CMD);
+ if (ticks == 0)
+ {
+ AhciDebugPrint("\tAttempt to reset port failed: %x\n", cmd);
+ return FALSE;
+ }
+ ticks--;
+ }
+ while(cmd.CR != 0 || cmd.FR != 0);
}
// 10.1.2 For each implemented port, system software shall allocate memory for and program:
- // PxCLB and PxCLBU (if CAP.S64A is set to ‘1’)
- // PxFB and PxFBU (if CAP.S64A is set to ‘1’)
+ // ? PxCLB and PxCLBU (if CAP.S64A is set to ‘1’)
+ // ? PxFB and PxFBU (if CAP.S64A is set to ‘1’)
// Note: Assuming 32bit support only
StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->CLB, commandListPhysical.LowPart);
if (IsAdapterCAPS64(adapterExtension->CAP))
AhciDebugPrint("\tDET == %x Unsupported\n", ssts.DET);
return FALSE;
}
-
}// -- AhciStartPort();
/**
VOID
AhciCommandCompletionDpcRoutine (
__in PSTOR_DPC Dpc,
- __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
- __in PAHCI_PORT_EXTENSION PortExtension,
+ __in PVOID HwDeviceExtension,
+ __in PVOID SystemArgument1,
__in PVOID SystemArgument2
)
{
PAHCI_SRB_EXTENSION SrbExtension;
STOR_LOCK_HANDLE lockhandle = {0};
PAHCI_COMPLETION_ROUTINE CompletionRoutine;
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
+ PAHCI_PORT_EXTENSION PortExtension;
UNREFERENCED_PARAMETER(Dpc);
UNREFERENCED_PARAMETER(SystemArgument2);
AhciDebugPrint("AhciCommandCompletionDpcRoutine()\n");
+ AdapterExtension = (PAHCI_ADAPTER_EXTENSION)HwDeviceExtension;
+ PortExtension = (PAHCI_PORT_EXTENSION)SystemArgument1;
+
StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
Srb = RemoveQueue(&PortExtension->CompletionQueue);
StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
*/
BOOLEAN
AhciHwPassiveInitialize (
- __in PAHCI_ADAPTER_EXTENSION AdapterExtension
+ __in PVOID DeviceExtension
)
{
ULONG index;
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
PAHCI_PORT_EXTENSION PortExtension;
AhciDebugPrint("AhciHwPassiveInitialize()\n");
+ AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
+
for (index = 0; index < AdapterExtension->PortCount; index++)
{
if ((AdapterExtension->PortImplemented & (0x1 << index)) != 0)
* return TRUE if intialization was successful
*/
BOOLEAN
+NTAPI
AhciHwInitialize (
- __in PAHCI_ADAPTER_EXTENSION AdapterExtension
+ __in PVOID DeviceExtension
)
{
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
AHCI_GHC ghc;
AhciDebugPrint("AhciHwInitialize()\n");
+ AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
AdapterExtension->StateFlags.MessagePerPort = FALSE;
// First check what type of interrupt/synchronization device is using
* return FALSE Indicates the interrupt was not ours.
*/
BOOLEAN
+NTAPI
AhciHwInterrupt (
- __in PAHCI_ADAPTER_EXTENSION AdapterExtension
+ __in PVOID DeviceExtension
)
{
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
ULONG portPending, nextPort, i, portCount;
+ AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
+
if (AdapterExtension->StateFlags.Removed)
{
return FALSE;
* return FALSE if the request must be submitted later
*/
BOOLEAN
+NTAPI
AhciHwStartIo (
- __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
+ __in PVOID DeviceExtension,
__in PSCSI_REQUEST_BLOCK Srb
)
{
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
+
AhciDebugPrint("AhciHwStartIo()\n");
+ AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
+
if (!IsPortValid(AdapterExtension, Srb->PathId))
{
Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
case SCSIOP_TEST_UNIT_READY:
Srb->SrbStatus = DeviceRequestComplete(AdapterExtension, Srb, cdb);
break;
+ case SCSIOP_MODE_SENSE:
+ Srb->SrbStatus = DeviceRequestSense(AdapterExtension, Srb, cdb);
+ break;
case SCSIOP_READ:
- //case SCSIOP_WRITE:
+ case SCSIOP_WRITE:
Srb->SrbStatus = DeviceRequestReadWrite(AdapterExtension, Srb, cdb);
break;
default:
* return TRUE if bus was successfully reset
*/
BOOLEAN
+NTAPI
AhciHwResetBus (
__in PVOID AdapterExtension,
__in ULONG PathId
)
{
STOR_LOCK_HANDLE lockhandle = {0};
- PAHCI_ADAPTER_EXTENSION adapterExtension;
+// PAHCI_ADAPTER_EXTENSION adapterExtension;
AhciDebugPrint("AhciHwResetBus()\n");
- adapterExtension = AdapterExtension;
+// adapterExtension = AdapterExtension;
if (IsPortValid(AdapterExtension, PathId))
{
* @remarks Called by Storport.
*/
ULONG
+NTAPI
AhciHwFindAdapter (
- __in PVOID AdapterExtension,
+ __in PVOID DeviceExtension,
__in PVOID HwContext,
__in PVOID BusInformation,
- __in PVOID ArgumentString,
+ __in PCHAR ArgumentString,
__inout PPORT_CONFIGURATION_INFORMATION ConfigInfo,
__in PBOOLEAN Reserved3
)
UNREFERENCED_PARAMETER(ArgumentString);
UNREFERENCED_PARAMETER(Reserved3);
- adapterExtension = AdapterExtension;
+ adapterExtension = DeviceExtension;
adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
// The last PCI base address register (BAR[5], header offset 0x24) points to the AHCI base memory, it’s called ABAR (AHCI Base Memory Register).
adapterExtension->AhciBaseAddress = pciConfigData->u.type0.BaseAddresses[5] & (0xFFFFFFF0);
- AhciDebugPrint("\tVendorID:%d DeviceID:%d RevisionID:%d\n", adapterExtension->VendorID,
- adapterExtension->DeviceID,
- adapterExtension->RevisionID);
+ AhciDebugPrint("\tVendorID: %04x DeviceID: %04x RevisionID: %02x\n",
+ adapterExtension->VendorID,
+ adapterExtension->DeviceID,
+ adapterExtension->RevisionID);
// 2.1.11
abar = NULL;
* NT_STATUS in case of driver loaded successfully.
*/
ULONG
+NTAPI
DriverEntry (
__in PVOID DriverObject,
__in PVOID RegistryPath
__in PAHCI_SRB_EXTENSION SrbExtension
)
{
+ PAHCI_COMMAND_TABLE cmdTable;
UNREFERENCED_PARAMETER(PortExtension);
- UNREFERENCED_PARAMETER(SrbExtension);
AhciDebugPrint("AhciATAPI_CFIS()\n");
- return 2;
+ cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
+
+ NT_ASSERT(SrbExtension->CommandReg == IDE_COMMAND_ATAPI_PACKET);
+
+ AhciZeroMemory((PCHAR)cmdTable->CFIS, sizeof(cmdTable->CFIS));
+
+ cmdTable->CFIS[AHCI_ATA_CFIS_FisType] = FIS_TYPE_REG_H2D; // FIS Type
+ cmdTable->CFIS[AHCI_ATA_CFIS_PMPort_C] = (1 << 7); // PM Port & C
+ cmdTable->CFIS[AHCI_ATA_CFIS_CommandReg] = SrbExtension->CommandReg;
+
+ cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesLow] = SrbExtension->FeaturesLow;
+ cmdTable->CFIS[AHCI_ATA_CFIS_LBA0] = SrbExtension->LBA0;
+ cmdTable->CFIS[AHCI_ATA_CFIS_LBA1] = SrbExtension->LBA1;
+ cmdTable->CFIS[AHCI_ATA_CFIS_LBA2] = SrbExtension->LBA2;
+ cmdTable->CFIS[AHCI_ATA_CFIS_Device] = SrbExtension->Device;
+ cmdTable->CFIS[AHCI_ATA_CFIS_LBA3] = SrbExtension->LBA3;
+ cmdTable->CFIS[AHCI_ATA_CFIS_LBA4] = SrbExtension->LBA4;
+ cmdTable->CFIS[AHCI_ATA_CFIS_LBA5] = SrbExtension->LBA5;
+ cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesHigh] = SrbExtension->FeaturesHigh;
+ cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountLow] = SrbExtension->SectorCountLow;
+ cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountHigh] = SrbExtension->SectorCountHigh;
+
+ return 5;
}// -- AhciATAPI_CFIS();
/**
return;
}// -- AhciProcessIO();
+/**
+ * @name AtapiInquiryCompletion
+ * @implemented
+ *
+ * AtapiInquiryCompletion routine should be called after device signals
+ * for device inquiry request is completed (through interrupt) -- ATAPI Device only
+ *
+ * @param PortExtension
+ * @param Srb
+ *
+ */
+VOID
+AtapiInquiryCompletion (
+ __in PVOID _Extension,
+ __in PVOID _Srb
+ )
+{
+ PAHCI_PORT_EXTENSION PortExtension;
+ PAHCI_ADAPTER_EXTENSION AdapterExtension;
+ PSCSI_REQUEST_BLOCK Srb;
+ BOOLEAN status;
+
+ AhciDebugPrint("AtapiInquiryCompletion()\n");
+
+ PortExtension = (PAHCI_PORT_EXTENSION)_Extension;
+ Srb = (PSCSI_REQUEST_BLOCK)_Srb;
+
+ NT_ASSERT(Srb != NULL);
+ NT_ASSERT(PortExtension != NULL);
+
+ AdapterExtension = PortExtension->AdapterExtension;
+
+ // send queue depth
+ status = StorPortSetDeviceQueueDepth(PortExtension->AdapterExtension,
+ Srb->PathId,
+ Srb->TargetId,
+ Srb->Lun,
+ AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP));
+
+ NT_ASSERT(status == TRUE);
+ return;
+}// -- AtapiInquiryCompletion();
+
/**
* @name InquiryCompletion
- * @not_implemented
+ * @implemented
*
* InquiryCompletion routine should be called after device signals
* for device inquiry request is completed (through interrupt)
*/
VOID
InquiryCompletion (
- __in PAHCI_PORT_EXTENSION PortExtension,
- __in PSCSI_REQUEST_BLOCK Srb
+ __in PVOID _Extension,
+ __in PVOID _Srb
)
{
- PCDB cdb;
+ PAHCI_PORT_EXTENSION PortExtension;
+ PSCSI_REQUEST_BLOCK Srb;
+
+// PCDB cdb;
BOOLEAN status;
PINQUIRYDATA InquiryData;
PAHCI_SRB_EXTENSION SrbExtension;
AhciDebugPrint("InquiryCompletion()\n");
+ PortExtension = (PAHCI_PORT_EXTENSION)_Extension;
+ Srb = (PSCSI_REQUEST_BLOCK)_Srb;
+
NT_ASSERT(Srb != NULL);
NT_ASSERT(PortExtension != NULL);
- cdb = (PCDB)&Srb->Cdb;
+// cdb = (PCDB)&Srb->Cdb;
InquiryData = Srb->DataBuffer;
SrbExtension = GetSrbExtension(Srb);
AdapterExtension = PortExtension->AdapterExtension;
PortExtension->DeviceParams.BytesPerPhysicalSector = DEVICE_ATA_BLOCK_SIZE;
+ // last byte should be NULL
+ StorPortCopyMemory(PortExtension->DeviceParams.VendorId, IdentifyDeviceData->ModelNumber, sizeof(PortExtension->DeviceParams.VendorId) - 1);
+ StorPortCopyMemory(PortExtension->DeviceParams.RevisionID, IdentifyDeviceData->FirmwareRevision, sizeof(PortExtension->DeviceParams.RevisionID) - 1);
+ StorPortCopyMemory(PortExtension->DeviceParams.SerialNumber, IdentifyDeviceData->SerialNumber, sizeof(PortExtension->DeviceParams.SerialNumber) - 1);
+
+ PortExtension->DeviceParams.VendorId[sizeof(PortExtension->DeviceParams.VendorId) - 1] = '\0';
+ PortExtension->DeviceParams.RevisionID[sizeof(PortExtension->DeviceParams.RevisionID) - 1] = '\0';
+ PortExtension->DeviceParams.SerialNumber[sizeof(PortExtension->DeviceParams.SerialNumber) - 1] = '\0';
+
// TODO: Add other device params
AhciDebugPrint("\tATA Device\n");
}
if (Srb->DataTransferLength < INQUIRYDATABUFFERSIZE)
{
AhciDebugPrint("\tDataBufferLength < sizeof(INQUIRYDATA), Could crash the driver.\n");
+ NT_ASSERT(FALSE);
}
// update data transfer length
InquiryData->DeviceType = PortExtension->DeviceParams.AccessType;
InquiryData->RemovableMedia = PortExtension->DeviceParams.RemovableDevice;
- // TODO: Fill VendorID, Product Revision Level and other string fields
- InquiryData->VendorId[0] = '2';
- InquiryData->ProductId[0] = '3';
- InquiryData->ProductRevisionLevel[0] = '4';
+ // Fill VendorID, Product Revision Level and other string fields
+ StorPortCopyMemory(InquiryData->VendorId, PortExtension->DeviceParams.VendorId, sizeof(InquiryData->VendorId) - 1);
+ StorPortCopyMemory(InquiryData->ProductId, PortExtension->DeviceParams.RevisionID, sizeof(PortExtension->DeviceParams.RevisionID));
+ StorPortCopyMemory(InquiryData->ProductRevisionLevel, PortExtension->DeviceParams.SerialNumber, sizeof(InquiryData->ProductRevisionLevel) - 1);
+
+ InquiryData->VendorId[sizeof(InquiryData->VendorId) - 1] = '\0';
+ InquiryData->ProductId[sizeof(InquiryData->ProductId) - 1] = '\0';
+ InquiryData->ProductRevisionLevel[sizeof(InquiryData->ProductRevisionLevel) - 1] = '\0';
// send queue depth
status = StorPortSetDeviceQueueDepth(PortExtension->AdapterExtension,
return;
}// -- InquiryCompletion();
+ /**
+ * @name AhciATAPICommand
+ * @implemented
+ *
+ * Handles ATAPI Requests commands
+ *
+ * @param AdapterExtension
+ * @param Srb
+ * @param Cdb
+ *
+ * @return
+ * return STOR status for AhciATAPICommand
+ */
+UCHAR
+AhciATAPICommand (
+ __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
+ __in PSCSI_REQUEST_BLOCK Srb,
+ __in PCDB Cdb
+ )
+{
+ ULONG SrbFlags, DataBufferLength;
+ PAHCI_SRB_EXTENSION SrbExtension;
+ PAHCI_PORT_EXTENSION PortExtension;
+
+ AhciDebugPrint("AhciATAPICommand()\n");
+
+ SrbFlags = Srb->SrbFlags;
+ SrbExtension = GetSrbExtension(Srb);
+ DataBufferLength = Srb->DataTransferLength;
+ PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
+
+ NT_ASSERT(PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI);
+
+ NT_ASSERT(SrbExtension != NULL);
+
+ SrbExtension->AtaFunction = ATA_FUNCTION_ATAPI_COMMAND;
+ SrbExtension->Flags = 0;
+
+ if (SrbFlags & SRB_FLAGS_DATA_IN)
+ {
+ SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
+ }
+
+ if (SrbFlags & SRB_FLAGS_DATA_OUT)
+ {
+ SrbExtension->Flags |= ATA_FLAGS_DATA_OUT;
+ }
+
+ SrbExtension->FeaturesLow = 0;
+
+ SrbExtension->CompletionRoutine = NULL;
+
+ NT_ASSERT(Cdb != NULL);
+ switch(Cdb->CDB10.OperationCode)
+ {
+ case SCSIOP_INQUIRY:
+ SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
+ SrbExtension->CompletionRoutine = AtapiInquiryCompletion;
+ break;
+ case SCSIOP_READ:
+ SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
+ SrbExtension->FeaturesLow = 0x5;
+ break;
+ case SCSIOP_WRITE:
+ SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
+ SrbExtension->FeaturesLow = 0x1;
+ break;
+ }
+
+ SrbExtension->CommandReg = IDE_COMMAND_ATAPI_PACKET;
+
+ SrbExtension->LBA0 = 0;
+ SrbExtension->LBA1 = (UCHAR)(DataBufferLength >> 0);
+ SrbExtension->LBA2 = (UCHAR)(DataBufferLength >> 8);
+ SrbExtension->Device = 0;
+ SrbExtension->LBA3 = 0;
+ SrbExtension->LBA4 = 0;
+ SrbExtension->LBA5 = 0;
+ SrbExtension->FeaturesHigh = 0;
+ SrbExtension->SectorCountLow = 0;
+ SrbExtension->SectorCountHigh = 0;
+
+ if ((SrbExtension->Flags & ATA_FLAGS_DATA_IN) || (SrbExtension->Flags & ATA_FLAGS_DATA_OUT))
+ {
+ SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb);
+ }
+
+ return SRB_STATUS_PENDING;
+}// -- AhciATAPICommand();
+
+/**
+ * @name DeviceRequestSense
+ * @implemented
+ *
+ * Handle SCSIOP_MODE_SENSE OperationCode
+ *
+ * @param AdapterExtension
+ * @param Srb
+ * @param Cdb
+ *
+ * @return
+ * return STOR status for DeviceRequestSense
+ */
+UCHAR
+DeviceRequestSense (
+ __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
+ __in PSCSI_REQUEST_BLOCK Srb,
+ __in PCDB Cdb
+ )
+{
+ PMODE_PARAMETER_HEADER ModeHeader;
+ PAHCI_PORT_EXTENSION PortExtension;
+
+ AhciDebugPrint("DeviceRequestSense()\n");
+
+ NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
+ NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_MODE_SENSE);
+
+ PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
+
+ if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
+ {
+ return AhciATAPICommand(AdapterExtension, Srb, Cdb);
+ }
+
+ ModeHeader = (PMODE_PARAMETER_HEADER)Srb->DataBuffer;
+
+ NT_ASSERT(ModeHeader != NULL);
+
+ AhciZeroMemory((PCHAR)ModeHeader, Srb->DataTransferLength);
+
+ ModeHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER);
+ ModeHeader->MediumType = 0;
+ ModeHeader->DeviceSpecificParameter = 0;
+ ModeHeader->BlockDescriptorLength = 0;
+
+ if (Cdb->MODE_SENSE.PageCode == MODE_SENSE_CURRENT_VALUES)
+ {
+ ModeHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_PARAMETER_BLOCK);
+ ModeHeader->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK);
+ }
+
+ return SRB_STATUS_SUCCESS;
+}// -- DeviceRequestSense();
+
/**
* @name DeviceRequestReadWrite
* @implemented
* @param Cdb
*
* @return
- * return STOR status for DeviceReportLuns
+ * return STOR status for DeviceRequestReadWrite
*/
-UCHAR DeviceRequestReadWrite (
+UCHAR
+DeviceRequestReadWrite (
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
__in PSCSI_REQUEST_BLOCK Srb,
__in PCDB Cdb
SrbExtension = GetSrbExtension(Srb);
PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
+ if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
+ {
+ return AhciATAPICommand(AdapterExtension, Srb, Cdb);
+ }
+
DataTransferLength = Srb->DataTransferLength;
BytesPerSector = PortExtension->DeviceParams.BytesPerLogicalSector;
NT_ASSERT(BytesPerSector > 0);
- ROUND_UP(DataTransferLength, BytesPerSector);
+ //ROUND_UP(DataTransferLength, BytesPerSector);
SectorCount = DataTransferLength / BytesPerSector;
+
+ Srb->DataTransferLength = SectorCount * BytesPerSector;
+
StartOffset = AhciGetLba(Cdb, Srb->CdbLength);
IsReading = (Cdb->CDB10.OperationCode == SCSIOP_READ);
else
{
SrbExtension->Flags |= ATA_FLAGS_DATA_OUT;
- NT_ASSERT(FALSE);
+ SrbExtension->CommandReg = IDE_COMMAND_WRITE_DMA;
}
SrbExtension->FeaturesLow = 0;
if (PortExtension->DeviceParams.Lba48BitMode)
{
SrbExtension->Flags |= ATA_FLAGS_48BIT_COMMAND;
- SrbExtension->CommandReg = IDE_COMMAND_READ_DMA_EXT;
+
+ if (IsReading)
+ {
+ SrbExtension->CommandReg = IDE_COMMAND_READ_DMA_EXT;
+ }
+ else
+ {
+ SrbExtension->CommandReg = IDE_COMMAND_WRITE_DMA_EXT;
+ }
SrbExtension->LBA3 = (StartOffset >> 24) & 0xFF;
SrbExtension->LBA4 = (StartOffset >> 32) & 0xFF;
* @param Cdb
*
* @return
- * return STOR status for DeviceReportLuns
+ * return STOR status for DeviceRequestCapacity
*/
-UCHAR DeviceRequestCapacity (
+UCHAR
+DeviceRequestCapacity (
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
__in PSCSI_REQUEST_BLOCK Srb,
__in PCDB Cdb
NT_ASSERT(Srb->DataBuffer != NULL);
NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
+
PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
+ if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
+ {
+ return AhciATAPICommand(AdapterExtension, Srb, Cdb);
+ }
+
if (Cdb->CDB10.OperationCode == SCSIOP_READ_CAPACITY)
{
ReadCapacity = (PREAD_CAPACITY_DATA)Srb->DataBuffer;
-
BytesPerLogicalSector = PortExtension->DeviceParams.BytesPerLogicalSector;
- MaxLba = (ULONG)PortExtension->DeviceParams.MaxLba.QuadPart;
+ MaxLba = (ULONG)PortExtension->DeviceParams.MaxLba.QuadPart - 1;
// I trust you windows :D
NT_ASSERT(Srb->DataTransferLength >= sizeof(READ_CAPACITY_DATA));
* @return
* return STOR status for DeviceRequestComplete
*/
-UCHAR DeviceRequestComplete (
+UCHAR
+DeviceRequestComplete (
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
__in PSCSI_REQUEST_BLOCK Srb,
__in PCDB Cdb
* @return
* return STOR status for DeviceReportLuns
*/
-UCHAR DeviceReportLuns (
+UCHAR
+DeviceReportLuns (
__in PAHCI_ADAPTER_EXTENSION AdapterExtension,
__in PSCSI_REQUEST_BLOCK Srb,
__in PCDB Cdb
)
{
PLUN_LIST LunList;
+ PAHCI_PORT_EXTENSION PortExtension;
AhciDebugPrint("DeviceReportLuns()\n");
- UNREFERENCED_PARAMETER(AdapterExtension);
UNREFERENCED_PARAMETER(Cdb);
+ PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
+
NT_ASSERT(Srb->DataTransferLength >= sizeof(LUN_LIST));
NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_REPORT_LUNS);
+ if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
+ {
+ return AhciATAPICommand(AdapterExtension, Srb, Cdb);
+ }
+
LunList = (PLUN_LIST)Srb->DataBuffer;
NT_ASSERT(LunList != NULL);
SrbExtension = GetSrbExtension(Srb);
PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
+ if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
+ {
+ return AhciATAPICommand(AdapterExtension, Srb, Cdb);
+ }
+
if (Srb->Lun != 0)
{
return SRB_STATUS_SELECTION_TIMEOUT;