mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 17:05:45 +00:00
[UNIATA]
* Sync to 0.44c3. CORE-6649 #resolve #comment Committed in r58151. Thanks Alter ;) CORE-6563 svn path=/trunk/; revision=58151
This commit is contained in:
parent
4fffa4fbc6
commit
296c68fb57
2 changed files with 68 additions and 21 deletions
|
@ -533,8 +533,16 @@ typedef union _ATAPI_REGISTERS_2 {
|
||||||
// ATAPI interrupt reasons
|
// ATAPI interrupt reasons
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// for IDX_ATAPI_IO1_i_InterruptReason
|
||||||
#define ATAPI_IR_COD 0x01
|
#define ATAPI_IR_COD 0x01
|
||||||
|
#define ATAPI_IR_COD_Data 0x0
|
||||||
|
#define ATAPI_IR_COD_Cmd 0x1
|
||||||
|
|
||||||
#define ATAPI_IR_IO 0x02
|
#define ATAPI_IR_IO 0x02
|
||||||
|
#define ATAPI_IR_IO_toDev 0x00
|
||||||
|
#define ATAPI_IR_IO_toHost 0x02
|
||||||
|
|
||||||
|
#define ATAPI_IR_Mask 0x03
|
||||||
|
|
||||||
//
|
//
|
||||||
// ATA Features
|
// ATA Features
|
||||||
|
|
|
@ -725,16 +725,23 @@ AtapiSoftReset(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AtapiStallExecution(500);
|
AtapiStallExecution(500);
|
||||||
|
GetBaseStatus(chan, statusByte2);
|
||||||
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
|
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
|
||||||
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
|
// 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) &&
|
while (!(AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) &&
|
||||||
i--)
|
i--)
|
||||||
{
|
{
|
||||||
AtapiStallExecution(30);
|
AtapiStallExecution(10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = 30 * 1000;
|
||||||
// ReactOS modification: Already stop looping when we know that the drive has finished resetting.
|
// 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
|
// 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
|
// the maximum waiting time (30 * i = 0.9 seconds) does not exceed the one of the original
|
||||||
|
@ -4492,7 +4499,7 @@ skip_dma_stat_check:
|
||||||
KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt));
|
KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt));
|
||||||
return 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));
|
KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
|
||||||
return OurInterrupt;
|
return OurInterrupt;
|
||||||
}
|
}
|
||||||
|
@ -4847,7 +4854,7 @@ try_dpc_wait:
|
||||||
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
if(deviceExtension->HwFlags & UNIATA_AHCI) {
|
||||||
KdPrint3((PRINT_PREFIX " AHCI branch (ATAPI)\n"));
|
KdPrint3((PRINT_PREFIX " AHCI branch (ATAPI)\n"));
|
||||||
} else {
|
} 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));
|
KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5016,7 +5023,7 @@ continue_err:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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));
|
KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
|
||||||
|
|
||||||
if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
|
if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
|
||||||
|
@ -5086,7 +5093,7 @@ continue_PIO:
|
||||||
KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
|
KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
|
||||||
// ATAPI branch
|
// 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));
|
KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
|
||||||
if(DmaTransfer) {
|
if(DmaTransfer) {
|
||||||
wordsThisInterrupt = DEV_BSIZE/2*512;
|
wordsThisInterrupt = DEV_BSIZE/2*512;
|
||||||
|
@ -5113,10 +5120,10 @@ continue_PIO:
|
||||||
|
|
||||||
if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
|
if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
|
||||||
|
|
||||||
interruptReason = 0x2;
|
interruptReason = ATAPI_IR_IO_toHost;
|
||||||
|
|
||||||
} else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
|
} else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
|
||||||
interruptReason = 0x0;
|
interruptReason = ATAPI_IR_IO_toDev;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
status = SRB_STATUS_ERROR;
|
status = SRB_STATUS_ERROR;
|
||||||
|
@ -5164,13 +5171,13 @@ IntrPrepareResetController:
|
||||||
goto ReturnEnableIntr;
|
goto ReturnEnableIntr;
|
||||||
|
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
// Command complete - verify, write, or the SMART enable/disable.
|
// Command complete - verify, write, or the SMART enable/disable.
|
||||||
// Also get_media_status
|
// Also get_media_status
|
||||||
interruptReason = 0x3;
|
interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5196,7 +5203,7 @@ IntrPrepareResetController:
|
||||||
chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
|
chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
|
||||||
goto CompleteRequest;
|
goto CompleteRequest;
|
||||||
} else
|
} else
|
||||||
if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) {
|
if (interruptReason == ATAPI_IR_COD_Cmd && (statusByte & IDE_STATUS_DRQ)) {
|
||||||
// Write the packet.
|
// Write the packet.
|
||||||
KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
|
KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
|
||||||
// Send CDB to device.
|
// Send CDB to device.
|
||||||
|
@ -5212,7 +5219,7 @@ IntrPrepareResetController:
|
||||||
|
|
||||||
goto ReturnEnableIntr;
|
goto ReturnEnableIntr;
|
||||||
|
|
||||||
} else if (interruptReason == 0x0 && (statusByte & IDE_STATUS_DRQ)) {
|
} else if (interruptReason == ATAPI_IR_IO_toDev && (statusByte & IDE_STATUS_DRQ)) {
|
||||||
|
|
||||||
// Write the data.
|
// Write the data.
|
||||||
if (atapiDev) {
|
if (atapiDev) {
|
||||||
|
@ -5319,7 +5326,7 @@ IntrPrepareResetController:
|
||||||
|
|
||||||
goto ReturnEnableIntr;
|
goto ReturnEnableIntr;
|
||||||
|
|
||||||
} else if (interruptReason == 0x2 && (statusByte & IDE_STATUS_DRQ)) {
|
} else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
|
||||||
|
|
||||||
|
|
||||||
if (atapiDev) {
|
if (atapiDev) {
|
||||||
|
@ -5515,7 +5522,7 @@ IntrPrepareResetController:
|
||||||
|
|
||||||
goto ReturnEnableIntr;
|
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"));
|
KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = CompleteRequest\n"));
|
||||||
// Command complete.
|
// Command complete.
|
||||||
|
@ -5663,7 +5670,8 @@ CompleteRequest:
|
||||||
AtaReq->OriginalSrb);
|
AtaReq->OriginalSrb);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// last request was illegal. No point trying again
|
// last request was illegal. No point trying again.
|
||||||
|
// Do-nothing call ?
|
||||||
AtapiHwInitializeChanger (HwDeviceExtension,
|
AtapiHwInitializeChanger (HwDeviceExtension,
|
||||||
srb,
|
srb,
|
||||||
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
|
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
|
||||||
|
@ -5706,6 +5714,7 @@ CompleteRequest:
|
||||||
|
|
||||||
if (AtaReq->OriginalSrb) {
|
if (AtaReq->OriginalSrb) {
|
||||||
KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiHwInitializeChanger()\n"));
|
KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiHwInitializeChanger()\n"));
|
||||||
|
// Do-nothing call ?
|
||||||
AtapiHwInitializeChanger (HwDeviceExtension,
|
AtapiHwInitializeChanger (HwDeviceExtension,
|
||||||
srb,
|
srb,
|
||||||
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
|
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
|
||||||
|
@ -6756,7 +6765,7 @@ AtapiSendCommand(
|
||||||
//ULONG ldev = GET_LDEV(Srb);
|
//ULONG ldev = GET_LDEV(Srb);
|
||||||
ULONG DeviceNumber = GET_CDEV(Srb);
|
ULONG DeviceNumber = GET_CDEV(Srb);
|
||||||
ULONG flags;
|
ULONG flags;
|
||||||
UCHAR statusByte,byteCountLow,byteCountHigh;
|
UCHAR statusByte,statusByte0,byteCountLow,byteCountHigh;
|
||||||
BOOLEAN use_dma = FALSE;
|
BOOLEAN use_dma = FALSE;
|
||||||
BOOLEAN dma_reinited = FALSE;
|
BOOLEAN dma_reinited = FALSE;
|
||||||
BOOLEAN retried = FALSE;
|
BOOLEAN retried = FALSE;
|
||||||
|
@ -6901,9 +6910,27 @@ AtapiSendCommand(
|
||||||
KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n"));
|
KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n"));
|
||||||
return srbStatus;
|
return srbStatus;
|
||||||
} else {
|
} 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->Srb = AtaReq->OriginalSrb;
|
||||||
AtaReq->OriginalSrb = NULL;
|
AtaReq->OriginalSrb = NULL;
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiHwInitializeChanger()\n"));
|
KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiHwInitializeChanger()\n"));
|
||||||
|
// Do-nothing call ?
|
||||||
AtapiHwInitializeChanger (HwDeviceExtension, Srb,
|
AtapiHwInitializeChanger (HwDeviceExtension, Srb,
|
||||||
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
|
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
|
||||||
// fall out
|
// fall out
|
||||||
|
@ -7395,6 +7422,8 @@ make_reset:
|
||||||
if(g_opt_AtapiSendDisableIntr) {
|
if(g_opt_AtapiSendDisableIntr) {
|
||||||
AtapiDisableInterrupts(deviceExtension, lChannel);
|
AtapiDisableInterrupts(deviceExtension, lChannel);
|
||||||
}
|
}
|
||||||
|
// remember status. Later we may check if error appeared after cmd packet
|
||||||
|
statusByte0 = statusByte;
|
||||||
|
|
||||||
// Write ATAPI packet command.
|
// Write ATAPI packet command.
|
||||||
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET);
|
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET);
|
||||||
|
@ -7442,9 +7471,19 @@ make_reset:
|
||||||
GetStatus(chan, statusByte);
|
GetStatus(chan, statusByte);
|
||||||
KdPrint3((PRINT_PREFIX "AtapiSendCommand: cmd status (%#x)\n", 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) {
|
if(statusByte & IDE_STATUS_ERROR) {
|
||||||
|
UCHAR interruptReason;
|
||||||
|
|
||||||
GetBaseStatus(chan, statusByte);
|
GetBaseStatus(chan, statusByte);
|
||||||
KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on cmd: (%#x)\n", 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.
|
// Read the error reg. to clear it and fail this request.
|
||||||
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
|
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
|
||||||
return MapError(deviceExtension, Srb);
|
return MapError(deviceExtension, Srb);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue