[UNIATA] Sync to 0.45h1. CORE-10185
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 14 Sep 2015 10:24:48 +0000 (10:24 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 14 Sep 2015 10:24:48 +0000 (10:24 +0000)
svn path=/trunk/; revision=69224

reactos/drivers/storage/ide/uniata/atapi.h
reactos/drivers/storage/ide/uniata/bm_devs.h
reactos/drivers/storage/ide/uniata/id_ata.cpp
reactos/drivers/storage/ide/uniata/id_dma.cpp
reactos/drivers/storage/ide/uniata/id_init.cpp
reactos/drivers/storage/ide/uniata/id_probe.cpp
reactos/drivers/storage/ide/uniata/id_sata.cpp
reactos/drivers/storage/ide/uniata/uniata_ver.h

index 54adb5b..cab5617 100644 (file)
@@ -437,6 +437,7 @@ typedef struct _MODE_PARAMETER_HEADER_10 {
 #define IDE_DRIVE_2                  0x10
 #define IDE_DRIVE_SELECT_1           (IDE_DRIVE_SELECT | IDE_DRIVE_1)
 #define IDE_DRIVE_SELECT_2           (IDE_DRIVE_SELECT | IDE_DRIVE_2)
+#define IDE_DRIVE_MASK               (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)
 
 #define IDE_USE_LBA                  0x40
 
index 6f9563b..2ff79d9 100644 (file)
@@ -696,6 +696,11 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define VIAPRQ         0x8000
 #define VIASATA         0x10000
 
+#define CYRIX_OLD       0
+#define CYRIX_3x        1
+#define CYRIX_NEW       2
+#define CYRIX_35        3
+
 #define ITE_33          0
 #define ITE_133         1
 #define ITE_133_NEW     2
@@ -734,6 +739,7 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
     PCI_DEV_HW_SPEC_BM( 7411, 1022, 0x00, ATA_UDMA5, "AMD 766"          , 0 | AMDBUG                      ),
     PCI_DEV_HW_SPEC_BM( 7441, 1022, 0x00, ATA_UDMA5, "AMD 768"          , 0                               ),
     PCI_DEV_HW_SPEC_BM( 7469, 1022, 0x00, ATA_UDMA6, "AMD 8111"         , 0                               ),
+    PCI_DEV_HW_SPEC_BM( 208F, 1022, 0x00, ATA_UDMA4, "AMD CS5535"       , CYRIX_35                        ),
     PCI_DEV_HW_SPEC_BM( 209a, 1022, 0x00, ATA_UDMA5, "AMD CS5536"       , 0                               ),
 
     PCI_DEV_HW_SPEC_BM( 4349, 1002, 0x00, ATA_UDMA5, "ATI IXP200"       , 0                                       ),
@@ -1041,6 +1047,7 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
     PCI_DEV_HW_SPEC_BM( 0d8f, 10de, 0x00, ATA_SA300, "nVidia nForce MCP89 AB", UNIATA_SATA | UNIATA_AHCI  ),
 
     PCI_DEV_HW_SPEC_BM( 0502, 100b, 0x00, ATA_UDMA2, "National Geode SC1100", 0                                   ),
+    PCI_DEV_HW_SPEC_BM( 002d, 100b, 0x00, ATA_UDMA4, "National Geode CS5535", CYRIX_35                            ),
 
     PCI_DEV_HW_SPEC_BM( 4d33, 105a, 0x00, ATA_UDMA2, "Promise PDC20246" , PROLD | 0x00                            ),
     PCI_DEV_HW_SPEC_BM( 4d38, 105a, 0x00, ATA_UDMA4, "Promise PDC20262" , PRNEW | 0x00                            ),
@@ -1204,7 +1211,9 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
 */
     PCI_DEV_HW_SPEC_BM( 0001, 16ca, 0x00, ATA_WDMA2, "Cenatek Rocket Drive",0                                     ),
 
-    PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530"       , 0                                       ),
+    PCI_DEV_HW_SPEC_BM( 0000, 1078, 0x00, ATA_WDMA2, "Cyrix 5510"       , CYRIX_OLD                               ),
+    PCI_DEV_HW_SPEC_BM( 0002, 1078, 0x00, ATA_WDMA2, "Cyrix 5520"       , CYRIX_OLD                               ),
+    PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530"       , CYRIX_3x                                ),
 
     PCI_DEV_HW_SPEC_BM( 1000, 1042, 0x00, ATA_PIO4,  "RZ 100x"          , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 1001, 1042, 0x00, ATA_PIO4,  "RZ 100x"          , 0                                       ),
index 83f41ea..64f111c 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2014 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_ata.cpp
@@ -498,6 +498,7 @@ AtapiSuckPort2(
         if (statusByte & IDE_STATUS_DRQ) {
             // Suck out any remaining bytes and throw away.
             AtapiReadPort2(chan, IDX_IO1_i_Data);
+            UniataNanoSleep(PIO0_TIMING);
         } else {
             break;
         }
@@ -508,6 +509,50 @@ AtapiSuckPort2(
     return statusByte;
 } // AtapiSuckPort2()
 
+ULONG
+DDKFASTAPI
+AtapiSuckPortBuffer2(
+    IN PHW_CHANNEL chan,
+    IN PUSHORT Buffer,
+    IN ULONG Count
+    )
+{
+    UCHAR statusByte;
+    ULONG i;
+    USHORT data;
+    BOOLEAN retry = FALSE;
+
+    // Assume, proper drive is already seleted
+    WaitOnBusyLong(chan);
+    for (i = 0; i < Count; i++) {
+
+        GetStatus(chan, statusByte);
+        if (statusByte & IDE_STATUS_DRQ) {
+            // Suck out any remaining bytes and throw away.
+            data = AtapiReadPort2(chan, IDX_IO1_i_Data);
+            (*Buffer) = data;
+            Count--;
+            Buffer++;
+            UniataNanoSleep(PIO0_TIMING);
+            retry = FALSE;
+        } else {
+            if(i<Count && !retry) {
+                KdPrint2((PRINT_PREFIX "  wait...\n"));
+                WaitForDrq(chan);
+                retry = TRUE;
+            }
+            break;
+        }
+    }
+    if(i) {
+        KdPrint2((PRINT_PREFIX "AtapiSuckPortBuffer2: %#x words\n", i ));
+        if(i==Count) {
+            AtapiSuckPort2(chan);
+        }
+    }
+    return i;
+} // AtapiSuckPortBuffer2()
+
 UCHAR
 DDKFASTAPI
 WaitOnBusy(
@@ -1253,7 +1298,7 @@ AtapiQueueTimerDpc(
 
 #endif //UNIATA_CORE
 
-#if DBG
+#ifdef _DEBUG
 VOID
 NTAPI
 UniataDumpATARegs(
@@ -1383,7 +1428,7 @@ IssueIdentify(
 
     if(use_ahci) {
         statusByte = WaitOnBusyLong(chan);
-#if DBG
+#ifdef _DEBUG
         if(!chan->AhciInternalAtaReq) {
             KdPrint2((PRINT_PREFIX "!AhciInternalAtaReq\n"));
         }
@@ -1594,11 +1639,24 @@ IssueIdentify(
         if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
 
             KdPrint2((PRINT_PREFIX "  use 16bit IO\n"));
+#ifdef _DEBUG
+            if(atapiDev) {
+              j = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
+              KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j));
 
+              j =
+                  AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow);
+
+              j |=
+                  (USHORT)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8;
+              KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j));
+
+            }
+#endif //DBG
             // ATI/SII chipsets with memory-mapped IO hangs when
             // I call ReadBuffer(), probably due to PCI burst/prefetch enabled
             // Unfortunately, I don't know yet how to workaround it except
-            // spacifying manual delay in the way you see below.
+            // specifying manual delay in the way you see below.
             ReadBuffer(chan, (PUSHORT)&deviceExtension->FullIdentifyData, 256, PIO0_TIMING);
 
             // Work around for some IDE and one model Atapi that will present more than
@@ -2003,10 +2061,12 @@ skip_lba_staff:
             LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_CD;
             LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_CD;
             statusByte = WaitForDrq(chan);
+
         } else {
             KdPrint2((PRINT_PREFIX "IssueIdentify: ATAPI drive type %#x.\n",
                 LunExt->IdentifyData.DeviceType));
         }
+        KdPrint2((PRINT_PREFIX "IssueIdentify: AtapiCmdSize %#x\n", deviceExtension->FullIdentifyData.AtapiCmdSize));
     } else {
         KdPrint2((PRINT_PREFIX "IssueIdentify: hard drive.\n"));
     }
@@ -2142,7 +2202,7 @@ AtapiResetController__(
     //ULONG RevID    =  deviceExtension->RevID;
     ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
     //UCHAR tmp8;
-    UCHAR tmp16;
+    USHORT tmp16;
 
     KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber));
     KdPrint2((PRINT_PREFIX "simplexOnly %d\n", deviceExtension->simplexOnly));
@@ -2171,6 +2231,19 @@ AtapiResetController__(
                 PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension);
 
                 KdPrint2((PRINT_PREFIX "AtapiResetController: pending SRB %#x, chan %#x\n", CurSrb, chan));
+                if(CurSrb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
+                    PHW_LU_EXTENSION     LunExt;
+                    KdPrint2((PRINT_PREFIX "  was MechStatus\n"));
+
+                    i = GET_CDEV(CurSrb);
+                    KdPrint2((PRINT_PREFIX "  Lun %x\n", i));
+                    LunExt = chan->lun[i];
+
+                    if(!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)) {
+                        LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED;
+                        KdPrint2((PRINT_PREFIX "  set DFLAGS_CHANGER_INITED\n"));
+                    }
+                }
                 // Check and see if we are processing an internal srb
                 if (AtaReq->OriginalSrb) {
                     KdPrint2((PRINT_PREFIX "  restore original SRB %#x\n", AtaReq->OriginalSrb));
@@ -2324,9 +2397,40 @@ AtapiResetController__(
                 break; }
             case ATA_SIS_ID:
             case ATA_NVIDIA_ID: {
+                ULONG offs;
+                ULONG Channel = deviceExtension->Channel + j;
                 KdPrint2((PRINT_PREFIX "  SIS/nVidia\n"));
-                if(!(ChipFlags & UNIATA_SATA))
+                if(!(ChipFlags & UNIATA_SATA)) {
                     goto default_reset;
+                }
+                offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
+
+                KdPrint2((PRINT_PREFIX "  disable Phy intr, offs %#x, c %u\n", offs, Channel));
+                /* disable device and PHY state change interrupts */
+                if(ChipFlags & NVQ) {
+                    KdPrint2((PRINT_PREFIX "  NVQ, 32bits reg\n"));
+                    AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 
+                        AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) & ((~(ULONG)0x0000000d) << (!Channel*16)) );
+                } else {
+                    AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 
+                        AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) & ((~(UCHAR)0x0d) << (!Channel*4)) );
+                }
+                tmp16 = UniataSataPhyEnable(HwDeviceExtension, j, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE);
+
+                KdPrint2((PRINT_PREFIX "  enable Phy intr, offs %#x\n", offs));
+                /* enable device and PHY state change interrupts */
+                if(ChipFlags & NVQ) {
+                    AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 
+                        AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) | (((ULONG)0x0000000d) << (!Channel*16)) );
+                } else {
+                    AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 
+                        AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) | (((UCHAR)0x0d) << (!Channel*4)) );
+                }
+
+                KdPrint2((PRINT_PREFIX "  dev status %#x\n", tmp16));
+                if(tmp16 != IDE_STATUS_WRONG) {
+                    goto default_reset;
+                }
                 break; }
             case ATA_SILICON_IMAGE_ID: {
                 ULONG offset;
@@ -2458,6 +2562,22 @@ default_reset:
 
                 GetStatus(chan, statusByte);
 
+                if(statusByte != IDE_STATUS_SUCCESS) {
+                    ULONG k;
+                    k = UniataAnybodyHome(deviceExtension, j, i);
+                    if(k == ATA_AT_HOME_HDD) {
+                        // device reset in progress, perform additional wait
+                        KdPrint2((PRINT_PREFIX "  long reset, wait up to 4.5 s\n"));
+                        k = 30 * 1000;
+                        while ((AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) &&
+                               k--)
+                        {
+                            AtapiStallExecution(150);
+                        }
+                        KdPrint2((PRINT_PREFIX " exit after %u loops\n", k));
+                        GetStatus(chan, statusByte);
+                    }
+                }
                 if(statusByte == IDE_STATUS_SUCCESS) {
 
                     IssueIdentify(HwDeviceExtension,
@@ -4261,7 +4381,7 @@ AtapiCheckInterrupt__(
             pr_status = AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
             AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0f << shift));
         }
-        KdPrint2((PRINT_PREFIX "  pr_status %x\n", pr_status));
+        KdPrint2((PRINT_PREFIX "  pr_status %x, shift %x\n", pr_status, shift));
 
         /* check for and handle connect events */
         if(((pr_status & (0x0cUL << shift)) == (0x04UL << shift)) ) {
@@ -5094,6 +5214,15 @@ continue_err:
             interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
             KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
 
+            if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
+                if(deviceExtension->HwFlags & UNIATA_AHCI) {
+                    // Do nothing here
+                } else
+                if(deviceExtension->HwFlags & UNIATA_SATA) {
+                    UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0);
+                }
+            }
+
             if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
                ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
                 if(AtaReq->retry < MAX_RETRIES) {
@@ -5356,24 +5485,24 @@ IntrPrepareResetController:
         // Ensure that this is a write command.
         if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
 
-           KdPrint2((PRINT_PREFIX 
-                      "AtapiInterrupt: Write interrupt\n"));
+            KdPrint2((PRINT_PREFIX 
+                       "AtapiInterrupt: Write interrupt\n"));
 
-           statusByte = WaitOnBusy(chan);
+            statusByte = WaitOnBusy(chan);
 
-           if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
+            if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
 
-               WriteBuffer(chan,
-                           AtaReq->DataBuffer,
-                           wordCount,
-                           UniataGetPioTiming(LunExt));
-           } else {
+                WriteBuffer(chan,
+                            AtaReq->DataBuffer,
+                            wordCount,
+                            UniataGetPioTiming(LunExt));
+            } else {
 
-               WriteBuffer2(chan,
-                           (PULONG)(AtaReq->DataBuffer),
-                           wordCount / 2,
-                           UniataGetPioTiming(LunExt));
-           }
+                WriteBuffer2(chan,
+                            (PULONG)(AtaReq->DataBuffer),
+                            wordCount / 2,
+                            UniataGetPioTiming(LunExt));
+            }
         } else {
 
             KdPrint3((PRINT_PREFIX 
@@ -5381,8 +5510,43 @@ IntrPrepareResetController:
                         interruptReason,
                         srb));
 
+            if(!wordCount && atapiDev && 
+                !(statusByte & (IDE_STATUS_ERROR | IDE_STATUS_BUSY)) &&
+                 (statusByte & IDE_STATUS_DRQ)) {
+                // this can be late Packet interrupt after packet sending
+                KdPrint2((PRINT_PREFIX "  unreliable wordCount ?\n"));
+
+                wordCount = AtapiSuckPortBuffer2(chan,
+                                                 AtaReq->DataBuffer,
+                                                 AtaReq->WordsLeft);
+                KdPrint2((PRINT_PREFIX "  transferred %#x\n", wordCount));
+                GetBaseStatus(chan, statusByte);
+                KdPrint2((PRINT_PREFIX "  status %#x, statusByte\n"));
+                if(wordCount) {
+                    interruptReason = ATAPI_IR_IO_toHost;
+#ifdef _DEBUG
+                    UniataDumpATARegs(chan);
+#endif
+                }
+                if(wordCount && AtaReq->WordsLeft) {
+                    goto continue_atapi_pio_read;
+                }
+            }
             // Fail this request.
             status = SRB_STATUS_ERROR;
+            if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) {
+                // some devices feel bad after incorrect commands and may need reset
+                KdPrint2((PRINT_PREFIX 
+                          "AtapiInterrupt: Try ATAPI reset\n"));
+
+                AtapiDisableInterrupts(deviceExtension, lChannel);
+                AtapiSoftReset(chan, DeviceNumber);
+                AtapiEnableInterrupts(deviceExtension, lChannel);
+                status = SRB_STATUS_BUS_RESET;
+                AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
+
+//                goto IntrPrepareResetController;
+            }
             goto CompleteRequest;
         }
         // Advance data buffer pointer and bytes left.
@@ -5516,7 +5680,7 @@ continue_read_drq:
             status = SRB_STATUS_ERROR;
             goto CompleteRequest;
         }
-
+continue_atapi_pio_read:
         // Advance data buffer pointer and bytes left.
         AtaReq->DataBuffer += wordCount;
         AtaReq->WordsLeft -= wordCount;
@@ -7554,8 +7718,14 @@ make_reset:
                                   CHECK_INTR_IDLE);
     AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
 
+    // clear interrupt
     GetBaseStatus(chan, statusByte);
 
+#ifdef _DEBUG
+    statusByte = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
+    KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", statusByte));
+#endif //DBG
+
     if(g_opt_AtapiSendDisableIntr) {
         AtapiEnableInterrupts(deviceExtension, lChannel);
     }
@@ -7865,7 +8035,7 @@ default_no_prep:
             } else {
                 RtlZeroMemory(modeData, sizeof(MODE_POWER_CONDITION_PAGE));
                 modeData->PageCode = MODE_PAGE_POWER_CONDITION;
-                modeData->PageLength = sizeof(MODE_POWER_CONDITION_PAGE)-sizeof(MODE_PARAMETER_HEADER);
+                modeData->PageLength = sizeof(MODE_PAGE_POWER_CONDITION)-sizeof(MODE_PARAMETER_HEADER);
                 modeData->Byte3.Fields.Idle = LunExt->PowerState <= StartStop_Power_Idle;
                 modeData->Byte3.Fields.Standby = LunExt->PowerState == StartStop_Power_Standby;
                 Srb->DataTransferLength = sizeof(MODE_POWER_CONDITION_PAGE);
@@ -10038,7 +10208,7 @@ DriverEntry(
             return status;
         }
 #endif // USE_REACTOS_DDK
-        KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, KeNumberProcessors));
+        KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, *KeNumberProcessors));
 
         KeQuerySystemTime(&t0);
         do {
@@ -10145,7 +10315,7 @@ DriverEntry(
             g_opt_WaitDrqDelay  = 100;
             g_opt_WaitBusyLongCount = 20000;
             g_opt_MaxIsrWait = 200;
-            g_opt_AtapiSendDisableIntr = 0;
+            g_opt_AtapiSendDisableIntr = FALSE;
             g_opt_AtapiDmaRawRead = FALSE;
             break;
         }
@@ -10165,8 +10335,8 @@ DriverEntry(
         g_opt_WaitDrqDelay  = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitDrqDelay",  g_opt_WaitDrqDelay);  // 10 vs 100
         g_opt_WaitBusyLongCount = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongCount", g_opt_WaitBusyLongCount); // 2000 vs 20000
         g_opt_WaitBusyLongDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongDelay", g_opt_WaitBusyLongDelay); // 250 vs 250
-        g_opt_AtapiSendDisableIntr = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiSendDisableIntr",  g_opt_AtapiSendDisableIntr);  // 1 vs 0
-        g_opt_AtapiDmaRawRead      = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead",       g_opt_AtapiDmaRawRead);       // 1 vs 0
+        g_opt_AtapiSendDisableIntr = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiSendDisableIntr",  g_opt_AtapiSendDisableIntr) ? TRUE : FALSE;  // 1 vs 0
+        g_opt_AtapiDmaRawRead      = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead",       g_opt_AtapiDmaRawRead) ? TRUE : FALSE;       // 1 vs 0
         g_opt_MaxIsrWait    = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxIsrWait",       g_opt_MaxIsrWait);       // 40 vs xxx
     }
 
index 00bd4e3..f606b5f 100644 (file)
@@ -1013,6 +1013,7 @@ AtapiDmaInit(
         /****************/
 
         KdPrint2((PRINT_PREFIX "SATA Generic\n"));
+
         if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || ((udmamode >= 0) && (chan->MaxTransferMode >= ATA_SA150))) {
             /* some drives report UDMA6, some UDMA5 */
             /* ATAPI may not have SataCapabilities set in IDENTIFY DATA */
@@ -1235,29 +1236,85 @@ set_new_acard:
         /*********/
         /* Cyrix */
         /*********/
-        ULONG cyr_piotiming[] =
-            { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
-        ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
-        ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
-        ULONG mode_reg = 0x24+(dev << 3);
-
+dma_cs55xx:
         if(apiomode >= 4)
             apiomode = 4;
-        for(i=udmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
-                AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
+
+        if(ChipType == CYRIX_3x) {
+            ULONG cyr_piotiming[] =
+                { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
+            ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
+            ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
+            ULONG mode_reg = 0x24+(dev << 3);
+
+            for(i=udmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                    AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
+                    return;
+                }
+            }
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+                AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
                 return;
             }
-        }
-        for(i=wdmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
-                AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
+        } else
+        if(ChipType == CYRIX_OLD) {
+            UCHAR cyr_piotiming_old[] =
+                { 11, 6, 3, 2, 1 };
+            UCHAR timing;
+
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+                timing = (6-apiomode) | (cyr_piotiming_old[i]);
+                /* Channel command timing */
+                SetPciConfig1(0x62+Channel, timing);
+                /* Read command timing */
+                SetPciConfig1(0x64+Channel*4+dev, timing);
+                /* Write command timing */
+                SetPciConfig1(0x66+Channel*4+dev, timing);
+                return;
+            }
+        } else
+        if(ChipType == CYRIX_35) {
+/*
+            USHORT c35_pio_timings[5] = {
+                0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131
+            };
+            USHORT c35_pio_cmd_timings[5] = {
+                0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
+            };
+            ULONG c35_udma_timings[5] = {
+               0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061
+            };
+            ULONG c35_mwdma_timings[3] = {
+               0x7F0FFFF3, 0x7F035352, 0x7F024241
+            };
+            ULONG mode_reg = 0x24+(dev << 3);
+*/
+            /* No MSR support yet, do not touch any regs */
+            for(i=udmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                    return;
+                }
+            }
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
                 return;
             }
-        }
-        if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
-            AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
-            return;
         }
         return;
 
@@ -1266,33 +1323,37 @@ set_new_acard:
         /************/
         /* National */
         /************/
-        ULONG nat_piotiming[] =
-           { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
-              0x00803020, 0x20102010, 0x00100010,
-              0x00100010, 0x00100010, 0x00100010 };
-        ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
-        ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
-
-        if(apiomode >= 4)
-            apiomode = 4;
-        for(i=udmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
-                SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]);
-                SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]);
-                return;
+        if(!ChipType) {
+            ULONG nat_piotiming[] =
+               { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
+                  0x00803020, 0x20102010, 0x00100010,
+                  0x00100010, 0x00100010, 0x00100010 };
+            ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
+            ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
+
+            if(apiomode >= 4)
+                apiomode = 4;
+            for(i=udmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                    SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]);
+                    SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]);
+                    return;
+                }
             }
-        }
-        for(i=wdmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
-                SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]);
-                SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]);
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]);
+                    SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]);
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+                ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
+                SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
                 return;
             }
-        }
-        if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
-            ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
-            SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
-            return;
+        } else {
+            goto dma_cs55xx;
         }
         /* Use GENERIC PIO */
         break; }
index 5ba3097..61cfeb4 100644 (file)
@@ -288,6 +288,21 @@ UniataChipDetectChannels(
             KdPrint2((PRINT_PREFIX "New JMicron PATA 1 chan\n"));
         }
         break;
+    case ATA_CYRIX_ID:
+        if(ChipType == CYRIX_OLD) {
+            UCHAR tmp8;
+            ULONG slotNumber;
+            slotNumber = deviceExtension->slotNumber;
+            KdPrint2((PRINT_PREFIX "Cyrix slot %#x\n", slotNumber));
+            GetPciConfig1(0x60, tmp8);
+            if(tmp8 & (1 << BMList[deviceExtension->DevIndex].channel)) {
+                KdPrint2((PRINT_PREFIX "Old Cyrix chan %d ok\n", BMList[deviceExtension->DevIndex].channel));
+            } else {
+                KdPrint2((PRINT_PREFIX "Old Cyrix no chan %d\n", BMList[deviceExtension->DevIndex].channel));
+                return FALSE;
+            }
+        }
+        break;
     } // end switch(VendorID)
 
     i = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NumberChannels", n);
@@ -2094,6 +2109,8 @@ AtapiChipInit(
             KdPrint2((PRINT_PREFIX "Intel SATA\n"));
             if(ChipFlags & UNIATA_AHCI) {
                 KdPrint2((PRINT_PREFIX "Do nothing for AHCI\n"));
+                /* enable PCI interrupt */
+                ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
                 break;
             }
             if(c == CHAN_NOT_SPECIFIED) {
@@ -2643,6 +2660,19 @@ AtapiChipInit(
         if(ChipType == ITE_133_NEW) {
         }
         break;
+    case ATA_CYRIX_ID:
+        KdPrint2((PRINT_PREFIX "Cyrix\n"));
+        if(ChipType == CYRIX_OLD) {
+            if(c == CHAN_NOT_SPECIFIED) {
+                GetPciConfig1(0x60, tmp8);
+                if(!(tmp8 & 0x40)) {
+                    KdPrint2((PRINT_PREFIX "Enable DMA\n"));
+                    tmp8 |= 0x40;
+                    SetPciConfig1(0x60, tmp8);
+                }
+            }
+        }
+        break;
     default:
         if(c != CHAN_NOT_SPECIFIED) {
             // We don't know how to check for 80-pin cable on unknown controllers.
index 42ae4db..a934888 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_probe.cpp
@@ -53,6 +53,10 @@ ULONG         IsaCount = 0;
 ULONG         MCACount = 0;
 
 BOOLEAN FirstMasterOk = FALSE;
+// This is our own resource check,
+// ReactOS allows to allocate same I/O range for both PCI and ISA controllers
+BOOLEAN AtdiskPrimaryClaimed = FALSE;
+BOOLEAN AtdiskSecondaryClaimed = FALSE;
 
 #ifndef UNIATA_CORE
 
@@ -1638,7 +1642,7 @@ UniataFindBusMasterController(
           chan->RegTranslation[IDX_SATA_IO].MemIo ? "mem" : "io"));
 
         if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
-#if DBG
+#ifdef _DEBUG
             UniataDumpATARegs(chan);
 #endif
 
@@ -1721,6 +1725,7 @@ UniataFindBusMasterController(
             KdPrint2((PRINT_PREFIX "claim Compatible controller\n"));
             if (channel == 0) {
                 KdPrint2((PRINT_PREFIX "claim Primary\n"));
+                AtdiskPrimaryClaimed =
                 ConfigInfo->AtdiskPrimaryClaimed = TRUE;
                 chan->PrimaryAddress = TRUE;
 
@@ -1729,10 +1734,24 @@ UniataFindBusMasterController(
             } else
             if (channel == 1) {
                 KdPrint2((PRINT_PREFIX "claim Secondary\n"));
+                AtdiskSecondaryClaimed =
                 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
 
                 FirstMasterOk = TRUE;
             }
+        } else {
+            if(chan->RegTranslation[IDX_IO1].Addr == IO_WD1 &&
+               !chan->RegTranslation[IDX_IO1].MemIo) {
+                KdPrint2((PRINT_PREFIX "claim Primary (PCI over ISA range)\n"));
+                AtdiskPrimaryClaimed =
+                ConfigInfo->AtdiskPrimaryClaimed = TRUE;
+            }
+            if(chan->RegTranslation[IDX_IO1].Addr == IO_WD2 &&
+               !chan->RegTranslation[IDX_IO1].MemIo) {
+                KdPrint2((PRINT_PREFIX "claim Secondary (PCI over ISA range)\n"));
+                AtdiskSecondaryClaimed =
+                ConfigInfo->AtdiskSecondaryClaimed = TRUE;
+            }
         }
 
         AtapiDmaAlloc(HwDeviceExtension, ConfigInfo, c);
@@ -2250,12 +2269,12 @@ AtapiFindController(
         }
         // check if Primary/Secondary Master IDE claimed
         if((ioSpace == (PUCHAR)IO_WD1) &&
-           (ConfigInfo->AtdiskPrimaryClaimed)) {
+           (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) {
             KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskPrimaryClaimed\n"));
             goto not_found;
         } else
         if((ioSpace == (PUCHAR)IO_WD2) &&
-           (ConfigInfo->AtdiskSecondaryClaimed)) {
+           (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) {
             KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskSecondaryClaimed\n"));
             goto not_found;
         }
@@ -2287,7 +2306,7 @@ AtapiFindController(
         UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
         UniataInitMapBM(deviceExtension, 0, FALSE);
 
-#if DBG
+#ifdef _DEBUG
         UniataDumpATARegs(chan);
 #endif
 
@@ -2697,6 +2716,7 @@ CheckDevice(
     UCHAR                statusByte;
     ULONG                RetVal=0;
     ULONG                waitCount = 10000;
+    ULONG                at_home = 0;
 
     KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n",
                deviceNumber));
@@ -2705,7 +2725,7 @@ CheckDevice(
         return 0;
     }
     if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+        if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
             return 0;
         }
     }
@@ -2715,6 +2735,20 @@ CheckDevice(
         LunExt->PowerState = 0;
     }
 
+    if((deviceExtension->HwFlags & UNIATA_SATA) &&
+        !UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
+        deviceNumber) {
+        KdPrint2((PRINT_PREFIX "  SATA w/o i/o registers, check slave presence\n"));
+        SelectDrive(chan, deviceNumber & 0x01);
+        statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect);
+        KdPrint2((PRINT_PREFIX "  DriveSelect: %#x\n", statusByte));
+        if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) {
+            KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
+            UniataForgetDevice(LunExt);
+            return 0;
+        }
+    }
+
     if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
         KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
         if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
@@ -2729,7 +2763,7 @@ CheckDevice(
         // Reset device
         AtapiSoftReset(chan, deviceNumber);
 
-        if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+        if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
             //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
             return 0;
         }
@@ -2787,7 +2821,7 @@ CheckDevice(
         // Select the device.
         SelectDrive(chan, deviceNumber);
 
-        if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+        if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
             //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
             return 0;
         }
@@ -2842,7 +2876,7 @@ CheckDevice(
         // ATAPI signature found.
         // Issue the ATAPI identify command if this
         // is not for the crash dump utility.
-
+try_atapi:
         if (!deviceExtension->DriverMustPoll) {
 
             // Issue ATAPI packet identify command.
@@ -2872,7 +2906,7 @@ CheckDevice(
                 }
 
             } else {
-
+forget_device:
                 // Indicate no working device.
                 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n",
                            deviceNumber));
@@ -2906,6 +2940,16 @@ CheckDevice(
             RetVal = DFLAGS_DEVICE_PRESENT;
             LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
             LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
+        } else {
+            // This can be ATAPI on broken hardware
+            GetBaseStatus(chan, statusByte);
+            if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+                KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n"));
+                goto forget_device;
+            }
+            KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n",
+                       deviceNumber, statusByte));
+            goto try_atapi;
         }
         GetBaseStatus(chan, statusByte);
     }
index 57c1638..38212b1 100644 (file)
@@ -728,12 +728,20 @@ UniataAhciInit(
     }
 
     /* re-enable AHCI mode */
+    /* Linux: Some controllers need AHCI_EN to be written multiple times.
+     * Try a few times before giving up.
+     */
     GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
-    if(!(GHC & AHCI_GHC_AE)) {
-        KdPrint2((PRINT_PREFIX "  re-enable AHCI mode, GHC %#x\n", GHC));
-        UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
-            GHC | AHCI_GHC_AE);
-        GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
+    for(i=0; i<5; i++) {
+        if(!(GHC & AHCI_GHC_AE)) {
+            KdPrint2((PRINT_PREFIX "  re-enable AHCI mode, GHC %#x\n", GHC));
+            UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
+                GHC | AHCI_GHC_AE);
+            AtapiStallExecution(1000);
+            GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
+        } else {
+            break;
+        }
     }
     KdPrint2((PRINT_PREFIX "  AHCI GHC %#x\n", GHC));
     if(!(GHC & AHCI_GHC_AE)) {
@@ -1980,6 +1988,7 @@ UniataAhciStartFR(
     CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
     KdPrint2(("  CMD %#x\n", CMD));
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD | ATA_AHCI_P_CMD_FRE);
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     return;
 } // end UniataAhciStartFR()
@@ -2039,6 +2048,7 @@ UniataAhciStart(
         CMD |
         ATA_AHCI_P_CMD_ST |
         ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     return;
 } // end UniataAhciStart()
@@ -2187,15 +2197,24 @@ UniataAhciBeginTransaction(
     if(CMD0 != CMD) {
         KdPrint2(("  send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
         UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
+        UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
     }
 
     /* issue command to controller */
     //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
+    KdPrint2(("  Set CI\n"));
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 0x01 << tag);
     chan->AhciPrevCI |= 0x01 << tag;
 
+    KdPrint2(("  Send CMD START\n"));
+    UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD,
+        CMD |
+        ATA_AHCI_P_CMD_ST |
+        ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
+
     if(!ATAPI_DEVICE(chan, DeviceNumber)) {
-        // TODO: check if we send ATA_RESET and wait for ready of so.
+        // TODO: check if we send ATAPI_RESET and wait for ready of so.
         if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) {
             ULONG  TFD;
             ULONG  i;
@@ -2365,6 +2384,7 @@ UniataAhciResume(
             (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) |
             (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 ))
             );
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
 #ifdef DBG
     //UniataDumpAhciPortRegs(chan);
@@ -2399,6 +2419,7 @@ UniataAhciSuspend(
     UniataAhciStop(chan);
     UniataAhciStopFR(chan);
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, 0);
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     /* Allow everything including partial and slumber modes. */
     UniataSataWritePort4(chan, IDX_SATA_SControl, 0, 0);
index d5d5ccb..1ddcc2b 100644 (file)
@@ -1,10 +1,10 @@
-#define UNIATA_VER_STR         "45e"
-#define UNIATA_VER_DOT         0.45.5.0
+#define UNIATA_VER_STR         "45h1"
+#define UNIATA_VER_DOT         0.45.8.1
 #define UNIATA_VER_MJ          0
 #define UNIATA_VER_MN          45
-#define UNIATA_VER_SUB_MJ      5
-#define UNIATA_VER_SUB_MN      0
-#define UNIATA_VER_DOT_COMMA   0,45,5,0
-#define UNIATA_VER_DOT_STR     "0.45.5.0"
-#define UNIATA_VER_YEAR        2014
-#define UNIATA_VER_YEAR_STR    "2014"
+#define UNIATA_VER_SUB_MJ      8
+#define UNIATA_VER_SUB_MN      1
+#define UNIATA_VER_DOT_COMMA   0,45,8,1
+#define UNIATA_VER_DOT_STR     "0.45.8.1"
+#define UNIATA_VER_YEAR        2015
+#define UNIATA_VER_YEAR_STR    "2015"