* 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);
NT_ASSERT(Srb != NULL);
{
Srb->SrbStatus = SRB_STATUS_SUCCESS;
}
+ else
+ {
+ return;
+ }
SrbExtension = GetSrbExtension(Srb);
+
CompletionRoutine = SrbExtension->CompletionRoutine;
+ NT_ASSERT(CompletionRoutine != NULL);
- if (CompletionRoutine != NULL)
- {
- // now it's completion routine responsibility to set SrbStatus
- CompletionRoutine(PortExtension, Srb);
- }
- else
- {
- Srb->SrbStatus = SRB_STATUS_SUCCESS;
- //StorPortNotification(RequestComplete, AdapterExtension, Srb);
- }
+ // now it's completion routine responsibility to set SrbStatus
+ CompletionRoutine(PortExtension, Srb);
+
+ StorPortNotification(RequestComplete, AdapterExtension, Srb);
- StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
return;
}// -- AhciCommandCompletionDpcRoutine();
*/
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
{
ULONG NCS, i;
PSCSI_REQUEST_BLOCK Srb;
+ PAHCI_SRB_EXTENSION SrbExtension;
PAHCI_ADAPTER_EXTENSION AdapterExtension;
AhciDebugPrint("AhciCompleteIssuedSrb()\n");
if (((1 << i) & CommandsToComplete) != 0)
{
Srb = PortExtension->Slot[i];
- NT_ASSERT(Srb != NULL);
- AddQueue(&PortExtension->CompletionQueue, Srb);
- StorPortIssueDpc(AdapterExtension, &PortExtension->CommandCompletion, PortExtension, Srb);
+ if (Srb == NULL)
+ {
+ continue;
+ }
+
+ SrbExtension = GetSrbExtension(Srb);
+ NT_ASSERT(SrbExtension != NULL);
+
+ if (SrbExtension->CompletionRoutine != NULL)
+ {
+ AddQueue(&PortExtension->CompletionQueue, Srb);
+ StorPortIssueDpc(AdapterExtension, &PortExtension->CommandCompletion, PortExtension, Srb);
+ }
+ else
+ {
+ NT_ASSERT(Srb->SrbStatus == SRB_STATUS_PENDING);
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ StorPortNotification(RequestComplete, AdapterExtension, Srb);
+ }
}
}
* 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;
return TRUE;
}
- AhciDebugPrint("\tPathId: %d Function: %x\n", Srb->PathId, Srb->Function);
switch(Srb->Function)
{
case SRB_FUNCTION_PNP:
Srb->SrbStatus = DeviceReportLuns(AdapterExtension, Srb, cdb);
break;
case SCSIOP_READ_CAPACITY:
- case SCSIOP_READ_CAPACITY16:
Srb->SrbStatus = DeviceRequestCapacity(AdapterExtension, Srb, cdb);
break;
+ 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:
AhciDebugPrint("\tOperationCode: %d\n", cdb->CDB10.OperationCode);
- Srb->SrbStatus = SRB_STATUS_BAD_FUNCTION;
+ Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
break;
}
}
break;
}
- StorPortNotification(RequestComplete, AdapterExtension, Srb);
+ if (Srb->SrbStatus != SRB_STATUS_PENDING)
+ {
+ StorPortNotification(RequestComplete, AdapterExtension, Srb);
+ }
+ else
+ {
+ AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
+ }
return TRUE;
}// -- AhciHwStartIo();
* 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;
ConfigInfo->NumberOfPhysicalBreaks = 0x21;
ConfigInfo->MaximumNumberOfLogicalUnits = 1;
ConfigInfo->NumberOfBuses = MAXIMUM_AHCI_PORT_COUNT;
- ConfigInfo->MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
ConfigInfo->MaximumTransferLength = MAXIMUM_TRANSFER_LENGTH;
ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
* 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();
/**
* @param PortExtension
*
*/
+
+#ifdef _MSC_VER // avoid MSVC C4700
+ #pragma warning(push)
+ #pragma warning(disable: 4700)
+#endif
+
VOID
AhciActivatePort (
__in PAHCI_PORT_EXTENSION PortExtension
)
{
AHCI_PORT_CMD cmd;
- ULONG sact, ci;
ULONG QueueSlots, slotToActivate, tmp;
PAHCI_ADAPTER_EXTENSION AdapterExtension;
return;
}
- sact = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SACT);
- ci = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CI);
-
// get the lowest set bit
tmp = QueueSlots & (QueueSlots - 1);
return;
}// -- AhciActivatePort();
+#ifdef _MSC_VER // avoid MSVC C4700
+ #pragma warning(pop)
+#endif
+
/**
* @name AhciProcessIO
* @implemented
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.RemovableDevice = 1;
}
- if (IdentifyDeviceData->CommandSetSupport.BigLba && IdentifyDeviceData->CommandSetActive.BigLba)
+ if ((IdentifyDeviceData->CommandSetSupport.BigLba) && (IdentifyDeviceData->CommandSetActive.BigLba))
{
PortExtension->DeviceParams.Lba48BitMode = 1;
}
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
)
{
- ULONG64 SectorNo;
BOOLEAN IsReading;
+ ULONG64 StartOffset;
PAHCI_SRB_EXTENSION SrbExtension;
PAHCI_PORT_EXTENSION PortExtension;
ULONG DataTransferLength, BytesPerSector, SectorCount;
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;
- ROUND_UP(DataTransferLength, BytesPerSector);
+ NT_ASSERT(BytesPerSector > 0);
+
+ //ROUND_UP(DataTransferLength, BytesPerSector);
SectorCount = DataTransferLength / BytesPerSector;
- SectorNo = AhciGetLba(Cdb);
+
+ Srb->DataTransferLength = SectorCount * BytesPerSector;
+
+ StartOffset = AhciGetLba(Cdb, Srb->CdbLength);
IsReading = (Cdb->CDB10.OperationCode == SCSIOP_READ);
NT_ASSERT(SectorCount > 0);
SrbExtension->AtaFunction = ATA_FUNCTION_ATA_READ;
- SrbExtension->Flags = ATA_FLAGS_USE_DMA;
+ SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
SrbExtension->CompletionRoutine = NULL;
if (IsReading)
else
{
SrbExtension->Flags |= ATA_FLAGS_DATA_OUT;
- NT_ASSERT(FALSE);
+ SrbExtension->CommandReg = IDE_COMMAND_WRITE_DMA;
}
SrbExtension->FeaturesLow = 0;
- SrbExtension->LBA0 = (SectorNo >> 0) & 0xFF;
- SrbExtension->LBA1 = (SectorNo >> 8) & 0xFF;
- SrbExtension->LBA2 = (SectorNo >> 16) & 0xFF;
+ SrbExtension->LBA0 = (StartOffset >> 0) & 0xFF;
+ SrbExtension->LBA1 = (StartOffset >> 8) & 0xFF;
+ SrbExtension->LBA2 = (StartOffset >> 16) & 0xFF;
SrbExtension->Device = (0xA0 | IDE_LBA_MODE);
if (PortExtension->DeviceParams.Lba48BitMode)
{
SrbExtension->Flags |= ATA_FLAGS_48BIT_COMMAND;
- SrbExtension->CommandReg = IDE_COMMAND_READ_DMA_EXT;
- SrbExtension->LBA3 = (SectorNo >> 24) & 0xFF;
- SrbExtension->LBA4 = (SectorNo >> 32) & 0xFF;
- SrbExtension->LBA5 = (SectorNo >> 40) & 0xFF;
+ 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;
+ SrbExtension->LBA5 = (StartOffset >> 40) & 0xFF;
}
else
{
SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb);
- AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
return SRB_STATUS_PENDING;
}// -- DeviceRequestReadWrite();
* @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 SRB_STATUS_SUCCESS;
}// -- DeviceRequestCapacity();
+/**
+ * @name DeviceRequestComplete
+ * @implemented
+ *
+ * Handle UnHandled Requests
+ *
+ * @param AdapterExtension
+ * @param Srb
+ * @param Cdb
+ *
+ * @return
+ * return STOR status for DeviceRequestComplete
+ */
+UCHAR
+DeviceRequestComplete (
+ __in PAHCI_ADAPTER_EXTENSION AdapterExtension,
+ __in PSCSI_REQUEST_BLOCK Srb,
+ __in PCDB Cdb
+ )
+{
+ AhciDebugPrint("DeviceRequestComplete()\n");
+
+ UNREFERENCED_PARAMETER(AdapterExtension);
+ UNREFERENCED_PARAMETER(Cdb);
+
+ Srb->ScsiStatus = SCSISTAT_GOOD;
+
+ return SRB_STATUS_SUCCESS;
+}// -- DeviceRequestComplete();
+
/**
* @name DeviceReportLuns
* @implemented
* @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;
SrbExtension->Sgl.List[0].Length = sizeof(IDENTIFY_DEVICE_DATA);
SrbExtension->pSgl = &SrbExtension->Sgl;
-
- AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
return SRB_STATUS_PENDING;
}
else
return (PAHCI_SRB_EXTENSION)(SrbExtension + Offset);
}// -- PAHCI_SRB_EXTENSION();
-
+/**
+ * @name AhciGetLba
+ * @implemented
+ *
+ * Find the logical address of demand block from Cdb
+ *
+ * @param Srb
+ *
+ * @return
+ * return Logical Address of the block
+ *
+ */
__inline
ULONG64
AhciGetLba (
- __in PCDB Cdb
+ __in PCDB Cdb,
+ __in ULONG CdbLength
)
{
ULONG64 lba = 0;
NT_ASSERT(Cdb != NULL);
+ NT_ASSERT(CdbLength != 0);
- lba |= Cdb->CDB10.LogicalBlockByte3 << 0;
- lba |= Cdb->CDB10.LogicalBlockByte2 << 8;
- lba |= Cdb->CDB10.LogicalBlockByte1 << 16;
- lba |= Cdb->CDB10.LogicalBlockByte0 << 24;
+ if (CdbLength == 0x10)
+ {
+ REVERSE_BYTES_QUAD(&lba, Cdb->CDB16.LogicalBlock);
+ }
+ else
+ {
+ lba |= Cdb->CDB10.LogicalBlockByte3 << 0;
+ lba |= Cdb->CDB10.LogicalBlockByte2 << 8;
+ lba |= Cdb->CDB10.LogicalBlockByte1 << 16;
+ lba |= Cdb->CDB10.LogicalBlockByte0 << 24;
+ }
return lba;
}// -- AhciGetLba();
\ No newline at end of file