* Sync with v0.42h.

svn path=/trunk/; revision=57050
This commit is contained in:
Amine Khaldi 2012-08-06 13:26:40 +00:00
parent e05a2f4599
commit ff6df0d592
11 changed files with 455 additions and 116 deletions

View file

@ -502,6 +502,7 @@ typedef union _ATAPI_REGISTERS_2 {
#define ATA_F_DMA 0x01 /* enable DMA */
#define ATA_F_OVL 0x02 /* enable overlap */
#define ATA_F_DMAREAD 0x04 /* DMA Packet (ATAPI) read */
#define ATA_C_F_SETXFER 0x03 /* set transfer mode */
@ -628,8 +629,19 @@ typedef struct _IDENTIFY_DATA {
ULONG UserAddressableSectors; // 60-61
USHORT SingleWordDMASupport : 8; // 62 \- obsolete
USHORT SingleWordDMAActive : 8; // /-
union {
struct {
USHORT SingleWordDMASupport : 8; // 62 ATA, obsolete
USHORT SingleWordDMAActive : 8; //
};
struct {
USHORT UDMASupport : 7; // 62 ATAPI
USHORT MultiWordDMASupport : 3;
USHORT DMASupport : 1;
USHORT Reaseved62_11_14 : 4;
USHORT DMADirRequired : 1;
} AtapiDMA;
};
USHORT MultiWordDMASupport : 8; // 63
USHORT MultiWordDMAActive : 8;

View file

@ -187,11 +187,14 @@ typedef struct _IDE_AHCI_REGISTERS {
} CAP;
#define AHCI_CAP_NOP_MASK 0x0000001f
#define AHCI_CAP_CCC 0x00000080
#define AHCI_CAP_NCS_MASK 0x00001f00
#define AHCI_CAP_PMD 0x00008000
#define AHCI_CAP_SPM 0x00020000
#define AHCI_CAP_SAM 0x00040000
#define AHCI_CAP_SCLO 0x01000000
#define AHCI_CAP_SNTF 0x20000000
#define AHCI_CAP_NCQ 0x40000000
#define AHCI_CAP_S64A 0x80000000
// Global HBA Control
@ -619,6 +622,7 @@ typedef struct _IDE_AHCI_PORT_REGISTERS {
#define IDX_AHCI_P_TFD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD))
#define IDX_AHCI_P_SIG (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG))
#define IDX_AHCI_P_CMD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CMD))
#define IDX_AHCI_P_ACT (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT))
#define IDX_AHCI_P_SNTF (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SNTF))
@ -1160,8 +1164,8 @@ typedef struct _HW_DEVICE_EXTENSION {
HW_LU_EXTENSION lun[IDE_MAX_LUN];
HW_CHANNEL chan[AHCI_MAX_PORT/*IDE_MAX_CHAN*/];
#else
PHW_LU_EXTENSION lun;
PHW_CHANNEL chan;
PHW_LU_EXTENSION lun; // lun array
PHW_CHANNEL chan; // channel array
#endif
UCHAR LastInterruptedChannel;
// Indicates the number of blocks transferred per int. according to the

View file

@ -773,7 +773,7 @@ AtaCommand48(
IN ULONG wait_flags
)
{
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
UCHAR statusByte;
ULONG i;
PUCHAR plba;
@ -1089,7 +1089,7 @@ AtapiTimerDpc(
KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no items\n"));
return;
}
chan = &deviceExtension->chan[lChannel];
chan = &(deviceExtension->chan[lChannel]);
while(TRUE) {
@ -1178,13 +1178,13 @@ AtapiQueueTimerDpc(
chan = prev_chan = NULL;
while(i != CHAN_NOT_SPECIFIED) {
prev_chan = chan;
chan = &deviceExtension->chan[i];
chan = &(deviceExtension->chan[i]);
if(chan->DpcTime > time.QuadPart) {
break;
}
i = chan->NextDpcChan;
}
chan = &deviceExtension->chan[lChannel];
chan = &(deviceExtension->chan[lChannel]);
if(!prev_chan) {
deviceExtension->FirstDpcChan = lChannel;
} else {
@ -1271,7 +1271,7 @@ IssueIdentify(
)
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
ULONG waitCount = 50000;
ULONG j;
UCHAR statusByte;
@ -1424,6 +1424,7 @@ IssueIdentify(
// Send IDENTIFY command.
// Load CylinderHigh and CylinderLow with number bytes to transfer for old devices, use 0 for newer.
statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, Command, (j < 4) ? DEV_BSIZE : 0 /* cyl */, 0, 0, 0, 0, ATA_WAIT_INTR);
// Clear interrupt
@ -2066,10 +2067,10 @@ AtapiResetController__(
for (; j < numberChannels; j++) {
KdPrint2((PRINT_PREFIX "AtapiResetController: Reset channel %d\n", j));
chan = &deviceExtension->chan[j];
KdPrint2((PRINT_PREFIX " CompleteType %#x\n", CompleteType));
//MaxLuns = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2;
chan = &(deviceExtension->chan[j]);
MaxLuns = chan->NumberLuns;
KdPrint2((PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x\n", CompleteType, MaxLuns, chan));
//MaxLuns = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2;
if(CompleteType != RESET_COMPLETE_NONE) {
#ifndef UNIATA_CORE
while((CurSrb = UniataGetCurRequest(chan))) {
@ -2283,11 +2284,14 @@ default_reset:
// all these shall be performed inside AtapiHwInitialize__() ?
#if 1
KdPrint2((PRINT_PREFIX " process connected devices\n"));
KdPrint2((PRINT_PREFIX " process connected devices 0 - %d\n", MaxLuns-1));
// Do special processing for ATAPI and IDE disk devices.
for (i = 0; i < MaxLuns; i++) {
// Check if device present.
KdPrint2((PRINT_PREFIX " Chan %#x\n", chan));
KdPrint2((PRINT_PREFIX " Lun %#x\n", i));
KdPrint2((PRINT_PREFIX " Lun ptr %#x\n", chan->lun[i]));
if (!(chan->lun[i]->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
if(ChipFlags & UNIATA_AHCI) {
// everything is done in UniataAhciReset()
@ -2429,7 +2433,7 @@ MapError(
ULONG lChannel = GET_CHANNEL(Srb);
PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
// ULONG i;
UCHAR errorByte;
UCHAR errorByte = 0;
UCHAR srbStatus = SRB_STATUS_SUCCESS;
UCHAR scsiStatus;
ULONG DeviceNumber = GET_CDEV(Srb);
@ -2437,7 +2441,15 @@ MapError(
// Read the error register.
errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
if(deviceExtension->HwFlags & UNIATA_AHCI) {
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
if(AtaReq) {
errorByte = AtaReq->ahci.in_error;
} else {
}
} else {
errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
}
KdPrint2((PRINT_PREFIX
"MapError: Error register is %#x\n",
errorByte));
@ -3803,7 +3815,7 @@ AtapiEnableInterrupts(
if(deviceExtension->HwFlags & UNIATA_AHCI) {
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE,
(ATA_AHCI_P_IX_CPD | ATA_AHCI_P_IX_TFE | ATA_AHCI_P_IX_HBF |
ATA_AHCI_P_IX_HBD | ATA_AHCI_P_IX_IF | ATA_AHCI_P_IX_OF |
ATA_AHCI_P_IX_HBD | ATA_AHCI_P_IX_INF | ATA_AHCI_P_IX_IF | ATA_AHCI_P_IX_OF |
((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */
ATA_AHCI_P_IX_DI |
@ -4576,6 +4588,29 @@ ServiceInterrupt:
if(deviceExtension->HwFlags & UNIATA_AHCI) {
UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, srb);
statusByte = (UCHAR)(AtaReq->ahci.in_status & IDE_STATUS_MASK);
if(chan->AhciLastIS & ~(ATA_AHCI_P_IX_DHR | ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DS | ATA_AHCI_P_IX_SDB)) {
KdPrint3((PRINT_PREFIX "Err intr (%#x)\n", chan->AhciLastIS & ~(ATA_AHCI_P_IX_DHR | ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DS | ATA_AHCI_P_IX_SDB)));
if(chan->AhciLastIS & ~ATA_AHCI_P_IX_OF) {
//KdPrint3((PRINT_PREFIX "Err mask (%#x)\n", chan->AhciLastIS & ~ATA_AHCI_P_IX_OF));
// We have some other error except Overflow
// Just signal ERROR, operation will be aborted in ERROR branch.
statusByte |= IDE_STATUS_ERROR;
} else {
// We have only Overflow. Abort operation and continue
#if DBG
UniataDumpAhciPortRegs(chan);
#endif
if(!UniataAhciAbortOperation(chan)) {
KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
}
#if DBG
UniataDumpAhciPortRegs(chan);
#endif
UniataAhciWaitCommandReady(chan, 10);
}
}
} else {
GetBaseStatus(chan, statusByte);
}
@ -4738,16 +4773,16 @@ try_dpc_wait:
(dma_status & BM_STATUS_ERR)) {
if(deviceExtension->HwFlags & UNIATA_AHCI) {
error = (UCHAR)((AtaReq->ahci.in_status >> 8) & 0xff);
error = AtaReq->ahci.in_error;
// wait ready
#if DBG
UniataDumpAhciPortRegs(chan);
#endif
UniataAhciStop(chan);
UniataAhciStart(chan);
UniataAhciWaitCommandReady(chan, 10);
if(!UniataAhciAbortOperation(chan)) {
KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
}
// clear interrupts again
UniataAhciWaitCommandReady(chan, 10);
#if DBG
UniataDumpAhciPortRegs(chan);
#endif
@ -5199,6 +5234,17 @@ IntrPrepareResetController:
if(DataOverrun) {
KdPrint2((PRINT_PREFIX " DataOverrun\n"));
AtapiSuckPort2(chan);
GetBaseStatus(chan, statusByte);
}
if(statusByte & IDE_STATUS_BUSY) {
for (i = 0; i < 2; i++) {
AtapiStallExecution(10);
GetBaseStatus(chan, statusByte);
if (!(statusByte & IDE_STATUS_BUSY)) {
break;
}
}
}
} else {
@ -5361,7 +5407,7 @@ IntrPrepareResetController:
CompleteRequest:
KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest\n"));
KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, srbstatus %x\n", status));
// Check and see if we are processing our secret (mechanism status/request sense) srb
if (AtaReq->OriginalSrb) {
@ -5790,6 +5836,13 @@ reenqueue_req:
interruptReason,
statusByte));
if(OldReqState == REQ_STATE_DPC_WAIT_BUSY0 &&
AtaReq->WordsLeft == 0) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: pending WAIT_BUSY0. Complete.\n"));
status = SRB_STATUS_SUCCESS;
chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
goto CompleteRequest;
}
}
ReturnEnableIntr:
@ -5980,7 +6033,7 @@ ULONGLONG
NTAPI
UniAtaCalculateLBARegs(
PHW_LU_EXTENSION LunExt,
ULONG startingSector,
ULONGLONG startingSector,
PULONG max_bcount
)
{
@ -6077,7 +6130,7 @@ IdeReadWrite(
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
//ULONG ldev = GET_LDEV(Srb);
UCHAR DeviceNumber = GET_CDEV(Srb);;
ULONG startingSector;
ULONGLONG startingSector=0;
ULONG max_bcount;
ULONG wordCount = 0;
UCHAR statusByte,statusByte2;
@ -6108,9 +6161,9 @@ IdeReadWrite(
if(AtaReq->WordsTransfered) {
AtaReq->DataBuffer = ((PUSHORT)(Srb->DataBuffer)) + AtaReq->WordsTransfered;
startingSector = (ULONG)(UniAtaCalculateLBARegsBack(LunExt, AtaReq->lba)) /* latest lba */ + AtaReq->bcount /* previous bcount */;
startingSector = (UniAtaCalculateLBARegsBack(LunExt, AtaReq->lba)) /* latest lba */ + AtaReq->bcount /* previous bcount */;
AtaReq->bcount = (AtaReq->TransferLength - AtaReq->WordsTransfered*2 + DEV_BSIZE-1) / DEV_BSIZE;
KdPrint2((PRINT_PREFIX "IdeReadWrite (Chained REQ): Starting sector %#x, OrigWordsRequested %#x, WordsTransfered %#x, DevSize %#x\n",
KdPrint2((PRINT_PREFIX "IdeReadWrite (Chained REQ): Starting sector %I64x, OrigWordsRequested %#x, WordsTransfered %#x, DevSize %#x\n",
startingSector,
AtaReq->TransferLength/2,
AtaReq->WordsTransfered,
@ -6119,9 +6172,24 @@ IdeReadWrite(
AtaReq->DataBuffer = (PUSHORT)(Srb->DataBuffer);
AtaReq->TransferLength = Srb->DataTransferLength;
// Set up 1st block.
MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
KdPrint2((PRINT_PREFIX "IdeReadWrite (Orig REQ): Starting sector %#x, OrigWordsRequested %#x, DevSize %#x\n",
switch(Srb->Cdb[0]) {
case SCSIOP_READ:
case SCSIOP_WRITE:
MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
break;
case SCSIOP_READ12:
case SCSIOP_WRITE12:
MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB12READWRITE.LBA);
MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
break;
case SCSIOP_READ16:
case SCSIOP_WRITE16:
MOV_QD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
break;
}
KdPrint2((PRINT_PREFIX "IdeReadWrite (Orig REQ): Starting sector %I64x, OrigWordsRequested %#x, DevSize %#x\n",
startingSector,
AtaReq->TransferLength/2,
AtaReq->bcount));
@ -6134,7 +6202,7 @@ IdeReadWrite(
AtaReq->WordsLeft = min(AtaReq->TransferLength - AtaReq->WordsTransfered*2,
AtaReq->bcount * DEV_BSIZE) / 2;
KdPrint2((PRINT_PREFIX "IdeReadWrite (REQ): Starting sector is %#x, Number of WORDS %#x, DevSize %#x\n",
KdPrint2((PRINT_PREFIX "IdeReadWrite (REQ): Starting sector is %I64x, Number of WORDS %#x, DevSize %#x\n",
startingSector,
AtaReq->WordsLeft,
AtaReq->bcount));
@ -6380,11 +6448,11 @@ IdeVerify(
//ULONG ldev = GET_LDEV(Srb);
ULONG DeviceNumber = GET_CDEV(Srb);
UCHAR statusByte;
ULONG startingSector;
ULONGLONG startingSector=0;
ULONG max_bcount;
ULONG sectors;
ULONG endSector;
USHORT sectorCount;
ULONGLONG sectors;
ULONGLONG endSector;
ULONG sectorCount=0;
ULONGLONG lba;
LunExt = chan->lun[DeviceNumber];
@ -6400,18 +6468,30 @@ IdeVerify(
sectors));
// Get starting sector number from CDB.
MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
MOV_DW_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
switch(Srb->Cdb[0]) {
case SCSIOP_VERIFY:
MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
MOV_SWP_DW2DD(sectorCount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
break;
case SCSIOP_VERIFY12:
MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB12READWRITE.LBA);
MOV_DD_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
break;
case SCSIOP_VERIFY16:
MOV_QD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
MOV_DD_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
break;
}
KdPrint2((PRINT_PREFIX
"IdeVerify: Starting sector %#x. Number of blocks %#x\n",
"IdeVerify: Starting sector %#I64x. Number of blocks %#x\n",
startingSector,
sectorCount));
endSector = startingSector + sectorCount;
KdPrint2((PRINT_PREFIX
"IdeVerify: Ending sector %#x\n",
"IdeVerify: Ending sector %#I64x\n",
endSector));
if (endSector > sectors) {
@ -6421,7 +6501,7 @@ IdeVerify(
"IdeVerify: Truncating request to %#x blocks\n",
sectors - startingSector - 1));
sectorCount = (USHORT)(sectors - startingSector - 1);
sectorCount = (ULONG)(sectors - startingSector - 1);
} else {
@ -6443,7 +6523,7 @@ IdeVerify(
statusByte = AtaCommand48(deviceExtension, LunExt->Lun, GET_CHANNEL(Srb),
IDE_COMMAND_VERIFY, lba,
sectorCount,
(USHORT)sectorCount,
0, ATA_IMMEDIATE);
if(!(statusByte & IDE_STATUS_ERROR)) {
@ -6490,6 +6570,7 @@ AtapiSendCommand(
BOOLEAN dma_reinited = FALSE;
BOOLEAN retried = FALSE;
ULONG fis_size;
UCHAR FeatureReg=0;
LunExt = chan->lun[DeviceNumber];
@ -6540,6 +6621,18 @@ AtapiSendCommand(
Cdb->CDB12READWRITE.LBA[3]
));
} else
if(ScsiCommand == SCSIOP_WRITE16) {
KdPrint(("Write16, LBA %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
Cdb->CDB16READWRITE.LBA[0],
Cdb->CDB16READWRITE.LBA[1],
Cdb->CDB16READWRITE.LBA[2],
Cdb->CDB16READWRITE.LBA[3],
Cdb->CDB16READWRITE.LBA[4],
Cdb->CDB16READWRITE.LBA[5],
Cdb->CDB16READWRITE.LBA[6],
Cdb->CDB16READWRITE.LBA[7]
));
} else
if(ScsiCommand == SCSIOP_MODE_SELECT) {
KdPrint(("ModeSelect 6\n"));
PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
@ -6571,6 +6664,8 @@ AtapiSendCommand(
case SCSIOP_WRITE:
case SCSIOP_READ12:
case SCSIOP_WRITE12:
case SCSIOP_READ16:
case SCSIOP_WRITE16:
// all right
break;
default:
@ -6638,6 +6733,13 @@ AtapiSendCommand(
// check if reorderable
switch(Srb->Cdb[0]) {
case SCSIOP_READ16:
case SCSIOP_WRITE16:
MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
MOV_QD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
goto GetLba2;
case SCSIOP_READ12:
case SCSIOP_WRITE12:
@ -6650,15 +6752,36 @@ AtapiSendCommand(
MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
GetLba:
MOV_DD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB10.LBA);
GetLba2:
AtaReq->Flags |= REQ_FLAG_REORDERABLE_CMD;
AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE || Srb->Cdb[0] == SCSIOP_WRITE12) ?
AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
Srb->Cdb[0] == SCSIOP_WRITE12 ||
Srb->Cdb[0] == SCSIOP_WRITE16) ?
REQ_FLAG_WRITE : REQ_FLAG_READ;
break;
default:
AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
if(!AtaReq->TransferLength) {
KdPrint((" assume 0-transfer\n"));
} else
if(Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
KdPrint((" assume OUT\n"));
AtaReq->Flags |= REQ_FLAG_WRITE;
} else
if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
KdPrint((" assume IN\n"));
AtaReq->Flags |= REQ_FLAG_READ;
}
break;
}
// check if DMA read/write
if(deviceExtension->HwFlags & UNIATA_SATA) {
// DEBUG !!!! for TEST ONLY
KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (ahci)\n"));
use_dma = TRUE;
} else
if(Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE, no DMA setup\n"));
} else
@ -6667,6 +6790,7 @@ GetLba:
switch(Srb->Cdb[0]) {
case SCSIOP_WRITE:
case SCSIOP_WRITE12:
case SCSIOP_WRITE16:
case SCSIOP_SEND:
if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_RO)
break;
@ -6674,6 +6798,7 @@ GetLba:
case SCSIOP_RECEIVE:
case SCSIOP_READ:
case SCSIOP_READ12:
case SCSIOP_READ16:
if(deviceExtension->opt_AtapiDmaReadWrite) {
call_dma_setup:
@ -6734,8 +6859,13 @@ call_dma_setup:
if(deviceExtension->HwFlags & UNIATA_AHCI) {
UniataAhciSetupCmdPtr(AtaReq);
if(!Srb->DataTransferLength) {
KdPrint2((PRINT_PREFIX "zero-transfer\n"));
use_dma = FALSE;
} else
if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
(PUCHAR)(AtaReq->DataBuffer),
Srb->DataTransferLength)) {
@ -6744,18 +6874,25 @@ call_dma_setup:
}
if(!use_dma) {
AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
} else {
FeatureReg |= ATA_F_DMA;
if(LunExt->IdentifyData.AtapiDMA.DMADirRequired &&
(Srb->SrbFlags & SRB_FLAGS_DATA_IN)) {
FeatureReg |= ATA_F_DMAREAD;
}
}
KdPrint2((PRINT_PREFIX "AtapiSendCommand: setup AHCI FIS\n"));
RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis));
RtlCopyMemory(&(AtaReq->ahci.ahci_cmd_ptr->acmd), Srb->Cdb, 16);
// this is done in UniataAhciSetupFIS_H2D()
//RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis));
RtlCopyMemory(&(AtaReq->ahci.ahci_cmd_ptr->acmd), Srb->Cdb, Srb->CdbLength);
fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
&(AtaReq->ahci.ahci_cmd_ptr->cfis[0]),
IDE_COMMAND_ATAPI_PACKET /* command */,
0 /* lba */,
(Srb->DataTransferLength >= 0x10000) ? (USHORT)(0xffff) : (USHORT)(Srb->DataTransferLength),
use_dma ? ATA_F_DMA : 0/* feature */
FeatureReg/* feature */
);
if(!fis_size) {
@ -6764,16 +6901,10 @@ call_dma_setup:
}
AtaReq->ahci.io_cmd_flags = UniAtaAhciAdjustIoFlags(0,
((AtaReq->Flags & REQ_FLAG_READ) ? 0 : ATA_AHCI_CMD_WRITE) |
((Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)) ? ATA_AHCI_CMD_WRITE : 0) |
(ATA_AHCI_CMD_ATAPI | ATA_AHCI_CMD_PREFETCH),
fis_size, DeviceNumber);
#if 0
AtaReq->ahci.io_cmd_flags = (USHORT)(((AtaReq->Flags & REQ_FLAG_READ) ? 0 : ATA_AHCI_CMD_WRITE) |
/*((LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? (ATA_AHCI_CMD_ATAPI | ATA_AHCI_CMD_PREFETCH) : 0) |*/
(ATA_AHCI_CMD_ATAPI | ATA_AHCI_CMD_PREFETCH) |
(fis_size / sizeof(ULONG)) |
(DeviceNumber << 12));
#endif
KdPrint2((PRINT_PREFIX "AtapiSendCommand ahci io flags %x: \n", AtaReq->ahci.io_cmd_flags));
}
@ -6805,7 +6936,7 @@ call_dma_setup:
KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
}
if((Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) /*&& !(deviceExtension->HwFlags & UNIATA_AHCI)*/) {
if((Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) && !(deviceExtension->HwFlags & UNIATA_SATA)) {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE -> no dma setup (2)\n"));
use_dma = FALSE;
AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
@ -6826,7 +6957,7 @@ call_dma_setup:
KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero transfer\n"));
use_dma = FALSE;
AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
if(!deviceExtension->opt_AtapiDmaZeroTransfer) {
if(!deviceExtension->opt_AtapiDmaZeroTransfer && !(deviceExtension->HwFlags & UNIATA_SATA)) {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit() to PIO\n"));
AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
}
@ -7003,8 +7134,15 @@ make_reset:
KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n",
statusByte));
AtapiWritePort1(chan, IDX_IO1_o_Feature,
use_dma ? ATA_F_DMA : 0);
if(use_dma) {
FeatureReg |= ATA_F_DMA;
if(LunExt->IdentifyData.AtapiDMA.DMADirRequired &&
(Srb->SrbFlags & SRB_FLAGS_DATA_IN)) {
FeatureReg |= ATA_F_DMAREAD;
}
}
AtapiWritePort1(chan, IDX_IO1_o_Feature, FeatureReg);
// Write transfer byte count to registers.
byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF);
@ -7153,6 +7291,7 @@ IdeSendCommand(
UCHAR statusByte,errorByte;
ULONG status;
ULONG i;
ULONGLONG lba;
PMODE_PARAMETER_HEADER modeData;
//ULONG ldev;
ULONG DeviceNumber;
@ -7196,27 +7335,39 @@ IdeSendCommand(
if(AtaReq->ReqState < REQ_STATE_PREPARE_TO_TRANSFER)
AtaReq->ReqState = REQ_STATE_PREPARE_TO_TRANSFER;
cdb = (PCDB)(Srb->Cdb);
if(CmdAction == CMD_ACTION_PREPARE) {
switch (Srb->Cdb[0]) {
case SCSIOP_SERVICE_ACTION16:
if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
// ok
} else {
goto default_no_prep;
}
#ifdef NAVO_TEST
case SCSIOP_INQUIRY: // now it requires device access
#endif //NAVO_TEST
case SCSIOP_READ_CAPACITY:
case SCSIOP_READ:
case SCSIOP_WRITE:
case SCSIOP_READ12:
case SCSIOP_WRITE12:
case SCSIOP_READ16:
case SCSIOP_WRITE16:
case SCSIOP_REQUEST_SENSE:
// all right
KdPrint2((PRINT_PREFIX "** Ide: Command continue prep\n"));
SetCheckPoint(50);
break;
default:
default_no_prep:
SetCheckPoint(0);
KdPrint2((PRINT_PREFIX "** Ide: Command break prep\n"));
return SRB_STATUS_BUSY;
}
}
cdb = (PCDB)(Srb->Cdb);
SetCheckPoint(0x100 | Srb->Cdb[0]);
switch (Srb->Cdb[0]) {
case SCSIOP_INQUIRY:
@ -7427,6 +7578,7 @@ IdeSendCommand(
// Claim 512 byte blocks (big-endian).
//((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
i = DEV_BSIZE;
RtlZeroMemory(Srb->DataBuffer, sizeof(READ_CAPACITY_DATA));
MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock, i );
// Calculate last sector.
@ -7454,7 +7606,48 @@ IdeSendCommand(
status = SRB_STATUS_SUCCESS;
break;
case SCSIOP_SERVICE_ACTION16:
if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
KdPrint2((PRINT_PREFIX
"** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->PathId, Srb->Lun, Srb->TargetId));
// Claim 512 byte blocks (big-endian).
//((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
i = DEV_BSIZE;
RtlZeroMemory(Srb->DataBuffer, sizeof(READ_CAPACITY16_DATA));
MOV_DD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->BytesPerBlock, i );
// Calculate last sector.
if(!(lba = LunExt->NumOfSectors)) {
lba = LunExt->IdentifyData.SectorsPerTrack *
LunExt->IdentifyData.NumberOfHeads *
LunExt->IdentifyData.NumberOfCylinders;
}
i--;
//((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress =
// (((PUCHAR)&i)[0] << 24) | (((PUCHAR)&i)[1] << 16) |
// (((PUCHAR)&i)[2] << 8) | ((PUCHAR)&i)[3];
MOV_QD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->LogicalBlockAddress, i );
KdPrint2((PRINT_PREFIX
"** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x (16)\n",
Srb->TargetId,
LunExt->IdentifyData.SectorsPerTrack,
LunExt->IdentifyData.NumberOfHeads,
LunExt->IdentifyData.NumberOfCylinders));
status = SRB_STATUS_SUCCESS;
} else {
goto default_abort;
}
break;
case SCSIOP_VERIFY:
case SCSIOP_VERIFY12:
case SCSIOP_VERIFY16:
KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_VERIFY PATH:LUN:TID = %#x:%#x:%#x\n",
@ -7465,13 +7658,19 @@ IdeSendCommand(
case SCSIOP_READ:
case SCSIOP_WRITE:
case SCSIOP_READ12:
case SCSIOP_WRITE12:
case SCSIOP_READ16:
case SCSIOP_WRITE16:
KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_%s PATH:LUN:TID = %#x:%#x:%#x\n",
(Srb->Cdb[0] == SCSIOP_WRITE) ? "WRITE" : "READ",
Srb->PathId, Srb->Lun, Srb->TargetId));
AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE) ? REQ_FLAG_WRITE : REQ_FLAG_READ;
AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
Srb->Cdb[0] == SCSIOP_WRITE12 ||
Srb->Cdb[0] == SCSIOP_WRITE16) ? REQ_FLAG_WRITE : REQ_FLAG_READ;
status = IdeReadWrite(HwDeviceExtension,
Srb, CmdAction);
break;
@ -7717,7 +7916,7 @@ passthrough_err:
}
default:
default_abort:
KdPrint2((PRINT_PREFIX
"IdeSendCommand: Unsupported command %#x\n",
Srb->Cdb[0]));
@ -8128,6 +8327,9 @@ reject_srb:
break;
//}
}
} else {
KdPrint2((PRINT_PREFIX
" SRB %#x, CDB %#x, AtaReq %#x, SCmd %#x\n", Srb, &(Srb->Cdb), Srb->SrbExtension, Srb->Cdb[0]));
}
/*
__try {
@ -8177,7 +8379,7 @@ reject_srb:
} else {
// Send command to device.
KdPrint2((PRINT_PREFIX "Send to device\n"));
KdPrint2((PRINT_PREFIX "Send to device %x\n", Srb->Cdb[0]));
if(TopLevel) {
KdPrint2((PRINT_PREFIX "TopLevel (2), srb %#x\n", Srb));
AtaReq = (PATA_REQ)(Srb->SrbExtension);
@ -8216,7 +8418,7 @@ reject_srb:
if(atapiDev &&
(Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) {
KdPrint3((PRINT_PREFIX "Try ATAPI send\n"));
KdPrint3((PRINT_PREFIX "Try ATAPI send %x\n", Srb->Cdb[0]));
status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
} else {
KdPrint2((PRINT_PREFIX "Try IDE send\n"));
@ -9526,7 +9728,8 @@ DriverEntry(
hwInitializationData.comm.DeviceIdLength = 0;
if(!BMListLen) {
hwInitializationData.comm.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, ata);
hwInitializationData.comm.SrbExtensionSize = //FIELD_OFFSET(ATA_REQ, ata);
sizeof(ATA_REQ);
KdPrint2((PRINT_PREFIX "using AtaReq sz %x\n", hwInitializationData.comm.SrbExtensionSize));
}
@ -9904,7 +10107,9 @@ AtapiRegCheckParameterValue(
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
paramPath.Buffer, parameters, NULL, NULL);
KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
if(NT_SUCCESS(status)) {
KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
}
ExFreePool(paramPath.Buffer);

View file

@ -803,7 +803,8 @@ AtapiDmaInit__(
IN PHW_LU_EXTENSION LunExt
)
{
if(LunExt->IdentifyData.SupportDma) {
if(LunExt->IdentifyData.SupportDma ||
(LunExt->IdentifyData.AtapiDMA.DMASupport && (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE))) {
KdPrint2((PRINT_PREFIX
"AtapiDmaInit__: Set (U)DMA on Device %d\n", LunExt->Lun));
/* for(i=AtaUmode(&(LunExt->IdentifyData)); i>=0; i--) {

View file

@ -2368,11 +2368,14 @@ AtapiSetupLunPtrs(
KdPrint2((PRINT_PREFIX "Achtung !deviceExtension->NumberLuns \n"));
deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN;
}
KdPrint2((PRINT_PREFIX " Chan %#x\n", chan));
chan->DeviceExtension = deviceExtension;
chan->lChannel = c;
chan->NumberLuns = deviceExtension->NumberLuns;
for(i=0; i<deviceExtension->NumberLuns; i++) {
chan->lun[i] = &(deviceExtension->lun[c*deviceExtension->NumberLuns+i]);
KdPrint2((PRINT_PREFIX " Lun %#x\n", i));
KdPrint2((PRINT_PREFIX " Lun ptr %#x\n", chan->lun[i]));
}
chan->AltRegMap = deviceExtension->AltRegMap;
chan->NextDpcChan = -1;
@ -2403,7 +2406,7 @@ UniataAllocateLunExt(
PHW_LU_EXTENSION old_luns = NULL;
PHW_CHANNEL old_chans = NULL;
KdPrint2((PRINT_PREFIX "allocate %d Luns for %d channels\n", deviceExtension->lun, deviceExtension->NumberChannels));
KdPrint2((PRINT_PREFIX "allocate %d Luns for %d channels\n", deviceExtension->NumberLuns, deviceExtension->NumberChannels));
old_luns = deviceExtension->lun;
old_chans = deviceExtension->chan;

View file

@ -1385,11 +1385,11 @@ UniataFindBusMasterController(
KdPrint2((PRINT_PREFIX "update ConfigInfo->nt4\n"));
_ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
_ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
if(deviceExtension->HwFlags & UNIATA_AHCI) {
//if(deviceExtension->HwFlags & UNIATA_AHCI) {
_ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ);
} else {
_ConfigInfo->nt4.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, dma_tab) + sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
}
//} else {
// _ConfigInfo->nt4.SrbExtensionSize = FIELD_OFFSET(ATA_REQ, dma_tab) + sizeof(BM_DMA_ENTRY)*ATA_DMA_ENTRIES;
//}
KdPrint2((PRINT_PREFIX "using AtaReq sz %x\n", _ConfigInfo->nt4.SrbExtensionSize));
}
if((WinVer_Id() > WinVer_2k) ||

View file

@ -772,13 +772,23 @@ UniataAhciDetect(
CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x\n", CAP, CAP2));
if(CAP & AHCI_CAP_S64A) {
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
KdPrint2((PRINT_PREFIX " 64bit"));
//deviceExtension->Host64 = TRUE;
}
if(CAP2 & AHCI_CAP2_BOH) {
BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
KdPrint2((PRINT_PREFIX " AHCI BOHC %#x\n", BOHC));
KdPrint2((PRINT_PREFIX " BOHC %#x", BOHC));
}
if(CAP & AHCI_CAP_NCQ) {
KdPrint2((PRINT_PREFIX " NCQ"));
}
if(CAP & AHCI_CAP_SNTF) {
KdPrint2((PRINT_PREFIX " SNTF"));
}
if(CAP & AHCI_CAP_CCC) {
KdPrint2((PRINT_PREFIX " CCC"));
}
KdPrint2((PRINT_PREFIX "\n"));
/* get the number of HW channels */
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
@ -787,6 +797,7 @@ UniataAhciDetect(
NumberChannels =
max((CAP & AHCI_CAP_NOP_MASK)+1, n);
KdPrint2((PRINT_PREFIX " CommandSlots %d\n", (CAP & AHCI_CAP_NCS_MASK)>>8 ));
KdPrint2((PRINT_PREFIX " Channels %d\n", n));
switch(deviceExtension->DevID) {
@ -871,7 +882,7 @@ UniataAhciStatus(
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
ULONG Channel = deviceExtension->Channel + lChannel;
ULONG hIS;
ULONG CI;
ULONG CI, ACT;
AHCI_IS_REG IS;
SATA_SSTATUS_REG SStatus;
SATA_SERROR_REG SError;
@ -888,6 +899,7 @@ UniataAhciStatus(
}
IS.Reg = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_IS);
CI = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CI);
ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
@ -896,8 +908,8 @@ UniataAhciStatus(
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg);
AtapiWritePort4(chan, IDX_SATA_SError, SError.Reg);
KdPrint((" AHCI: istatus=%08x sstatus=%08x serror=%08x CI=%08x\n",
IS.Reg, SStatus.Reg, SError.Reg, CI));
KdPrint((" AHCI: is=%08x ss=%08x serror=%08x CI=%08x, ACT=%08x\n",
IS.Reg, SStatus.Reg, SError.Reg, CI, ACT));
/* do we have cold connect surprise */
if(IS.CPDS) {
@ -1059,6 +1071,7 @@ UniataAhciWaitCommandReady(
)
{
AHCI_IS_REG IS;
//ULONG ACT;
ULONG CI=0;
ULONG i;
ULONG SError;
@ -1068,7 +1081,8 @@ UniataAhciWaitCommandReady(
for (i=0; i<timeout; i++) {
CI = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CI);
if (!((CI >> tag) & 0x01)) {
//ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
if (!(( CI >> tag) & 0x01)) {
break;
}
IS.Reg = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_IS);
@ -1146,6 +1160,7 @@ UniataAhciSendCommand(
KdPrint2((PRINT_PREFIX " AHCI CMD address is not aligned (mask %#x)\n", (ULONG)AHCI_CMD_ALIGNEMENT_MASK));
}
//UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 1 << tag);
return UniataAhciWaitCommandReady(chan, timeout);
@ -1269,6 +1284,28 @@ UniataAhciSendPIOCommand(
} // end UniataAhciSendPIOCommand()
BOOLEAN
NTAPI
UniataAhciAbortOperation(
IN PHW_CHANNEL chan
)
{
/* kick controller into sane state */
if(!UniataAhciStop(chan)) {
return FALSE;
}
if(!UniataAhciStopFR(chan)) {
return FALSE;
}
if(!UniataAhciCLO(chan)) {
return FALSE;
}
UniataAhciStartFR(chan);
UniataAhciStart(chan);
return TRUE;
} // end UniataAhciAbortOperation()
ULONG
NTAPI
UniataAhciSoftReset(
@ -1290,18 +1327,11 @@ UniataAhciSoftReset(
PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
#ifdef DBG
// UniataDumpAhciPortRegs(chan);
#endif // DBG
/* kick controller into sane state */
UniataAhciStop(chan);
UniataAhciCLO(chan);
UniataAhciStart(chan);
#ifdef DBG
// UniataDumpAhciPortRegs(chan);
#endif // DBG
if(!UniataAhciAbortOperation(chan)) {
KdPrint2((" abort failed\n"));
return (ULONG)(-1);
}
/* pull reset active */
RtlZeroMemory(AHCI_CMD->cfis, sizeof(AHCI_CMD->cfis));
@ -1523,7 +1553,7 @@ UniataAhciStartFR(
return;
} // end UniataAhciStartFR()
VOID
BOOLEAN
NTAPI
UniataAhciStopFR(
IN PHW_CHANNEL chan
@ -1542,14 +1572,14 @@ UniataAhciStopFR(
CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
if(!(CMD & ATA_AHCI_P_CMD_FR)) {
KdPrint2((" final CMD %#x\n", CMD));
return;
return TRUE;
}
AtapiStallExecution(1000);
}
KdPrint2((" CMD %#x\n", CMD));
KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
KdPrint2(("UniataAhciStopFR: timeout\n"));
return;
return FALSE;
} // end UniataAhciStopFR()
VOID
@ -1582,7 +1612,7 @@ UniataAhciStart(
return;
} // end UniataAhciStart()
VOID
BOOLEAN
NTAPI
UniataAhciCLO(
IN PHW_CHANNEL chan
@ -1600,7 +1630,7 @@ UniataAhciCLO(
//CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
CAP = chan->DeviceExtension->AHCI_CAP;
if(!(CAP & AHCI_CAP_SCLO)) {
return;
return TRUE;
}
KdPrint2((" send CLO\n"));
CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
@ -1611,16 +1641,16 @@ UniataAhciCLO(
CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
if(!(CMD & ATA_AHCI_P_CMD_CLO)) {
KdPrint2((" final CMD %#x\n", CMD));
return;
return TRUE;
}
AtapiStallExecution(1000);
}
KdPrint2((" CMD %#x\n", CMD));
KdPrint2(("UniataAhciCLO: timeout\n"));
return;
return FALSE;
} // end UniataAhciCLO()
VOID
BOOLEAN
NTAPI
UniataAhciStop(
IN PHW_CHANNEL chan
@ -1641,14 +1671,14 @@ UniataAhciStop(
CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
if(!(CMD & ATA_AHCI_P_CMD_CR)) {
KdPrint2((" final CMD %#x\n", CMD));
return;
return TRUE;
}
AtapiStallExecution(1000);
}
KdPrint2((" CMD %#x\n", CMD));
KdPrint((" SError %#x\n", AtapiReadPort4(chan, IDX_SATA_SError)));
KdPrint2(("UniataAhciStop: timeout\n"));
return;
return FALSE;
} // end UniataAhciStop()
UCHAR
@ -1664,7 +1694,7 @@ UniataAhciBeginTransaction(
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
//ULONG Channel = deviceExtension->Channel + lChannel;
//ULONG hIS;
ULONG CMD;
ULONG CMD, CMD0;
//AHCI_IS_REG IS;
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
//SATA_SSTATUS_REG SStatus;
@ -1712,20 +1742,24 @@ UniataAhciBeginTransaction(
AHCI_CL->cmd_table_phys));
#endif // DBG
CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
CMD0 = CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
KdPrint2((" CMD %#x\n", CMD));
// switch controller to ATAPI mode for ATA_PACKET commands only
if(ATAPI_DEVICE(chan, DeviceNumber) &&
AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_PACKET) {
KdPrint2((" ATAPI\n"));
CMD |= ATA_AHCI_P_CMD_ATAPI;
KdDump(&(AtaReq->ahci.ahci_cmd_ptr->acmd), 16);
} else {
CMD &= ~ATA_AHCI_P_CMD_ATAPI;
}
KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
if(CMD0 != CMD) {
KdPrint2((" send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
}
/* issue command to controller */
//UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 0x01 << tag);
chan->AhciPrevCI |= 0x01 << tag;
@ -1770,7 +1804,7 @@ UniataAhciEndTransaction(
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
//ULONG Channel = deviceExtension->Channel + lChannel;
//ULONG hIS;
ULONG CI;
ULONG CI, ACT;
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
ULONG TFD;
PUCHAR RCV_FIS = &(chan->AhciCtlBlock->rcv_fis.rfis[0]);
@ -1809,7 +1843,7 @@ UniataAhciEndTransaction(
((ULONGLONG)(RCV_FIS[7] & 0x0f) << 24);
}
AtaReq->WordsTransfered = AHCI_CL->bytecount/2;
/*
if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
KdPrint2(("RCV:\n"));
KdDump(RCV_FIS, 24);
@ -1821,18 +1855,20 @@ UniataAhciEndTransaction(
AtaReq->WordsTransfered = ((ULONG)RCV_FIS[5] | ((ULONG)RCV_FIS[6] << 8)) / 2;
}
}
*/
ACT = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_ACT);
CI = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CI);
if(CI & (1 << tag)) {
// clear CI
KdPrint2((" Incomplete command, CI %#x\n", CI));
KdPrint2((" Incomplete command, CI %#x, ACT %#x\n", CI, ACT));
KdPrint2((" FIS status %#x, error %#x\n", RCV_FIS[2], RCV_FIS[3]));
#if DBG
UniataDumpAhciPortRegs(chan);
#endif
UniataAhciStop(chan);
UniataAhciStart(chan);
if(!UniataAhciAbortOperation(chan)) {
KdPrint2((" Abort failed, need RESET\n"));
}
#if DBG
UniataDumpAhciPortRegs(chan);
#endif

View file

@ -195,6 +195,12 @@ UniataAhciSendPIOCommand(
IN ULONG timeout
);
BOOLEAN
NTAPI
UniataAhciAbortOperation(
IN PHW_CHANNEL chan
);
ULONG
NTAPI
UniataAhciSoftReset(
@ -231,7 +237,7 @@ UniataAhciStartFR(
IN PHW_CHANNEL chan
);
VOID
BOOLEAN
NTAPI
UniataAhciStopFR(
IN PHW_CHANNEL chan
@ -243,13 +249,13 @@ UniataAhciStart(
IN PHW_CHANNEL chan
);
VOID
BOOLEAN
NTAPI
UniataAhciCLO(
IN PHW_CHANNEL chan
);
VOID
BOOLEAN
NTAPI
UniataAhciStop(
IN PHW_CHANNEL chan

View file

@ -8,6 +8,7 @@
#define MOV_DD_SWP(a,b) ((a) = RtlUlongByteSwap(*(PULONG)&(b)))
#define MOV_DW_SWP(a,b) ((a) = RtlUshortByteSwap(*(PUSHORT)&(b)))
#define MOV_SWP_DW2DD(a,b) ((a) = RtlUshortByteSwap(*(PUSHORT)&(b)))
#define MOV_QD_SWP(a,b) { ((PULONG)&(a))[0] = RtlUlongByteSwap( ((PULONG)&(b))[1]); ((PULONG)&(a))[1] = RtlUlongByteSwap( ((PULONG)&(b))[0]); }
#else
@ -37,6 +38,32 @@ _MOV_DD_SWP_i386(
/********************/
typedef void
(__fastcall *ptrMOV_QD_SWP)(
void* a, // ECX
void* b // EDX
);
extern "C" ptrMOV_QD_SWP _MOV_QD_SWP;
extern "C"
void
__fastcall
_MOV_QD_SWP_i486(
void* a, // ECX
void* b // EDX
);
extern "C"
void
__fastcall
_MOV_QD_SWP_i386(
void* a, // ECX
void* b // EDX
);
#define MOV_QD_SWP(a,b) _MOV_QD_SWP(&(a),&(b))
/********************/
extern "C"
void
__fastcall

View file

@ -145,6 +145,14 @@ typedef union _CDB {
UCHAR Control;
} CDB10, *PCDB10;
// Service Action 16-byte CDB
struct _SERVICE_ACTION16 {
UCHAR OperationCode; // 0x9E
UCHAR ServiceAction : 5;
UCHAR Reserved1 : 3;
UCHAR Data[14];
} SERVICE_ACTION16, *PSERVICE_ACTION16;
// CD Rom Audio CDBs
#define PauseResume_Pause 0x00
@ -723,6 +731,26 @@ typedef union _CDB {
UCHAR Reserved1[2];
} CDB12READWRITE, *PCDB12READWRITE;
struct _CDB16READWRITE {
UCHAR OperationCode;
union {
UCHAR Flags;
struct {
UCHAR RELADR : 1;
UCHAR Reserved0 : 2;
UCHAR FUA : 1;
UCHAR DPO : 1;
UCHAR Reserved1 : 3;
} Fields;
} Byte1;
UCHAR LBA [8];
UCHAR NumOfBlocks [4];
UCHAR GroupNumber:5;
UCHAR Reserved14_5_6:2;
UCHAR Restricted:1; // MMC-4
UCHAR Reserved1[1];
} CDB16READWRITE, *PCDB16READWRITE;
// Plextor Read CD-DA
struct _PLXTR_READ_CDDA {
UCHAR OperationCode;
@ -866,6 +894,13 @@ typedef union _CDB {
#define SCSIOP_CLOSE_TRACK_SESSION 0x5B
#define SCSIOP_READ_BUFFER_CAPACITY 0x5C
#define SCSIOP_SEND_CUE_SHEET 0x5D
#define SCSIOP_READ16 0x88
#define SCSIOP_WRITE16 0x8A
#define SCSIOP_VERIFY16 0x8F
#define SCSIOP_SERVICE_ACTION16 0x9E
#define SCSIOP_SA_READ_CAPACITY16 0x10
#define SCSIOP_BLANK 0xA1
#define SCSIOP_SEND_KEY 0xA3
#define SCSIOP_REPORT_KEY 0xA4
@ -874,6 +909,7 @@ typedef union _CDB {
#define SCSIOP_SET_READ_AHEAD 0xA7
#define SCSIOP_READ12 0xA8
#define SCSIOP_WRITE12 0xAA
#define SCSIOP_VERIFY12 0xAF
#define SCSIOP_SEEK12 0xAB
#define SCSIOP_GET_PERFORMANCE 0xAC
#define SCSIOP_READ_DVD_STRUCTURE 0xAD
@ -1365,6 +1401,15 @@ typedef struct _READ_CAPACITY_DATA {
ULONG BytesPerBlock;
} READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA;
typedef struct _READ_CAPACITY16_DATA {
ULONGLONG LogicalBlockAddress;
ULONG BytesPerBlock;
UCHAR Prot_EN:1;
UCHAR RTO_EN:1;
UCHAR Reserved:6;
UCHAR Reserved1[20];
} READ_CAPACITY16_DATA, *PREAD_CAPACITY16_DATA;
// CD ROM Read Table Of Contents (TOC) structures
// Format 0 - Get table of contents

View file

@ -1,10 +1,10 @@
#define UNIATA_VER_STR "42e2"
#define UNIATA_VER_DOT 0.42.5.2
#define UNIATA_VER_STR "42h"
#define UNIATA_VER_DOT 0.42.8.0
#define UNIATA_VER_MJ 0
#define UNIATA_VER_MN 42
#define UNIATA_VER_SUB_MJ 5
#define UNIATA_VER_SUB_MN 2
#define UNIATA_VER_DOT_COMMA 0,42,5,2
#define UNIATA_VER_DOT_STR "0.42.5.2"
#define UNIATA_VER_SUB_MJ 8
#define UNIATA_VER_SUB_MN 0
#define UNIATA_VER_DOT_COMMA 0,42,8,0
#define UNIATA_VER_DOT_STR "0.42.8.0"
#define UNIATA_VER_YEAR 2012
#define UNIATA_VER_YEAR_STR "2012"