[USBOHCI_NEW][USBUHCI_NEW] Avoid unnecessary/incorrect status defines.
[reactos.git] / drivers / storage / storahci / storahci.c
index 7b76d78..c674b2b 100644 (file)
  * 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;
@@ -76,12 +79,27 @@ AhciPortInitialize (
     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))
@@ -386,7 +404,6 @@ AhciStartPort (
             AhciDebugPrint("\tDET == %x Unsupported\n", ssts.DET);
             return FALSE;
     }
-
 }// -- AhciStartPort();
 
 /**
@@ -403,8 +420,8 @@ 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
   )
 {
@@ -412,14 +429,20 @@ AhciCommandCompletionDpcRoutine (
     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);
 
@@ -427,22 +450,21 @@ AhciCommandCompletionDpcRoutine (
     {
         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();
 
@@ -459,14 +481,17 @@ 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)
@@ -492,14 +517,17 @@ AhciHwPassiveInitialize (
  * 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
@@ -537,6 +565,7 @@ AhciCompleteIssuedSrb (
 {
     ULONG NCS, i;
     PSCSI_REQUEST_BLOCK Srb;
+    PAHCI_SRB_EXTENSION SrbExtension;
     PAHCI_ADAPTER_EXTENSION AdapterExtension;
 
     AhciDebugPrint("AhciCompleteIssuedSrb()\n");
@@ -553,10 +582,26 @@ AhciCompleteIssuedSrb (
         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);
+            }
         }
     }
 
@@ -670,12 +715,16 @@ AhciInterruptHandler (
  * 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;
@@ -734,13 +783,18 @@ AhciHwInterrupt (
  * 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;
@@ -748,7 +802,6 @@ AhciHwStartIo (
         return TRUE;
     }
 
-    AhciDebugPrint("\tPathId: %d Function: %x\n", Srb->PathId, Srb->Function);
     switch(Srb->Function)
     {
         case SRB_FUNCTION_PNP:
@@ -824,16 +877,21 @@ AhciHwStartIo (
                         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;
                 }
             }
@@ -844,7 +902,14 @@ AhciHwStartIo (
             break;
     }
 
-    StorPortNotification(RequestComplete, AdapterExtension, Srb);
+    if (Srb->SrbStatus != SRB_STATUS_PENDING)
+    {
+        StorPortNotification(RequestComplete, AdapterExtension, Srb);
+    }
+    else
+    {
+        AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
+    }
     return TRUE;
 }// -- AhciHwStartIo();
 
@@ -861,17 +926,18 @@ 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))
     {
@@ -920,11 +986,12 @@ AhciHwResetBus (
  * @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
     )
@@ -945,7 +1012,7 @@ AhciHwFindAdapter (
     UNREFERENCED_PARAMETER(ArgumentString);
     UNREFERENCED_PARAMETER(Reserved3);
 
-    adapterExtension = AdapterExtension;
+    adapterExtension = DeviceExtension;
     adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
     adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
 
@@ -971,9 +1038,10 @@ AhciHwFindAdapter (
     // 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;
@@ -1054,7 +1122,6 @@ AhciHwFindAdapter (
     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;
 
@@ -1092,6 +1159,7 @@ AhciHwFindAdapter (
  * NT_STATUS in case of driver loaded successfully.
  */
 ULONG
+NTAPI
 DriverEntry (
     __in PVOID DriverObject,
     __in PVOID RegistryPath
@@ -1200,12 +1268,34 @@ AhciATAPI_CFIS (
     __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();
 
 /**
@@ -1390,13 +1480,18 @@ AhciProcessSrb (
  * @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;
 
@@ -1419,9 +1514,6 @@ AhciActivatePort (
         return;
     }
 
-    sact = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SACT);
-    ci = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CI);
-
     // get the lowest set bit
     tmp = QueueSlots & (QueueSlots - 1);
 
@@ -1443,6 +1535,10 @@ AhciActivatePort (
     return;
 }// -- AhciActivatePort();
 
+#ifdef _MSC_VER     // avoid MSVC C4700
+    #pragma warning(pop)
+#endif
+
 /**
  * @name AhciProcessIO
  * @implemented
@@ -1527,9 +1623,52 @@ AhciProcessIO (
     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)
@@ -1540,11 +1679,14 @@ AhciProcessIO (
  */
 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;
@@ -1553,10 +1695,13 @@ InquiryCompletion (
 
     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;
@@ -1585,7 +1730,7 @@ InquiryCompletion (
             PortExtension->DeviceParams.RemovableDevice = 1;
         }
 
-        if (IdentifyDeviceData->CommandSetSupport.BigLba && IdentifyDeviceData->CommandSetActive.BigLba)
+        if ((IdentifyDeviceData->CommandSetSupport.BigLba) && (IdentifyDeviceData->CommandSetActive.BigLba))
         {
             PortExtension->DeviceParams.Lba48BitMode = 1;
         }
@@ -1621,6 +1766,15 @@ InquiryCompletion (
 
         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");
     }
@@ -1635,6 +1789,7 @@ InquiryCompletion (
     if (Srb->DataTransferLength < INQUIRYDATABUFFERSIZE)
     {
         AhciDebugPrint("\tDataBufferLength < sizeof(INQUIRYDATA), Could crash the driver.\n");
+        NT_ASSERT(FALSE);
     }
 
     // update data transfer length
@@ -1651,10 +1806,14 @@ InquiryCompletion (
     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,
@@ -1667,6 +1826,151 @@ InquiryCompletion (
     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
@@ -1678,16 +1982,17 @@ InquiryCompletion (
  * @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;
@@ -1700,19 +2005,29 @@ UCHAR DeviceRequestReadWrite (
     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)
@@ -1723,24 +2038,32 @@ UCHAR DeviceRequestReadWrite (
     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
     {
@@ -1755,7 +2078,6 @@ UCHAR DeviceRequestReadWrite (
 
     SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb);
 
-    AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
     return SRB_STATUS_PENDING;
 }// -- DeviceRequestReadWrite();
 
@@ -1770,9 +2092,10 @@ UCHAR 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
@@ -1790,15 +2113,20 @@ UCHAR DeviceRequestCapacity (
     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));
@@ -1821,6 +2149,36 @@ UCHAR DeviceRequestCapacity (
     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
@@ -1834,22 +2192,30 @@ UCHAR DeviceRequestCapacity (
  * @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);
@@ -1901,6 +2267,11 @@ DeviceInquiryRequest (
     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;
@@ -1936,8 +2307,6 @@ DeviceInquiryRequest (
         SrbExtension->Sgl.List[0].Length = sizeof(IDENTIFY_DEVICE_DATA);
 
         SrbExtension->pSgl = &SrbExtension->Sgl;
-
-        AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
         return SRB_STATUS_PENDING;
     }
     else
@@ -2209,21 +2578,41 @@ GetSrbExtension (
     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