Author: akhaldi
Date: Wed Jan  9 17:19:26 2013
New Revision: 58151

URL: http://svn.reactos.org/svn/reactos?rev=58151&view=rev
Log:
[UNIATA]
* Sync to 0.44c3.
CORE-6649 #resolve #comment Committed in r58151. Thanks Alter ;)
CORE-6563

Modified:
    trunk/reactos/drivers/storage/ide/uniata/atapi.h
    trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp

Modified: trunk/reactos/drivers/storage/ide/uniata/atapi.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/atapi.h?rev=58151&r1=58150&r2=58151&view=diff
==============================================================================
--- trunk/reactos/drivers/storage/ide/uniata/atapi.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/storage/ide/uniata/atapi.h [iso-8859-1] Wed Jan  9 
17:19:26 2013
@@ -533,8 +533,16 @@
 // ATAPI interrupt reasons
 //
 
+// for IDX_ATAPI_IO1_i_InterruptReason
 #define ATAPI_IR_COD 0x01
-#define ATAPI_IR_IO  0x02
+#define ATAPI_IR_COD_Data   0x0
+#define ATAPI_IR_COD_Cmd    0x1
+
+#define ATAPI_IR_IO        0x02
+#define ATAPI_IR_IO_toDev  0x00
+#define ATAPI_IR_IO_toHost 0x02
+
+#define ATAPI_IR_Mask      0x03
 
 //
 // ATA Features

Modified: trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp?rev=58151&r1=58150&r2=58151&view=diff
==============================================================================
--- trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/storage/ide/uniata/id_ata.cpp [iso-8859-1] Wed Jan  9 
17:19:26 2013
@@ -725,16 +725,23 @@
         }
     } else {
         AtapiStallExecution(500);
+        GetBaseStatus(chan, statusByte2);
         AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
-        AtapiStallExecution(30);
-
-        // Wait for BUSY assertion, in some cases delay may occure
-        while (!(AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) &&
-               i--)
-        {
-            AtapiStallExecution(30);
-        }
-
+
+        // Do not wait for BUSY assertion if it was initially set, jump to
+        // BUSY release wait loop
+        if(!(statusByte2 & IDE_STATUS_BUSY)) {
+            // Wait for BUSY assertion, in some cases delay may occure
+            // 100ms should be enough
+            i = 10*1000;
+            while (!(AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) 
&&
+                   i--)
+            {
+                AtapiStallExecution(10);
+            }
+        }
+
+        i = 30 * 1000;
         // ReactOS modification: Already stop looping when we know that the 
drive has finished resetting.
         // Not all controllers clear the IDE_STATUS_BUSY flag (e.g. not the 
VMware one), so ensure that
         // the maximum waiting time (30 * i = 0.9 seconds) does not exceed the 
one of the original
@@ -4492,7 +4499,7 @@
             KdPrint2((PRINT_PREFIX "  OurInterrupt = %d\n", OurInterrupt));
             return OurInterrupt;
         }
-        interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
+        interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
         KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", 
interruptReason));
         return OurInterrupt;
     }
@@ -4847,7 +4854,7 @@
         if(deviceExtension->HwFlags & UNIATA_AHCI) {
             KdPrint3((PRINT_PREFIX "  AHCI branch (ATAPI)\n"));
         } else {
-            interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
+            interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
             KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", 
interruptReason));
         }
 
@@ -5016,7 +5023,7 @@
                 }
             }
         } else {
-            interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
+            interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
             KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason 
%x\n", interruptReason));
 
             if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > 
ATA_UDMA2) &&
@@ -5086,7 +5093,7 @@
         KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
         // ATAPI branch
 
-        interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
+        interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
         KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", 
interruptReason));
         if(DmaTransfer) {
             wordsThisInterrupt = DEV_BSIZE/2*512;
@@ -5113,10 +5120,10 @@
 
             if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
 
-                interruptReason =  0x2;
+                interruptReason = ATAPI_IR_IO_toHost;
 
             } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
-                interruptReason = 0x0;
+                interruptReason = ATAPI_IR_IO_toDev;
 
             } else {
                 status = SRB_STATUS_ERROR;
@@ -5164,13 +5171,13 @@
                     goto ReturnEnableIntr;
 
                 } else {
-                    interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 
0x2 : 0x0;
+                    interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 
ATAPI_IR_IO_toHost : ATAPI_IR_IO_toDev;
                 }
 
             } else {
                 // Command complete - verify, write, or the SMART 
enable/disable.
                 // Also get_media_status
-                interruptReason = 0x3;
+                interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
             }
         }
     }
@@ -5196,7 +5203,7 @@
         chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
         goto CompleteRequest;
     } else
-    if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) {
+    if (interruptReason == ATAPI_IR_COD_Cmd && (statusByte & IDE_STATUS_DRQ)) {
         // Write the packet.
         KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
         // Send CDB to device.
@@ -5212,7 +5219,7 @@
 
         goto ReturnEnableIntr;
 
-    } else if (interruptReason == 0x0 && (statusByte & IDE_STATUS_DRQ)) {
+    } else if (interruptReason == ATAPI_IR_IO_toDev && (statusByte & 
IDE_STATUS_DRQ)) {
 
         // Write the data.
         if (atapiDev) {
@@ -5319,7 +5326,7 @@
 
         goto ReturnEnableIntr;
 
-    } else if (interruptReason == 0x2 && (statusByte & IDE_STATUS_DRQ)) {
+    } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & 
IDE_STATUS_DRQ)) {
 
 
         if (atapiDev) {
@@ -5515,7 +5522,7 @@
 
         goto ReturnEnableIntr;
 
-    } else if (interruptReason == 0x3  && !(statusByte & IDE_STATUS_DRQ)) {
+    } else if (interruptReason == (ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd) && 
!(statusByte & IDE_STATUS_DRQ)) {
 
         KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = 
CompleteRequest\n"));
         // Command complete.
@@ -5663,7 +5670,8 @@
                                                               
AtaReq->OriginalSrb);
                     } else {
 
-                        // last request was illegal.  No point trying again
+                        // last request was illegal.  No point trying again.
+                        // Do-nothing call ?
                         AtapiHwInitializeChanger (HwDeviceExtension,
                                                   srb,
                                                   
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
@@ -5706,6 +5714,7 @@
 
             if (AtaReq->OriginalSrb) {
                 KdPrint2((PRINT_PREFIX "AtapiInterrupt: call 
AtapiHwInitializeChanger()\n"));
+                // Do-nothing call ?
                 AtapiHwInitializeChanger (HwDeviceExtension,
                                           srb,
                                           
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
@@ -6756,7 +6765,7 @@
     //ULONG                ldev = GET_LDEV(Srb);
     ULONG                DeviceNumber = GET_CDEV(Srb);
     ULONG flags;
-    UCHAR statusByte,byteCountLow,byteCountHigh;
+    UCHAR statusByte,statusByte0,byteCountLow,byteCountHigh;
     BOOLEAN use_dma = FALSE;
     BOOLEAN dma_reinited = FALSE;
     BOOLEAN retried = FALSE;
@@ -6901,9 +6910,27 @@
             KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING 
(2)\n"));
             return srbStatus;
         } else {
+
+            // failed!  Get the sense key and maybe try again
+            AtaReq->Srb = BuildRequestSenseSrb (  HwDeviceExtension,
+                                                  AtaReq->OriginalSrb);
+
+            srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, 
CMD_ACTION_ALL);
+
+            KdPrint3((PRINT_PREFIX "AtapiSendCommand: chan->ExpectingInterrupt 
%d (1)\n", chan->ExpectingInterrupt));
+
+            if (srbStatus == SRB_STATUS_PENDING) {
+                KdPrint2((PRINT_PREFIX "AtapiSendCommand: send orig 
SRB_STATUS_PENDING (2.1)\n"));
+                return srbStatus;
+            }
+
+            // failed again ? should not get here
+
             AtaReq->Srb = AtaReq->OriginalSrb;
             AtaReq->OriginalSrb = NULL;
+
             KdPrint2((PRINT_PREFIX "AtapiSendCommand: 
AtapiHwInitializeChanger()\n"));
+            // Do-nothing call ?
             AtapiHwInitializeChanger (HwDeviceExtension, Srb,
                                       (PMECHANICAL_STATUS_INFORMATION_HEADER) 
NULL);
             // fall out
@@ -7395,6 +7422,8 @@
     if(g_opt_AtapiSendDisableIntr) {
         AtapiDisableInterrupts(deviceExtension, lChannel);
     }
+    // remember status. Later we may check if error appeared after cmd packet 
+    statusByte0 = statusByte;
 
     // Write ATAPI packet command.
     AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET);
@@ -7442,9 +7471,19 @@
     GetStatus(chan, statusByte);
     KdPrint3((PRINT_PREFIX "AtapiSendCommand: cmd status (%#x)\n", 
statusByte));
 
+    // When we operate in DMA mode, we should not start transfer when there is 
an error on entry
+    // Interrupt may never come in such case.
     if(statusByte & IDE_STATUS_ERROR) {
+        UCHAR interruptReason;
+
         GetBaseStatus(chan, statusByte);
         KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on cmd: (%#x)\n", 
statusByte));
+
+        interruptReason = (AtapiReadPort1(chan, 
IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
+        KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", 
interruptReason));
+
+        // TODO:  we should check interruptReason and decide what to do now
+
         // Read the error reg. to clear it and fail this request.
         AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
         return MapError(deviceExtension, Srb);


Reply via email to