/*++
-Copyright (c) 2002-2007 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2008 Alexandr A. Telyatnikov (Alter)
Module Name:
id_ata.cpp
7. XP support (binary compatibility)
8. Serial ATA (SATA/SATA2) support
9. NT 3.51 support (binary compatibility)
-
+
etc. (See todo.txt)
static const CHAR ver_string[] = "\n\nATAPI IDE MiniPort Driver (UniATA) v 0." UNIATA_VER_STR "\n";
+static const CHAR uniata_comm_name[] = UNIATA_COMM_PORT_VENDOR_STR " \n";
+
UNICODE_STRING SavedRegPath;
WCHAR SavedRegPathBuffer[256];
BOOLEAN g_opt_Verbose = 0;
+BOOLEAN WinVer_WDM_Model = FALSE;
//UCHAR EnableDma = FALSE;
//UCHAR EnableReorder = FALSE;
);
VOID
+NTAPI
AtapiHwInitialize__(
IN PHW_DEVICE_EXTENSION deviceExtension,
IN ULONG lChannel
);
VOID
+NTAPI
AtapiQueueTimerDpc(
IN PVOID HwDeviceExtension,
IN ULONG lChannel,
#endif //UNIATA_CORE
BOOLEAN
+NTAPI
AtapiCheckInterrupt__(
IN PVOID HwDeviceExtension,
IN UCHAR c
#ifndef UNIATA_CORE
BOOLEAN
+NTAPI
AtapiRegGetStringParameterValue(
IN PWSTR RegistryPath,
IN PWSTR Name,
LONGLONG t;
LARGE_INTEGER t0;
+#ifdef NAVO_TEST
+ return;
+#endif //NAVO_TEST
+
if(!nano || !g_Perf || !g_PerfDt)
return;
t = (g_Perf * nano) / g_PerfDt / 1000;
//AtapiReadPortExN_template(USHORT, Ushort, 2);
AtapiReadPortExN_template(UCHAR, Uchar, 1);
-#define AtapiReadPortBufferN_template(type, Type, sz) \
+#define AtapiReadPortBufferN_template(_type, _Type, sz) \
VOID \
DDKFASTAPI \
AtapiReadBuffer##sz( \
IN ULONG Timing \
) \
{ \
- ULONG i=0; \
+ PIORES res; \
+ \
+ if(Timing) { \
+ while(Count) { \
+ (*((_type*)Buffer)) = AtapiReadPort##sz(chan, _port); \
+ Count--; \
+ Buffer = ((_type*)Buffer)+1; \
+ UniataNanoSleep(Timing); \
+ } \
+ return; \
+ } \
+ \
+ if(_port >= IDX_MAX_REG) { \
+ res = (PIORES)(_port); \
+ } else \
+ if(chan) { \
+ res = &chan->RegTranslation[_port]; \
+ } else { \
+ KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \
+ return; \
+ } \
+ if(!res->MemIo) { \
+ /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
+ ScsiPortReadPortBuffer##_Type((_type*)(res->Addr), (_type*)Buffer, Count); \
+ return; \
+ } \
while(Count) { \
- ((type*)Buffer)[i] = AtapiReadPort##sz(chan, _port); \
- i++; \
+ (*((_type*)Buffer)) = ScsiPortReadRegister##_Type((_type*)(res->Addr)); \
Count--; \
- UniataNanoSleep(Timing); \
+ Buffer = ((_type*)Buffer)+1; \
} \
return; \
}
-#define AtapiWritePortBufferN_template(type, Type, sz) \
+#define AtapiWritePortBufferN_template(_type, _Type, sz) \
VOID \
DDKFASTAPI \
AtapiWriteBuffer##sz( \
IN ULONG Timing \
) \
{ \
- ULONG i=0; \
+ PIORES res; \
+ \
+ if(Timing) { \
+ while(Count) { \
+ AtapiWritePort##sz(chan, _port, *((_type*)Buffer)); \
+ Buffer = ((_type*)Buffer)+1; \
+ Count--; \
+ UniataNanoSleep(Timing); \
+ } \
+ return; \
+ } \
+ \
+ if(_port >= IDX_MAX_REG) { \
+ res = (PIORES)(_port); \
+ } else \
+ if(chan) { \
+ res = &chan->RegTranslation[_port]; \
+ } else { \
+ KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \
+ return; \
+ } \
+ if(!res->MemIo) { \
+ /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
+ ScsiPortWritePortBuffer##_Type((_type*)(res->Addr), (_type*)Buffer, Count); \
+ return; \
+ } \
while(Count) { \
- AtapiWritePort##sz(chan, _port, ((type*)Buffer)[i]); \
- i++; \
+ ScsiPortWriteRegister##_Type((_type*)(res->Addr), *((_type*)Buffer)); \
Count--; \
- UniataNanoSleep(Timing); \
+ Buffer = ((_type*)Buffer)+1; \
} \
return; \
}
return Status;
}
// if(deviceExtension->HwFlags & UNIATA_SATA) {
- if(deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(UniataIsSATARangeAvailable(deviceExtension, 0)) {
if(Status & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
return Status;
}
ULONG DeviceNumber
)
{
- ULONG c = chan->lChannel;
- ULONG i;
+ //ULONG c = chan->lChannel;
+ ULONG i = 30 * 1000;
UCHAR dma_status = 0;
KdPrint2((PRINT_PREFIX "AtapiSoftReset:\n"));
UCHAR statusByte2;
SelectDrive(chan, DeviceNumber);
AtapiStallExecution(10000);
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
- for (i = 0; i < 1000; i++) {
- AtapiStallExecution(999);
+
+ // 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
+ // implementation. (which is around 1 second)
+ while ((AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) &&
+ i--)
+ {
+ AtapiStallExecution(30);
}
+
SelectDrive(chan, DeviceNumber);
WaitOnBusy(chan);
GetBaseStatus(chan, statusByte2);
Translate to 48-Lba form if required
*/
UCHAR
+NTAPI
AtaCommand48(
IN PHW_DEVICE_EXTENSION deviceExtension,
IN ULONG DeviceNumber,
//>>>>>> NV: 2006/08/03
if((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) &&
CheckIfBadBlock(&(deviceExtension->lun[ldev]), lba, count)) {
- KdPrint2((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
+ KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
return IDE_STATUS_ERROR;
//return SRB_STATUS_ERROR;
}
chan->ChannelCtrlFlags |= CTRFLAGS_LBA48;
plba = (PUCHAR)&lba;
- AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)(feature>>8) & 0xff);
+ AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)(feature>>8));
AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)feature);
- AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)(count>>8) & 0xff);
- AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)count & 0xff);
+ AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)(count>>8));
+ AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)count);
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[3]));
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[0]));
AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[4]));
AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) );
} else {
+ plba = (PUCHAR)&lba; //ktp
chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
//if(feature ||
AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)feature);
//}
AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)count);
- AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)lba & 0xff);
- AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(lba>>8) & 0xff);
- AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(lba>>16) & 0xff);
+ AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)plba[0]);
+ AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)plba[1]);
+ AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)plba[2]);
if(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_LBA_ENABLED) {
//KdPrint2((PRINT_PREFIX "AtaCommand28: ldev %#x USE_LBA\n", ldev ));
- AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)((lba>>24) & 0xf) | IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) );
+ AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)(plba[3] & 0xf) | IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) );
} else {
//KdPrint2((PRINT_PREFIX "AtaCommand28: ldev %#x USE_CHS\n", ldev ));
- AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)((lba>>24) & 0xf) | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) );
+ AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)(plba[3] & 0xf) | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) );
}
}
break;
} else {
//if(deviceExtension->HwFlags & UNIATA_SATA) {
- if(deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
break;
}
AtapiStallExecution(100);
This is simply wrapper for AtaCommand48()
*/
UCHAR
+NTAPI
AtaCommand(
IN PHW_DEVICE_EXTENSION deviceExtension,
IN ULONG DeviceNumber,
IN UCHAR command,
IN USHORT cylinder,
IN UCHAR head,
- IN UCHAR sector,
+ IN UCHAR sector,
IN UCHAR count,
IN UCHAR feature,
IN ULONG flags
)
{
return AtaCommand48(deviceExtension, DeviceNumber, lChannel,
- command,
+ command,
(ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
count, feature, flags);
} // end AtaCommand()
LONG
+NTAPI
AtaPio2Mode(LONG pio)
{
switch (pio) {
} // end AtaPio2Mode()
LONG
+NTAPI
AtaPioMode(PIDENTIFY_DATA2 ident)
{
if (ident->PioTimingsValid) {
return 5;
if (ident->AdvancedPIOModes & AdvancedPIOModes_4)
return 4;
- if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
+ if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
return 3;
- }
+ }
if (ident->PioCycleTimingMode == 2)
return 2;
if (ident->PioCycleTimingMode == 1)
return 1;
if (ident->PioCycleTimingMode == 0)
return 0;
- return -1;
+ return -1;
} // end AtaPioMode()
LONG
+NTAPI
AtaWmode(PIDENTIFY_DATA2 ident)
{
if (ident->MultiWordDMASupport & 0x04)
} // end AtaWmode()
LONG
+NTAPI
AtaUmode(PIDENTIFY_DATA2 ident)
{
if (!ident->UdmaModesValid)
KdPrint2((PRINT_PREFIX "AtapiTimerDpc:\n"));
lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan;
- if(lChannel == -1) {
+ if(lChannel == CHAN_NOT_SPECIFIED) {
KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no items\n"));
return;
}
chan->HwScsiTimer = NULL;
deviceExtension->FirstDpcChan = chan->NextDpcChan;
- if(deviceExtension->FirstDpcChan != -1) {
+ if(deviceExtension->FirstDpcChan != CHAN_NOT_SPECIFIED) {
recall = TRUE;
}
HwScsiTimer(HwDeviceExtension);
- chan->NextDpcChan = -1;
+ chan->NextDpcChan = CHAN_NOT_SPECIFIED;
lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan;
- if(lChannel == -1) {
+ if(lChannel == CHAN_NOT_SPECIFIED) {
KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no more items\n"));
deviceExtension->FirstDpcChan =
- deviceExtension->ActiveDpcChan = -1;
+ deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED;
return;
}
}
if(recall) {
- deviceExtension->ActiveDpcChan = -1;
+ deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED;
MiniportTimerValue = (ULONG)(time.QuadPart - chan->DpcTime)/10;
if(!MiniportTimerValue)
MiniportTimerValue = 1;
cancels previous Dpc request (if any), but we need Dpc queue.
*/
VOID
+NTAPI
AtapiQueueTimerDpc(
IN PVOID HwDeviceExtension,
IN ULONG lChannel,
i = deviceExtension->FirstDpcChan;
chan = prev_chan = NULL;
- while(i != -1) {
+ while(i != CHAN_NOT_SPECIFIED) {
prev_chan = chan;
chan = &deviceExtension->chan[i];
if(chan->DpcTime > time.QuadPart) {
#endif //UNIATA_CORE
VOID
+NTAPI
UniataDumpATARegs(
IN PHW_CHANNEL chan
)
for(j=1; j<IDX_IO1_SZ; j++) {
statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
" Reg_%#x (%#x) = %#x\n",
j,
chan->RegTranslation[IDX_IO1+j].Addr,
}
for(j=0; j<IDX_BM_IO_SZ-1; j++) {
statusByteAlt = AtapiReadPort1(chan, IDX_BM_IO+j);
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
" BM_%#x (%#x) = %#x\n",
j,
chan->RegTranslation[IDX_BM_IO+j].Addr,
--*/
BOOLEAN
+NTAPI
IssueIdentify(
IN PVOID HwDeviceExtension,
IN ULONG DeviceNumber,
KdPrint2((PRINT_PREFIX "IssueIdentify: NO SLAVE\n"));
return FALSE;
}
+ if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
+ KdPrint2((PRINT_PREFIX "IssueIdentify: HIDDEN\n"));
+ return FALSE;
+ }
SelectDrive(chan, DeviceNumber);
AtapiStallExecution(10);
KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte != IDE_STATUS_IDLE\n"));
//if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
- if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
SelectDrive(chan, DeviceNumber);
WaitOnBusyLong(chan);
} else {
KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI. Status (%#x)\n", statusByte));
//if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
- if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
statusByte = WaitForIdleLong(chan);
KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI (2). Status (%#x)\n", statusByte));
}
}
// if(deviceExtension->HwFlags & UNIATA_SATA) {
- if(deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
j = 4;
} else {
j = 0;
KdPrint2((PRINT_PREFIX "IssueIdentify: BASE statusByte %#x\n", statusByte));
if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
-
+
KdPrint2((PRINT_PREFIX " use 16bit IO\n"));
#if 0
USHORT w;
// 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 the way you see below.
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
" IO_%#x (%#x), %s:\n",
IDX_IO1_i_Data,
chan->RegTranslation[IDX_IO1_i_Data].Addr,
chan->RegTranslation[IDX_IO1_i_Data].MemIo ? "Mem" : "IO"));
for(i=0; i<256; i++) {
/*
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
" IO_%#x (%#x):\n",
IDX_IO1_i_Data,
chan->RegTranslation[IDX_IO1_i_Data].Addr));
*/
w = AtapiReadPort2(chan, IDX_IO1_i_Data);
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
" %x\n", w));
AtapiStallExecution(1);
((PUSHORT)&deviceExtension->FullIdentifyData)[i] = w;
ULONGLONG cylinders=0;
ULONGLONG tmp_cylinders=0;
// Read very-old-style drive geometry
- KdPrint2((PRINT_PREFIX "CHS %#x:%#x:%#x\n",
+ KdPrint2((PRINT_PREFIX "CHS %#x:%#x:%#x\n",
deviceExtension->FullIdentifyData.NumberOfCylinders,
deviceExtension->FullIdentifyData.NumberOfHeads,
deviceExtension->FullIdentifyData.SectorsPerTrack
/* (deviceExtension->FullIdentifyData.TranslationFieldsValid) &&*/
(NumOfSectors < deviceExtension->FullIdentifyData.UserAddressableSectors)) {
KdPrint2((PRINT_PREFIX "NumberOfCylinders == 0x3fff\n"));
- cylinders =
+ cylinders =
(deviceExtension->FullIdentifyData.UserAddressableSectors /
(deviceExtension->FullIdentifyData.NumberOfHeads *
deviceExtension->FullIdentifyData.SectorsPerTrack));
(deviceExtension->FullIdentifyData.UserAddressableSectors48 > NumOfSectors)
) {
KdPrint2((PRINT_PREFIX "LBA48\n"));
- cylinders =
+ cylinders =
(deviceExtension->FullIdentifyData.UserAddressableSectors48 /
(deviceExtension->FullIdentifyData.NumberOfHeads *
deviceExtension->FullIdentifyData.SectorsPerTrack));
KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
-
+
NativeNumOfSectors = cylinders *
deviceExtension->FullIdentifyData.NumberOfHeads *
deviceExtension->FullIdentifyData.SectorsPerTrack;
KdPrint2((PRINT_PREFIX "Read high order bytes\n"));
NativeNumOfSectors |=
((ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) << 24 );
- hNativeNumOfSectors=
+ hNativeNumOfSectors=
(ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) |
((ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 8) ;
((PULONG)&NativeNumOfSectors)[1] = hNativeNumOfSectors;
((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) << 8 ) |
((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) << 32) |
((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 16) |
- ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 40)
+ ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 40)
;
}
}
}
}
-
+
if(NumOfSectors < 0x2100000 /*&& NumOfSectors > 31*1000*1000*/) {
// check for native LBA size
// some drives report ~32Gb in Identify Block
--*/
BOOLEAN
+NTAPI
SetDriveParameters(
IN PVOID HwDeviceExtension,
IN ULONG DeviceNumber,
} // end SetDriveParameters()
+VOID
+NTAPI
+UniataForgetDevice(
+ PHW_LU_EXTENSION LunExt
+ )
+{
+ LunExt->DeviceFlags &= DFLAGS_HIDDEN;
+} // end UniataForgetDevice()
+
/*++
BOOLEAN
+NTAPI
AtapiResetController__(
IN PVOID HwDeviceExtension,
IN ULONG PathId,
ULONG slotNumber = deviceExtension->slotNumber;
ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
ULONG VendorID = deviceExtension->DevID & 0xffff;
+#ifdef _DEBUG
ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
+#endif
//ULONG RevID = deviceExtension->RevID;
ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
UCHAR tmp8;
KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber));
- if(!deviceExtension->simplexOnly) {
+ if(!deviceExtension->simplexOnly && (PathId != CHAN_NOT_SPECIFIED)) {
// we shall reset both channels on SimplexOnly devices,
// It's not worth doing so on normal controllers
j = PathId;
- numberChannels = j+1;
+ numberChannels = min(j+1, deviceExtension->NumberChannels);
} else {
j=0;
numberChannels = deviceExtension->NumberChannels;
max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2;
if(CompleteType != RESET_COMPLETE_NONE) {
#ifndef UNIATA_CORE
- while(CurSrb = UniataGetCurRequest(chan)) {
+ while((CurSrb = UniataGetCurRequest(chan))) {
PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension);
// Clear request tracking fields.
AtaReq->WordsLeft = 0;
AtaReq->DataBuffer = NULL;
+ AtaReq->TransferLength = 0;
ScsiPortNotification(RequestComplete,
deviceExtension,
// Indicate ready for next request.
ScsiPortNotification(NextLuRequest,
- deviceExtension,
+ deviceExtension,
PathId,
TargetId,
Lun);
chan->ChannelCtrlFlags = 0;
InterlockedExchange(&(chan->CheckIntr),
CHECK_INTR_IDLE);
-
+
// Reset controller
KdPrint2((PRINT_PREFIX " disable intr (0)\n"));
AtapiDisableInterrupts(deviceExtension, j);
ULONG timeout;
if(!(ChipFlags & UNIATA_SATA))
goto default_reset;
- if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(!UniataIsSATARangeAvailable(deviceExtension, j)) {
goto default_reset;
}
// Disable interrupts
KdPrint2((PRINT_PREFIX " disable intr\n"));
AtapiDisableInterrupts(deviceExtension, j);
+ AtapiStallExecution(100);
KdPrint2((PRINT_PREFIX " re-enable intr\n"));
AtapiEnableInterrupts(deviceExtension, j);
KdPrint2((PRINT_PREFIX " wait a little (2)\n"));
}
//if(!(ChipFlags & UNIATA_SATA)) {
- if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
+ if(!UniataIsSATARangeAvailable(deviceExtension, j)) {
// Reset DMA engine if active
KdPrint2((PRINT_PREFIX " check DMA engine\n"));
dma_status = GetDmaStatus(chan->DeviceExtension, chan->lChannel);
// Check if device present.
if (!(deviceExtension->lun[i + (j * 2)].DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
+#ifdef NAVO_TEST
+ continue;
+#else //NAVO_TEST
//if(!CheckDevice(HwDeviceExtension, i, j, FALSE))
if(!UniataAnybodyHome(HwDeviceExtension, j, i)) {
continue;
} else {
if(!UniataAnybodyHome(HwDeviceExtension, j, i)) {
KdPrint2((PRINT_PREFIX " device have gone\n"));
- deviceExtension->lun[i + (j * 2)].DeviceFlags &= ~DFLAGS_DEVICE_PRESENT;
+ UniataForgetDevice(&(deviceExtension->lun[i + (j * 2)]));
}
+#endif //NAVO_TEST
}
SelectDrive(chan, i);
statusByte = WaitOnBusyLong(chan);
statusByte = UniataIsIdle(deviceExtension, statusByte);
if(statusByte == 0xff) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"no drive, status %#x\n",
statusByte));
- deviceExtension->lun[i + (j * 2)].DeviceFlags = 0;
+ UniataForgetDevice(&(deviceExtension->lun[i + (j * 2)]));
} else
// Check for ATAPI disk.
if (deviceExtension->lun[i + (j * 2)].DeviceFlags & DFLAGS_ATAPI_DEVICE) {
IDE_COMMAND_ATAPI_IDENTIFY, FALSE);
} else {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiResetController: Status after soft reset %#x\n",
statusByte));
}
--*/
ULONG
+NTAPI
MapError(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
// ULONG i;
UCHAR errorByte;
- UCHAR srbStatus;
+ UCHAR srbStatus = SRB_STATUS_SUCCESS;
UCHAR scsiStatus;
ULONG ldev = GET_LDEV(Srb);
// Read the error register.
errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"MapError: Error register is %#x\n",
errorByte));
switch (errorByte >> 4) {
case SCSI_SENSE_NO_SENSE:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: No sense information\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_RECOVERED_ERROR:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Recovered error\n"));
scsiStatus = 0;
srbStatus = SRB_STATUS_SUCCESS;
case SCSI_SENSE_NOT_READY:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Device not ready\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_MEDIUM_ERROR:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Media error\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_HARDWARE_ERROR:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Hardware error\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_ILLEGAL_REQUEST:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Illegal request\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_UNIT_ATTENTION:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Unit attention\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_DATA_PROTECT:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Data protect\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
case SCSI_SENSE_BLANK_CHECK:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Blank check\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_ABORTED_COMMAND:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"Atapi: Command Aborted\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
default:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ATAPI: Invalid sense information\n"));
scsiStatus = 0;
srbStatus = SRB_STATUS_ERROR;
chan->ReturningMediaStatus = errorByte;
if (errorByte & IDE_ERROR_MEDIA_CHANGE_REQ) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Media change\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
}
} else if (errorByte & IDE_ERROR_COMMAND_ABORTED) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Command abort\n"));
srbStatus = SRB_STATUS_ABORTED;
scsiStatus = SCSISTAT_CHECK_CONDITION;
} else if (errorByte & IDE_ERROR_END_OF_MEDIA) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: End of media\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
} else if (errorByte & IDE_ERROR_ILLEGAL_LENGTH) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Illegal length\n"));
srbStatus = SRB_STATUS_INVALID_REQUEST;
} else if (errorByte & IDE_ERROR_BAD_BLOCK) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Bad block\n"));
srbStatus = SRB_STATUS_ERROR;
scsiStatus = SCSISTAT_CHECK_CONDITION;
} else if (errorByte & IDE_ERROR_ID_NOT_FOUND) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Id not found\n"));
srbStatus = SRB_STATUS_ERROR;
scsiStatus = SCSISTAT_CHECK_CONDITION;
} else if (errorByte & IDE_ERROR_MEDIA_CHANGE) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Media change\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
} else if (errorByte & IDE_ERROR_DATA_ERROR) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IDE: Data error\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
if (deviceExtension->lun[ldev].ErrorCount >= MAX_ERRORS) {
// deviceExtension->DWordIO = FALSE;
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"MapError: ErrorCount >= MAX_ERRORS\n"));
deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_DWORDIO_ENABLED;
deviceExtension->lun[ldev].MaximumBlockXfer = 0;
BrutePoint();
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"MapError: Disabling 32-bit PIO and Multi-sector IOs\n"));
// Log the error.
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
HwDeviceExtension,
Srb,
KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base)\n"));
+ if(WinVer_WDM_Model) {
+ AtapiResetController__(HwDeviceExtension, CHAN_NOT_SPECIFIED, RESET_COMPLETE_ALL);
+ }
+
/* do extra chipset specific setups */
AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED);
/*
} // end AtapiHwInitialize()
VOID
+NTAPI
AtapiHwInitialize__(
IN PHW_DEVICE_EXTENSION deviceExtension,
IN ULONG lChannel
ULONG PreferedMode = 0xffffffff;
AtapiChipInit(deviceExtension, DEVNUM_NOT_SPECIFIED, lChannel);
- FindDevices(deviceExtension, FALSE, lChannel);
+ FindDevices(deviceExtension, 0, lChannel);
for (i = lChannel*2; i < (lChannel+1)*2; i++) {
- KdPrint2((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x\n", lChannel));
+ KdPrint3((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x, dev %x\n", lChannel, i));
LunExt = &(deviceExtension->lun[i]);
// skip empty slots
IdeMediaStatus(TRUE,deviceExtension,(UCHAR)i);
// If supported, setup Multi-block transfers.
- if (LunExt->MaximumBlockXfer) {
+ statusByte = AtaCommand(deviceExtension, i & 1, lChannel,
+ IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
+ LunExt->MaximumBlockXfer, 0, ATA_WAIT_BASE_READY);
+
+ // Check for errors. Reset the value to 0 (disable MultiBlock) if the
+ // command was aborted.
+ if (statusByte & IDE_STATUS_ERROR) {
+
+ // Read the error register.
+ errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
+
+ KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
+ statusByte,
+ errorByte));
statusByte = AtaCommand(deviceExtension, i & 1, lChannel,
IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
LunExt->MaximumBlockXfer, 0, ATA_WAIT_BASE_READY);
- // Check for errors. Reset the value to 0 (disable MultiBlock) if the
- // command was aborted.
if (statusByte & IDE_STATUS_ERROR) {
-
// Read the error register.
errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
- KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
+ KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
statusByte,
errorByte));
-
- // Adjust the devExt. value, if necessary.
- LunExt->MaximumBlockXfer = 0;
-
- } else {
- KdPrint2((PRINT_PREFIX
- "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
- i,
- LunExt->MaximumBlockXfer));
}
+ // Adjust the devExt. value, if necessary.
+ LunExt->MaximumBlockXfer = 0;
+
+ } else {
+ KdPrint2((PRINT_PREFIX
+ "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
+ i,
+ LunExt->MaximumBlockXfer));
}
if(LunExt->IdentifyData.MajorRevision) {
-
+
if(LunExt->opt_ReadCacheEnable) {
KdPrint2((PRINT_PREFIX " Try Enable Read Cache\n"));
// If supported, setup read/write cacheing
// Check for errors.
if (statusByte & IDE_STATUS_ERROR) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
i));
LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_BASE_READY);
// Check for errors.
if (statusByte & IDE_STATUS_ERROR) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
i));
LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
#ifndef UNIATA_CORE
VOID
+NTAPI
AtapiHwInitializeChanger(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
--*/
ULONG
+NTAPI
AtapiParseArgumentString(
- IN PCHAR String,
- IN PCHAR KeyWord
+ IN PCCH String,
+ IN PCCH KeyWord
)
{
- PCHAR cptr;
- PCHAR kptr;
+ PCCH cptr;
+ PCCH kptr;
ULONG value;
ULONG stringLength = 0;
ULONG keyWordLength = 0;
return 0;
}
- // Calculate the string length and lower case all characters.
+ // Calculate the string length.
cptr = String;
- while (*cptr) {
- if (*cptr >= 'A' && *cptr <= 'Z') {
- *cptr = *cptr + ('a' - 'A');
- }
- cptr++;
+ while (*cptr++) {
stringLength++;
}
- // Calculate the keyword length and lower case all characters.
- cptr = KeyWord;
- while (*cptr) {
-
- if (*cptr >= 'A' && *cptr <= 'Z') {
- *cptr = *cptr + ('a' - 'A');
- }
- cptr++;
+ // Calculate the keyword length.
+ kptr = KeyWord;
+ while (*kptr++) {
keyWordLength++;
}
}
kptr = KeyWord;
- while (*cptr++ == *kptr++) {
+ while ((*cptr == *kptr) ||
+ (*cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
+ (*cptr >= 'a' && *cptr - ('a' - 'A') == *kptr)) {
+ cptr++;
+ kptr++;
- if (*(cptr - 1) == '\0') {
+ if (*cptr == '\0') {
// end of string
return 0;
}
}
- if (*(kptr - 1) == '\0') {
+ if (*kptr == '\0') {
// May have a match backup and check for blank or equals.
- cptr--;
while (*cptr == ' ' || *cptr == '\t') {
cptr++;
}
}
value = 0;
- if ((*cptr == '0') && (*(cptr + 1) == 'x')) {
+ if ((*cptr == '0') && ((*(cptr + 1) == 'x') || (*(cptr + 1) == 'X'))) {
// Value is in Hex. Skip the "0x"
cptr += 2;
for (index = 0; *(cptr + index); index++) {
} else {
if ((*(cptr + index) >= 'a') && (*(cptr + index) <= 'f')) {
value = (16 * value) + (*(cptr + index) - 'a' + 10);
+ } else if ((*(cptr + index) >= 'A') && (*(cptr + index) <= 'F')) {
+ value = (16 * value) + (*(cptr + index) - 'A' + 10);
} else {
// Syntax error, return not found.
return 0;
Timer callback
*/
VOID
+NTAPI
AtapiCallBack__(
IN PVOID HwDeviceExtension,
IN UCHAR lChannel
chan->DpcState = DPC_STATE_TIMER;
if(!AtapiInterrupt__(HwDeviceExtension, lChannel)) {
InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE);
- KdPrint2((PRINT_PREFIX "AtapiCallBack: What's fucking this ???!!!\n"));
+ KdPrint2((PRINT_PREFIX "AtapiCallBack: What's fucking this ???\n"));
}
goto ReturnCallback;
}
// Ask for next request.
ScsiPortNotification(NextLuRequest,
- deviceExtension,
+ deviceExtension,
PathId,
TargetId,
Lun);
chan = &(deviceExtension->chan[c]);
- if((ULONG)CrNtInterlockedCompareExchange((PVOID*)&(chan->CheckIntr),
- (PVOID)CHECK_INTR_ACTIVE,
- (PVOID)CHECK_INTR_DETECTED) == CHECK_INTR_DETECTED) {
+ if((ULONG)InterlockedCompareExchange(&chan->CheckIntr,
+ CHECK_INTR_ACTIVE,
+ CHECK_INTR_DETECTED) == CHECK_INTR_DETECTED) {
//ASSERT(!deviceExtension->simplexOnly);
chan->DpcState = DPC_STATE_ISR;
if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
} // end AtapiCallBack__()
VOID
+NTAPI
AtapiCallBack_X(
IN PVOID HwDeviceExtension
)
ULONG c, _c;
BOOLEAN status = FALSE;
ULONG c_state;
- ULONG i_res;
+ ULONG i_res = 0;
ULONG pass;
BOOLEAN checked[AHCI_MAX_PORT];
for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
checked[_c] = FALSE;
}
-// fc =
+// fc =
// atapiDev = (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
for(pass=0; pass<2; pass++) {
for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
if(checked[c])
continue;
- // check non-empty and execting interrupt channels first
+ // check non-empty and expecting interrupt channels first
if(!pass && !deviceExtension->chan[c].ExpectingInterrupt)
continue;
// if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_DETECTED) {
// deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE;
// }
- c_state = (ULONG)CrNtInterlockedCompareExchange((PVOID*)&(deviceExtension->chan[c].CheckIntr),
- (PVOID)CHECK_INTR_ACTIVE,
- (PVOID)CHECK_INTR_DETECTED);
+ c_state = (ULONG)InterlockedCompareExchange(&(deviceExtension->chan[c].CheckIntr),
+ CHECK_INTR_ACTIVE,
+ CHECK_INTR_DETECTED);
if(c_state == CHECK_INTR_IDLE) {
// c_state = deviceExtension->chan[c].CheckIntr;
// if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_IDLE) {
// deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE
// }
- c_state = (ULONG)CrNtInterlockedCompareExchange((PVOID*)&(deviceExtension->chan[c].CheckIntr),
- (PVOID)CHECK_INTR_ACTIVE,
- (PVOID)CHECK_INTR_IDLE);
+ c_state = (ULONG)InterlockedCompareExchange(&(deviceExtension->chan[c].CheckIntr),
+ CHECK_INTR_ACTIVE,
+ CHECK_INTR_IDLE);
}
} while(c_state == CHECK_INTR_CHECK);
KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): locked\n"));
#ifndef UNIATA_CORE
BOOLEAN
+NTAPI
AtapiInterrupt2(
IN PKINTERRUPT Interrupt,
IN PVOID Isr2HwDeviceExtension
ULONG c_count = 0;
ULONG i_res;
+ // we should never get here for ISA/MCA
if(!BMList[deviceExtension->DevIndex].Isr2Enable) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt2: NOT ACTIVE cntrlr %#x chan %#x\n",deviceExtension->DevIndex, deviceExtension->Channel));
return FALSE;
continue;
}
- if((ULONG)CrNtInterlockedCompareExchange((PVOID*)&(deviceExtension->chan[c].CheckIntr),
- (PVOID)CHECK_INTR_CHECK,
- (PVOID)CHECK_INTR_IDLE) != CHECK_INTR_IDLE) {
+ if((ULONG)CrNtInterlockedCompareExchange(&(deviceExtension->chan[c].CheckIntr),
+ CHECK_INTR_CHECK,
+ CHECK_INTR_IDLE) != CHECK_INTR_IDLE) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !CHECK_INTR_IDLE\n"));
// hunt on unexpected intr (Some devices generate double interrupts,
// some controllers (at least CMD649) interrupt twice with small delay.
}
c_count++;
- if(i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c)) {
+ if((i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt2: intr\n"));
if(i_res == 2) {
}
KdPrint2((PRINT_PREFIX "AtapiInterrupt2: return %d\n", status));
return status;
-
+
} // end AtapiInterrupt2()
RETTYPE_XXableInterrupts
if(!(deviceExtension->chan[c].ChannelCtrlFlags & CTRFLAGS_DPC_REQ)) {
- if((ULONG)CrNtInterlockedCompareExchange((PVOID*)&(deviceExtension->chan[c].CheckIntr),
- (PVOID)CHECK_INTR_ACTIVE,
- (PVOID)CHECK_INTR_DETECTED) != CHECK_INTR_DETECTED) {
+ if((ULONG)InterlockedCompareExchange(&(deviceExtension->chan[c].CheckIntr),
+ CHECK_INTR_ACTIVE,
+ CHECK_INTR_DETECTED) != CHECK_INTR_DETECTED) {
continue;
}
-
+
} else {
deviceExtension->chan[c].ChannelCtrlFlags &= ~CTRFLAGS_DPC_REQ;
}
} else {
// check if other channel(s) interrupted
// must do nothing in simplex mode
- if((ULONG)CrNtInterlockedCompareExchange((PVOID*)&(chan->CheckIntr),
- (PVOID)CHECK_INTR_ACTIVE,
- (PVOID)CHECK_INTR_DETECTED) != CHECK_INTR_DETECTED) {
+ if((ULONG)CrNtInterlockedCompareExchange(&(chan->CheckIntr),
+ CHECK_INTR_ACTIVE,
+ CHECK_INTR_DETECTED) != CHECK_INTR_DETECTED) {
continue;
}
//ASSERT(!deviceExtension->simplexOnly);
VOID
+NTAPI
AtapiEnableInterrupts(
IN PVOID HwDeviceExtension,
IN ULONG c
} // end AtapiEnableInterrupts()
VOID
+NTAPI
AtapiDisableInterrupts(
IN PVOID HwDeviceExtension,
IN ULONG c
Check hardware for interrupt state
*/
BOOLEAN
+NTAPI
AtapiCheckInterrupt__(
IN PVOID HwDeviceExtension,
IN UCHAR c // logical channel
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
PHW_CHANNEL chan = &(deviceExtension->chan[c]);
+ PHW_LU_EXTENSION LunExt;
ULONG VendorID = deviceExtension->DevID & 0xffff;
ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
ULONG status;
- ULONG pr_status;
+ ULONG pr_status = 0;
UCHAR dma_status = 0;
UCHAR reg8 = 0;
- UCHAR reg32 = 0;
+ ULONG reg32 = 0;
UCHAR statusByte;
ULONG slotNumber = deviceExtension->slotNumber;
ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
UCHAR lChannel;
BOOLEAN DmaTransfer = FALSE;
BOOLEAN OurInterrupt = FALSE;
- ULONG k;
+// ULONG k;
UCHAR interruptReason;
BOOLEAN EarlyIntr = FALSE;
goto check_unknown;
}
+ if((ChipFlags & UNIATA_AHCI) &&
+ UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
+ OurInterrupt = UniataAhciStatus(HwDeviceExtension, lChannel);
+ return OurInterrupt;
+ }
+
// Attention !
// We can catch (BM_STATUS_ACTIVE + BM_STATUS_INTR) when operation is actually completed
// Such behavior was observed with Intel ICH-xxx chips
status = AtapiReadPortEx4(chan, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x1c);
if (!DmaTransfer)
break;
- if (!(status &
+ if (!(status &
((Channel) ? 0x00004000 : 0x00000400))) {
KdPrint2((PRINT_PREFIX " Promise old/new unexpected\n"));
return FALSE;
if(ChipType == SIIMIO) {
- reg32 = AtapiReadPort1(chan, IDX_BM_DeviceSpecific0);
+ reg32 = AtapiReadPort4(chan, IDX_BM_DeviceSpecific0);
KdPrint2((PRINT_PREFIX " Sii DS0 %x\n", reg32));
if(reg32 == 0xffffffff) {
KdPrint2((PRINT_PREFIX " Sii mio unexpected\n"));
AtapiReadPort1(chan, IDX_BM_Command) & ~BM_COMMAND_START_STOP);
goto skip_dma_stat_check;
default:
- if(deviceExtension->BaseIoAddressSATA_0.Addr &&
- (ChipFlags & UNIATA_SATA)) {
- if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT)) {
- OurInterrupt = 2;
+ if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
+ if(ChipFlags & UNIATA_AHCI) {
+ // Do nothing here
+ } else
+ if(ChipFlags & UNIATA_SATA) {
+ if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT)) {
+ OurInterrupt = 2;
+ }
}
}
}
AtapiStallExecution(1);
}
+ LunExt = &(deviceExtension->lun[c*2 + chan->cur_cdev]);
/* if drive is busy it didn't interrupt */
- /* the exception is DCS + BSY state of ATAPI dvices */
+ /* the exception is DCS + BSY state of ATAPI devices */
KdPrint2((PRINT_PREFIX " getting status...\n"));
GetStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX " status %#x\n", statusByte));
+ if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
+ KdPrint3((PRINT_PREFIX " ATAPI status %#x\n", statusByte));
+ } else {
+ KdPrint2((PRINT_PREFIX " IDE status %#x\n", statusByte));
+ }
if (statusByte == 0xff) {
// interrupt from empty controller ?
} else
if (statusByte & IDE_STATUS_BUSY) {
if(!chan->ExpectingInterrupt) {
- KdPrint2((PRINT_PREFIX " unexpected intr + BUSY\n"));
+ KdPrint3((PRINT_PREFIX " unexpected intr + BUSY\n"));
return OurInterrupt;
}
- if(deviceExtension->lun[c*2 + chan->cur_cdev].DeviceFlags & DFLAGS_ATAPI_DEVICE) {
+ if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
} else {
KdPrint2((PRINT_PREFIX " expecting intr + BUSY (3), non ATAPI\n"));
return FALSE;
}
- if(statusByte != (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) {
- KdPrint2((PRINT_PREFIX " unexpected status, seems it is not our\n"));
+ if((statusByte & ~IDE_STATUS_DRQ) != (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) {
+ KdPrint3((PRINT_PREFIX " unexpected status, seems it is not our\n"));
+ return FALSE;
+ }
+ if(!(LunExt->DeviceFlags & DFLAGS_INT_DRQ) && (statusByte & IDE_STATUS_DRQ)) {
+ KdPrint3((PRINT_PREFIX " unexpected DRQ, seems it is not our\n"));
return FALSE;
}
EarlyIntr = TRUE;
if(dma_status & BM_STATUS_INTR) {
- KdPrint2((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n"));
+ KdPrint3((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n"));
/* clear interrupt and get status */
GetBaseStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX " base status %#x\n", statusByte));
+ KdPrint3((PRINT_PREFIX " base status %#x (+BM_STATUS_INTR)\n", statusByte));
return TRUE;
}
if(g_WaitBusyInISR) {
- for(k=20; k; k--) {
- GetStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
- KdPrint2((PRINT_PREFIX " Error reg (%#x)\n",
- AtapiReadPort1(chan, IDX_IO1_i_Error)));
- if (!(statusByte & IDE_STATUS_BUSY)) {
- KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
- break;
- }
- break;
- //AtapiStallExecution(25);
+ GetStatus(chan, statusByte);
+ KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
+ reg8 = AtapiReadPort1(chan, IDX_IO1_i_Error);
+ KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", reg8));
+ if (!(statusByte & IDE_STATUS_BUSY)) {
+ KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
}
if (statusByte & IDE_STATUS_BUSY) {
KdPrint2((PRINT_PREFIX " still BUSY, seems it is not our\n"));
KdPrint2((PRINT_PREFIX " base status %#x\n", statusByte));
if (statusByte == 0xff) {
// interrupt from empty controller ?
- } else
+ } else
if(!(statusByte & (IDE_STATUS_DRQ | IDE_STATUS_DRDY))) {
KdPrint2((PRINT_PREFIX " no DRQ/DRDY set\n"));
return OurInterrupt;
KdPrint2((PRINT_PREFIX " Unexpected interrupt.\n"));
- if(deviceExtension->lun[c*2 + chan->cur_cdev * 2].DeviceFlags & DFLAGS_ATAPI_DEVICE) {
+ if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
} else {
KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt));
return OurInterrupt;
}
interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
- KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
+ KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
return OurInterrupt;
}
//ASSERT(!chan->queue_depth || chan->cur_req);
BOOLEAN
+NTAPI
AtapiInterrupt__(
IN PVOID HwDeviceExtension,
IN UCHAR c
PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
ULONG wordCount = 0, wordsThisInterrupt = DEV_BSIZE/2;
- ULONG status;
+ ULONG status = SRB_STATUS_SUCCESS;
UCHAR dma_status = 0;
ULONG i;
ULONG k;
- UCHAR statusByte,interruptReason;
+ UCHAR statusByte = 0,interruptReason;
BOOLEAN atapiDev = FALSE;
}
if (srb) {
- PathId = srb->PathId;
+ PathId = srb->PathId;
TargetId = srb->TargetId;
- Lun = srb->Lun;
+ Lun = srb->Lun;
} else {
PathId = (UCHAR)c;
TargetId =
switch(OldReqState) {
case REQ_STATE_ATAPI_EXPECTING_CMD_INTR:
+ KdPrint3((PRINT_PREFIX " EXPECTING_CMD_INTR\n"));
case REQ_STATE_ATAPI_EXPECTING_DATA_INTR:
case REQ_STATE_DPC_WAIT_BUSY0:
case REQ_STATE_DPC_WAIT_BUSY1:
#else
ServiceInterrupt:
#endif //UNIATA_CORE
-
+/*
// make additional delay for old devices (if we are not in DPC)
if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4))
&&
KdPrint2((PRINT_PREFIX " additional delay 10us for old devices\n"));
AtapiStallExecution(10);
}
-
+*/
/* clear interrupt and get status */
GetBaseStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
+ if(atapiDev) {
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte));
+ } else {
+ KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
+ }
if(!UseDpc) {
KdPrint2((PRINT_PREFIX " operate like in DPC\n"));
InDpc = TRUE;
}
-
+
if (!atapiDev) {
// IDE
if (statusByte & IDE_STATUS_BUSY) {
#ifndef UNIATA_CORE
goto PostToDpc;
-#else UNIATA_CORE
+#else //UNIATA_CORE
AtapiStallExecution(TimerValue);
goto ServiceInterrupt;
#endif //UNIATA_CORE
- } else
+ } else
if (InDpc && i == k) {
// reset the controller.
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
" Resetting due to BUSY on entry - %#x.\n",
statusByte));
goto IntrPrepareResetController;
}
if (statusByte & IDE_STATUS_BUSY) {
//if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) {
- KdPrint2((PRINT_PREFIX " BUSY on ATAPI device, waiting\n"));
+ KdPrint3((PRINT_PREFIX " BUSY on ATAPI device, waiting\n"));
for(k=20; k; k--) {
GetStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
- KdPrint2((PRINT_PREFIX " Error reg (%#x)\n",
+ KdPrint3((PRINT_PREFIX " status re-check %#x\n", statusByte));
+ KdPrint3((PRINT_PREFIX " Error reg (%#x)\n",
AtapiReadPort1(chan, IDX_IO1_i_Error)));
if (!(statusByte & IDE_STATUS_BUSY)) {
KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
break;
}
if(k <= 18) {
- KdPrint2((PRINT_PREFIX " too long wait -> DPC\n"));
+ KdPrint3((PRINT_PREFIX " too long wait -> DPC\n"));
if(!InDpc) {
KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC\n"));
TimerValue = 100;
}
#ifndef UNIATA_CORE
goto CallTimerDpc2;
-#else UNIATA_CORE
+#else //UNIATA_CORE
AtapiStallExecution(TimerValue);
#endif //UNIATA_CORE
}
AtapiStallExecution(10);
}
if (statusByte & IDE_STATUS_BUSY) {
- KdPrint2((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n"));
+ KdPrint3((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n"));
goto try_dpc_wait;
}
}
KdPrint2((PRINT_PREFIX " Bad Lba unknown\n"));
}
- KdPrint2((PRINT_PREFIX " wait ready after error\n"));
if(!atapiDev) {
+ KdPrint2((PRINT_PREFIX " wait 100 ready after IDE error\n"));
AtapiStallExecution(100);
} else {
+ KdPrint2((PRINT_PREFIX " wait 10 ready after ATAPI error\n"));
AtapiStallExecution(10);
}
continue_err:
- KdPrint2((PRINT_PREFIX " Intr on DRQ %x\n",
+ KdPrint3((PRINT_PREFIX " Intr on DRQ %x\n",
LunExt->DeviceFlags & DFLAGS_INT_DRQ));
for (k = atapiDev ? 0 : 200; k; k--) {
GetStatus(chan, statusByte);
if (!(statusByte & IDE_STATUS_DRQ)) {
- AtapiStallExecution(50);
+ AtapiStallExecution(100);
} else {
break;
}
}
} else {
interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
- KdPrint2((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) &&
+ ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
+ if(AtaReq->retry < MAX_RETRIES) {
+//fallback_pio:
+ AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
+ AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
+// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
+ AtaReq->ReqState = REQ_STATE_QUEUED;
+ goto reenqueue_req;
+ }
+ } else {
+ if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
+ AtaReq->retry++;
+ }
+ KdPrint3((PRINT_PREFIX "Errors in PIO mode\n"));
+ }
}
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error\n"));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n"));
if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
// Fail this request.
status = SRB_STATUS_ERROR;
} else {
KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n"));
}
-#ifdef IO_STATISTICS
} else
if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) {
KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n"));
} else
if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n"));
+#ifdef IO_STATISTICS
chan->lun[DeviceNumber]->RecoverCount[AtaReq->retry]++;
- if(chan->lun[DeviceNumber]->RecoverCount[AtaReq->retry] >= chan->lun[DeviceNumber]->IoCount/3) {
+ if(chan->lun[DeviceNumber]->RecoverCount[AtaReq->retry] >= chan->lun[DeviceNumber]->IoCount/3 ||
+ (deviceExtension->HwFlags & UNIATA_NO80CHK)
+ ) {
+#else
+ if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
+#endif //IO_STATISTICS
+ KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", deviceExtension->lun[DeviceNumber].TransferMode));
deviceExtension->lun[DeviceNumber].LimitedTransferMode =
deviceExtension->lun[DeviceNumber].TransferMode;
}
-#endif //IO_STATISTICS
}
#ifdef IO_STATISTICS
chan->lun[DeviceNumber]->IoCount++;
// ATAPI branch
interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & 0x3);
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
if(DmaTransfer) {
wordsThisInterrupt = DEV_BSIZE/2*512;
} else {
- wordsThisInterrupt = DEV_BSIZE;
+ wordsThisInterrupt = DEV_BSIZE/2;
}
} else {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq0)\n"));
#ifndef UNIATA_CORE
goto PostToDpc;
-#else UNIATA_CORE
+#else //UNIATA_CORE
AtapiStallExecution(TimerValue);
goto ServiceInterrupt;
#endif //UNIATA_CORE
KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte));
if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) {
// Write the packet.
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
// Send CDB to device.
WriteBuffer(chan, (PUSHORT)srb->Cdb, 6, 0);
AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
KdPrint2((PRINT_PREFIX "AtapiInterrupt: get W wordCount %#x\n", wordCount));
if (wordCount != AtaReq->WordsLeft) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiInterrupt: %d words requested; %d words xferred\n",
AtaReq->WordsLeft,
wordCount));
// Verify this makes sense.
if (wordCount > AtaReq->WordsLeft) {
wordCount = AtaReq->WordsLeft;
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiInterrupt: Write underrun\n"));
DataOverrun = TRUE;
}
// Ensure that this is a write command.
if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiInterrupt: Write interrupt\n"));
statusByte = WaitOnBusy(chan);
}
} else {
- KdPrint2((PRINT_PREFIX
+ KdPrint3((PRINT_PREFIX
"AtapiInterrupt: Int reason %#x, but srb is for a write %#x.\n",
interruptReason,
srb));
(AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8);
// Covert bytes to words.
- wordCount >>= 1;
+ wordCount /= 2;
KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R wordCount %#x\n", wordCount));
if (wordCount != AtaReq->WordsLeft) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiInterrupt: %d words requested; %d words xferred\n",
AtaReq->WordsLeft,
wordCount));
statusByte = WaitOnBusy(chan);
if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeIntr: Read %#x words\n", wordCount));
ReadBuffer(chan,
UniataGetPioTiming(LunExt));
KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) ));
//KdDump(AtaReq->DataBuffer, wordCount*2);
+ if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
+ KdDump(AtaReq->DataBuffer, wordCount*2);
+ }
GetStatus(chan, statusByte);
KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
}
} else {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeIntr: Read %#x Dwords\n", wordCount/2));
ReadBuffer2(chan,
}
} else {
- KdPrint2((PRINT_PREFIX
+ KdPrint3((PRINT_PREFIX
"AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
interruptReason,
srb));
KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n"));
if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
if (status == SRB_STATUS_SUCCESS) {
// Bingo!!
AtapiHwInitializeChanger (HwDeviceExtension,
*/
srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
if (srbStatus == SRB_STATUS_PENDING) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (1)\n"));
PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
if (status == SRB_STATUS_DATA_OVERRUN) {
// Check to see if we at least get mininum number of bytes
if ((srb->DataTransferLength - AtaReq->WordsLeft) >
*/
srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt));
if (srbStatus == SRB_STATUS_PENDING) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (2)\n"));
// If we get here, it means AtapiSendCommand() has failed
// Can't recover. Pretend the original srb has failed and complete it.
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
if (AtaReq->OriginalSrb) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiHwInitializeChanger()\n"));
} else if (status == SRB_STATUS_ERROR) {
// Map error to specific SRB status and handle request sense.
- KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n"));
+ KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n"));
status = MapError(deviceExtension,
srb);
} else if(!DmaTransfer) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion\n"));
+ // Command complete.
PIO_wait_busy:
KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion, wait BUSY\n"));
// Wait for busy to drop.
KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (busy)\n"));
#ifndef UNIATA_CORE
goto PostToDpc;
-#else UNIATA_CORE
+#else //UNIATA_CORE
AtapiStallExecution(TimerValue);
goto ServiceInterrupt;
#endif //UNIATA_CORE
if (i == 5*30) {
// reset the controller.
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiInterrupt: Resetting due to BSY still up - %#x.\n",
statusByte));
goto IntrPrepareResetController;
TimerValue = 100;
#ifndef UNIATA_CORE
goto PostToDpc;
-#else UNIATA_CORE
+#else //UNIATA_CORE
AtapiStallExecution(TimerValue);
goto ServiceInterrupt;
#endif //UNIATA_CORE
CHECK_INTR_IDLE);
// Sanity check that there is a current request.
- if (srb != NULL) {
+ if(srb != NULL) {
// Set status in SRB.
srb->SrbStatus = (UCHAR)status;
// Check for underflow.
- if (AtaReq->WordsLeft) {
+ if(AtaReq->WordsLeft) {
KdPrint2((PRINT_PREFIX "AtapiInterrupt: Check for underflow, AtaReq->WordsLeft %x\n", AtaReq->WordsLeft));
// Subtract out residual words and update if filemark hit,
// setmark hit , end of data, end of media...
if (!(LunExt->DeviceFlags & DFLAGS_TAPE_DEVICE)) {
if (status == SRB_STATUS_DATA_OVERRUN) {
- srb->DataTransferLength -= AtaReq->WordsLeft;
+ srb->DataTransferLength -= AtaReq->WordsLeft*2;
} else {
srb->DataTransferLength = 0;
}
} else {
- srb->DataTransferLength -= AtaReq->WordsLeft;
+ srb->DataTransferLength -= AtaReq->WordsLeft*2;
+ }
+ }
+ if(status == SRB_STATUS_SUCCESS) {
+ AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2;
+ if(!atapiDev &&
+ AtaReq->WordsTransfered*2 < AtaReq->TransferLength) {
+ KdPrint2((PRINT_PREFIX "AtapiInterrupt: more I/O required (%x of %x bytes) -> reenqueue\n",
+ AtaReq->WordsTransfered*2, AtaReq->TransferLength));
+ AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
+ AtaReq->ReqState = REQ_STATE_PREPARE_TO_NEXT;
+ goto reenqueue_req;
+ } else {
+ KdPrint2((PRINT_PREFIX " Transfered %x, full size %x\n",
+ AtaReq->WordsTransfered*2, AtaReq->TransferLength));
}
}
KdPrint2((PRINT_PREFIX "AtapiInterrupt: Clear RDP\n"));
chan->RDP = FALSE;
goto CompleteRDP;
- }
+ }
AtapiStallExecution(50);
}
}
TimerValue = 2000;
#ifndef UNIATA_CORE
goto CallTimerDpc;
-#else UNIATA_CORE
+#else //UNIATA_CORE
AtapiStallExecution(TimerValue);
goto ServiceInterrupt;
#endif //UNIATA_CORE
NULL);
} else {
ScsiPortNotification(NextLuRequest,
- deviceExtension,
+ deviceExtension,
PathId,
TargetId,
Lun);
--*/
ULONG
+NTAPI
IdeSendSmartCommand(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
if (regs->bCommandReg != SMART_CMD) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendSmartCommand: bCommandReg != SMART_CMD\n"));
return SRB_STATUS_INVALID_REQUEST;
}
statusByte = WaitOnBusy(chan);
if (statusByte & IDE_STATUS_BUSY) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendSmartCommand: Returning BUSY status\n"));
return SRB_STATUS_BUSY;
}
statusByte = WaitOnBusy(chan);
if (statusByte & IDE_STATUS_BUSY) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendSmartCommand: Returning BUSY status\n"));
return SRB_STATUS_BUSY;
}
#endif //UNIATA_CORE
ULONGLONG
+NTAPI
UniAtaCalculateLBARegs(
PHW_LU_EXTENSION LunExt,
- ULONG startingSector
+ ULONG startingSector,
+ PULONG max_bcount
)
{
UCHAR drvSelect,sectorNumber;
USHORT cylinder;
ULONG tmp;
+ (*max_bcount) = 0;
+
if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
+ if(LunExt->LimitedTransferMode >= ATA_DMA) {
+ if(LunExt->DeviceExtension) {
+ (*max_bcount) = LunExt->DeviceExtension->MaximumDmaTransferLength / DEV_BSIZE;
+ }
+ }
return startingSector;
}
tmp = LunExt->IdentifyData.SectorsPerTrack *
cylinder = 0;
drvSelect = 0;
sectorNumber = 1;
+ (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack;
} else {
cylinder = (USHORT)(startingSector / tmp);
drvSelect = (UCHAR)((startingSector % tmp) / LunExt->IdentifyData.SectorsPerTrack);
sectorNumber = (UCHAR)(startingSector % LunExt->IdentifyData.SectorsPerTrack) + 1;
+ (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack - sectorNumber + 1;
+ KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n",
+ cylinder, drvSelect, sectorNumber, (*max_bcount)));
}
return (ULONG)(sectorNumber&0xff) | (((ULONG)cylinder&0xffff)<<8) | (((ULONG)drvSelect&0xf)<<24);
} // end UniAtaCalculateLBARegs()
ULONGLONG
+NTAPI
UniAtaCalculateLBARegsBack(
PHW_LU_EXTENSION LunExt,
ULONGLONG lba
--*/
ULONG
+NTAPI
IdeReadWrite(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
ULONG ldev = GET_LDEV(Srb);
UCHAR DeviceNumber = (UCHAR)(ldev & 1);
ULONG startingSector;
- ULONG wordCount;
+ ULONG max_bcount;
+ ULONG wordCount = 0;
UCHAR statusByte,statusByte2;
UCHAR cmd;
ULONGLONG lba;
if((CmdAction & CMD_ACTION_PREPARE) &&
(AtaReq->ReqState != REQ_STATE_READY_TO_TRANSFER)) {
+ if(LunExt->opt_ReadOnly &&
+ (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)) {
+ if(LunExt->opt_ReadOnly == 1) {
+ KdPrint2((PRINT_PREFIX "Abort WRITE (Soft R/O)\n"));
+ return SRB_STATUS_ERROR;
+ } else {
+ KdPrint2((PRINT_PREFIX "Ignore WRITE (Soft R/O)\n"));
+ return SRB_STATUS_SUCCESS;
+ }
+ }
+
// Set data buffer pointer and words left.
- AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer;
+ AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
- MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
- //ASSERT(Srb->DataTransferLength == AtaReq->bcount * DEV_BSIZE);
- AtaReq->WordsLeft = min(Srb->DataTransferLength,
- AtaReq->bcount * DEV_BSIZE) / 2;
+ if(AtaReq->WordsTransfered) {
+ AtaReq->DataBuffer = ((PUSHORT)(Srb->DataBuffer)) + AtaReq->WordsTransfered;
+ startingSector = (ULONG)(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",
+ startingSector,
+ AtaReq->TransferLength/2,
+ AtaReq->WordsTransfered,
+ AtaReq->bcount));
+ } else {
+ 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",
+ startingSector,
+ AtaReq->TransferLength/2,
+ AtaReq->bcount));
+ }
+ lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount);
- // Set up 1st block.
- MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
+ if(max_bcount) {
+ AtaReq->bcount = min(AtaReq->bcount, max_bcount);
+ }
+ 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",
startingSector,
AtaReq->WordsLeft,
AtaReq->bcount));
- lba = UniAtaCalculateLBARegs(LunExt, startingSector);
AtaReq->lba = lba;
// assume best case here
// this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
(PUCHAR)(AtaReq->DataBuffer),
- ((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1)))) {
+ AtaReq->bcount * DEV_BSIZE)) {
use_dma = FALSE;
}
}
// Prepare write command.
if (use_dma) {
- wordCount = Srb->DataTransferLength/2;
+ wordCount = AtaReq->bcount*DEV_BSIZE/2;
cmd = IDE_COMMAND_WRITE_DMA;
} else
if (LunExt->MaximumBlockXfer) {
use_dma) {
statusByte2 = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
cmd, lba,
- (UCHAR)((Srb->DataTransferLength + DEV_BSIZE-1) / DEV_BSIZE),
+ (USHORT)(AtaReq->bcount),
// (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
0, ATA_IMMEDIATE);
- GetStatus(chan, statusByte2);
+ if(statusByte2 != 0xff) {
+ GetStatus(chan, statusByte2);
+ }
if(statusByte2 & IDE_STATUS_ERROR) {
statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
KdPrint2((PRINT_PREFIX "IdeReadWrite: status %#x, error %#x\n", statusByte2, statusByte));
statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
cmd, lba,
- (UCHAR)((Srb->DataTransferLength + DEV_BSIZE-1) / DEV_BSIZE),
+ (USHORT)(AtaReq->bcount),
// (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
0, ATA_WAIT_INTR);
- if (!(statusByte & IDE_STATUS_DRQ)) {
+ if (!(statusByte & IDE_STATUS_DRQ) ||
+ statusByte == 0xff) {
- KdPrint2((PRINT_PREFIX
- "IdeReadWrite: DRQ never asserted (%#x)\n",
- statusByte));
+ if(statusByte == 0xff) {
+ KdPrint2((PRINT_PREFIX
+ "IdeReadWrite: error sending command (%#x)\n",
+ statusByte));
+ } else {
+ KdPrint2((PRINT_PREFIX
+ "IdeReadWrite: DRQ never asserted (%#x)\n",
+ statusByte));
+ }
AtaReq->WordsLeft = 0;
// Clear current SRB.
UniataRemoveRequest(chan, Srb);
- return SRB_STATUS_TIMEOUT;
+ return (statusByte == 0xff) ? SRB_STATUS_ERROR : SRB_STATUS_TIMEOUT;
}
chan->ExpectingInterrupt = TRUE;
// Write next DEV_BSIZE/2*N words.
if (!(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED)) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeReadWrite: Write %#x words\n", wordCount));
WriteBuffer(chan,
} else {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeReadWrite: Write %#x Dwords\n", wordCount/2));
WriteBuffer2(chan,
--*/
ULONG
+NTAPI
IdeVerify(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
ULONG ldev = GET_LDEV(Srb);
UCHAR statusByte;
ULONG startingSector;
+ ULONG max_bcount;
ULONG sectors;
ULONG endSector;
USHORT sectorCount;
InterlockedExchange(&(chan->CheckIntr),
CHECK_INTR_IDLE);
- lba = UniAtaCalculateLBARegs(LunExt, startingSector);
+ lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount);
statusByte = AtaCommand48(deviceExtension, ldev & 0x01, GET_CHANNEL(Srb),
IDE_COMMAND_VERIFY, lba,
--*/
ULONG
+NTAPI
AtapiSendCommand(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
UCHAR statusByte,byteCountLow,byteCountHigh;
BOOLEAN use_dma = FALSE;
BOOLEAN dma_reinited = FALSE;
+ BOOLEAN retried = FALSE;
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: req state %#x\n", AtaReq->ReqState));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: req state %#x, Action %x\n", AtaReq->ReqState, CmdAction));
if(AtaReq->ReqState < REQ_STATE_PREPARE_TO_TRANSFER)
AtaReq->ReqState = REQ_STATE_PREPARE_TO_TRANSFER;
} else {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero transfer, no DMA setup\n"));
}
-
+
} else {
if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
// if this is queued request, reinit DMA and check
KdPrint2((PRINT_PREFIX "AtapiSendCommand: !CMD_ACTION_EXEC => SRB_STATUS_PENDING\n"));
return SRB_STATUS_PENDING;
}
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma));
if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
}
if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
}
-
+
KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_EXEC\n"));
#ifndef UNIATA_CORE
ULONG srbStatus;
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n"));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n"));
// Set this flag now. If the device hangs on the mech. status
// command, we will not have the chance to set it.
deviceExtension->lun[ldev].DeviceFlags |= DFLAGS_CHANGER_INITED;
HwDeviceExtension,
Srb);
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n"));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n"));
srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
if (srbStatus == SRB_STATUS_PENDING) {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n"));
}
#endif //UNIATA_CORE
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Command %#x to TargetId %d lun %d\n",
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: Command %#x to TargetId %d lun %d\n",
Srb->Cdb[0], Srb->TargetId, Srb->Lun));
// Make sure command is to ATAPI device.
flags = deviceExtension->lun[ldev].DeviceFlags;
- if (flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
- if ((Srb->Lun) > (deviceExtension->lun[ldev].DiscsPresent - 1)) {
+ if(flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
+ if((Srb->Lun) > (deviceExtension->lun[ldev].DiscsPresent - 1)) {
// Indicate no device found at this address.
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
return SRB_STATUS_SELECTION_TIMEOUT;
}
- } else if (Srb->Lun > 0) {
+ } else if(Srb->Lun > 0) {
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
return SRB_STATUS_SELECTION_TIMEOUT;
}
- if (!(flags & DFLAGS_ATAPI_DEVICE)) {
+ if(!(flags & DFLAGS_ATAPI_DEVICE)) {
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
return SRB_STATUS_SELECTION_TIMEOUT;
}
-
+retry:
// Select device 0 or 1.
SelectDrive(chan, ldev & 0x1);
// Verify that controller is ready for next command.
GetStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte));
- if (statusByte == 0xff) {
+ if(statusByte == 0xff) {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: bad status 0xff on entry\n"));
goto make_reset;
}
- if (statusByte & IDE_STATUS_BUSY) {
+ if(statusByte & IDE_STATUS_BUSY) {
if(statusByte & IDE_STATUS_DSC) {
KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC on entry (%#x), try exec\n", statusByte));
+ } else {
+ KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x) -> reset\n", statusByte));
+ // We have to make reset here, since we are expecting device to be available
+ //return SRB_STATUS_BUSY; // this cause queue freeze
+ goto make_reset;
}
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x)\n", statusByte));
- AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
- return SRB_STATUS_BUSY;
}
- if (statusByte & IDE_STATUS_ERROR) {
+ if(statusByte & IDE_STATUS_ERROR) {
if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte));
// Read the error reg. to clear it and fail this request.
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
return MapError(deviceExtension, Srb);
}
// If a tape drive doesn't have DSC set and the last command is restrictive, don't send
// the next command. See discussion of Restrictive Delayed Process commands in QIC-157.
- if ((!(statusByte & IDE_STATUS_DSC)) &&
+ if((!(statusByte & IDE_STATUS_DSC)) &&
(flags & (DFLAGS_TAPE_DEVICE | DFLAGS_ATAPI_DEVICE)) && chan->RDP) {
AtapiStallExecution(200);
return SRB_STATUS_PENDING;
}
- if (IS_RDP(Srb->Cdb[0])) {
+ if(IS_RDP(Srb->Cdb[0])) {
chan->RDP = TRUE;
KdPrint2((PRINT_PREFIX "AtapiSendCommand: %#x mapped as DSC restrictive\n", Srb->Cdb[0]));
} else {
chan->RDP = FALSE;
}
- if (statusByte & IDE_STATUS_DRQ) {
+ if(statusByte & IDE_STATUS_DRQ) {
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n",
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n",
statusByte));
// Try to drain the data that one preliminary device thinks that it has
// to transfer. Hopefully this random assertion of DRQ will not be present
// in production devices.
for (i = 0; i < 0x10000; i++) {
GetStatus(chan, statusByte);
- if (statusByte & IDE_STATUS_DRQ) {
+ if(statusByte & IDE_STATUS_DRQ) {
AtapiReadPort2(chan, IDX_IO1_i_Data);
} else {
break;
if (i == 0x10000) {
make_reset:
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted.Status (%#x)\n", statusByte));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted.Status (%#x)\n", statusByte));
AtapiDisableInterrupts(deviceExtension, lChannel);
KdPrint2((PRINT_PREFIX "AtapiSendCommand: Issued soft reset to Atapi device. \n"));
// Re-initialize Atapi device.
+ CheckDevice(HwDeviceExtension, GET_CHANNEL(Srb), ldev & 1, TRUE);
+/*
IssueIdentify(HwDeviceExtension, ldev & 1, GET_CHANNEL(Srb),
IDE_COMMAND_ATAPI_IDENTIFY, FALSE);
+*/
// Inform the port driver that the bus has been reset.
ScsiPortNotification(ResetDetected, HwDeviceExtension, 0);
// Clean up device extension fields that AtapiStartIo won't.
CHECK_INTR_IDLE);
AtapiEnableInterrupts(deviceExtension, lChannel);
-
+/*
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
return SRB_STATUS_BUS_RESET;
-
+*/
+ if(!retried) {
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: retry after reset.\n"));
+ retried = TRUE;
+ goto retry;
+ }
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: selection timeout.\n"));
+ AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
+ return SRB_STATUS_SELECTION_TIMEOUT;
}
}
- if (flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
+ if(flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
// As the cdrom driver sets the LUN field in the cdb, it must be removed.
Srb->Cdb[1] &= ~0xE0;
- if ((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY) && (flags & DFLAGS_SANYO_ATAPI_CHANGER)) {
+ if((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY) && (flags & DFLAGS_SANYO_ATAPI_CHANGER)) {
// Torisan changer. TUR's are overloaded to be platter switches.
Srb->Cdb[7] = Srb->Lun;
}
}
statusByte = WaitOnBusy(chan);
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n",
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n",
statusByte));
AtapiWritePort1(chan, IDX_IO1_o_Feature,
// This device interrupts when ready to receive the packet.
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n",
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n",
statusByte));
chan->ExpectingInterrupt = TRUE;
// Write ATAPI packet command.
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET);
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING\n"));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (DRQ)\n"));
return SRB_STATUS_PENDING;
} else {
InterlockedExchange(&(chan->CheckIntr),
CHECK_INTR_IDLE);
- AtapiDisableInterrupts(deviceExtension, lChannel);
+ //AtapiDisableInterrupts(deviceExtension, lChannel);
// Write ATAPI packet command.
AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET);
if (!(statusByte & IDE_STATUS_DRQ)) {
AtapiEnableInterrupts(deviceExtension, lChannel);
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte));
AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
return SRB_STATUS_ERROR;
}
}
GetStatus(chan, statusByte);
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
// Send CDB to device.
statusByte = WaitOnBaseBusy(chan);
GetBaseStatus(chan, statusByte);
- AtapiEnableInterrupts(deviceExtension, lChannel);
+ //AtapiEnableInterrupts(deviceExtension, lChannel);
WriteBuffer(chan,
(PUSHORT)Srb->Cdb,
AtapiDmaStart(HwDeviceExtension, ldev & 1, lChannel, Srb);
}
- KdPrint2((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt));
+ KdPrint3((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt));
KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (3)\n"));
return SRB_STATUS_PENDING;
#endif
ULONG
+NTAPI
IdeSendCommand(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
if(CmdAction == CMD_ACTION_PREPARE) {
switch (Srb->Cdb[0]) {
- //case SCSIOP_INQUIRY: // now it requires device access
+#ifdef NAVO_TEST
+ case SCSIOP_INQUIRY: // now it requires device access
+#endif //NAVO_TEST
case SCSIOP_READ_CAPACITY:
case SCSIOP_READ:
case SCSIOP_WRITE:
(Srb->TargetId > 2) /*||
(!deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT)*/) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_INQUIRY rejected\n"));
// Indicate no device found at this address.
status = SRB_STATUS_SELECTION_TIMEOUT;
} else {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_INQUIRY ok\n"));
PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
PIDENTIFY_DATA2 identifyData = &(deviceExtension->lun[ldev].IdentifyData);
if (!(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-
+
if(!CheckDevice(HwDeviceExtension, lChannel, ldev & 1, FALSE)) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_INQUIRY rejected (2)\n"));
// Indicate no device found at this address.
+#ifndef NAVO_TEST
status = SRB_STATUS_SELECTION_TIMEOUT;
break;
}
} else {
if(!UniataAnybodyHome(HwDeviceExtension, lChannel, ldev & 1)) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_INQUIRY device have gone\n"));
// Indicate no device found at this address.
- deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_DEVICE_PRESENT;
+ UniataForgetDevice(&(deviceExtension->lun[ldev]));
+#endif //NAVO_TEST
status = SRB_STATUS_SELECTION_TIMEOUT;
break;
}
// Set the removable bit, if applicable.
if (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"RemovableMedia\n"));
inquiryData->RemovableMedia = 1;
}
// Set the Relative Addressing (LBA) bit, if applicable.
if (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_LBA_ENABLED) {
inquiryData->RelativeAddressing = 1;
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"RelativeAddressing\n"));
}
// Set the CommandQueue bit
case SCSIOP_TEST_UNIT_READY:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_TEST_UNIT_READY PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->PathId, Srb->Lun, Srb->TargetId));
if (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
case SCSIOP_READ_CAPACITY:
- KdPrint2((PRINT_PREFIX
+ 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).
MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress, i );
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x\n",
Srb->TargetId,
deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack,
case SCSIOP_VERIFY:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_VERIFY PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->PathId, Srb->Lun, Srb->TargetId));
status = IdeVerify(HwDeviceExtension,Srb);
case SCSIOP_READ:
case SCSIOP_WRITE:
- KdPrint2((PRINT_PREFIX
- "IdeSendCommand: SCSIOP_READ/SCSIOP_WRITE PATH:LUN:TID = %#x:%#x:%#x\n",
+ 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;
case SCSIOP_START_STOP_UNIT:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_START_STOP_UNIT PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->PathId, Srb->Lun, Srb->TargetId));
//Determine what type of operation we should perform
// this function makes sense buffers to report the results
// of the original GET_MEDIA_STATUS command
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_REQUEST_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->PathId, Srb->Lun, Srb->TargetId));
if (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
PIDEREGS_EX regs;
BOOLEAN use_dma = FALSE;
ULONG to_lim;
-
+
regs = (PIDEREGS_EX) &(Srb->Cdb[2]);
lChannel = Srb->TargetId >> 1;
regs->bDriveHeadReg &= 0x0f;
regs->bDriveHeadReg |= (UCHAR) (((Srb->TargetId & 0x1) << 4) | 0xA0);
- if((regs->bReserved & 1) == 0) { // execute ATA command
+ if((regs->bOpFlags & 1) == 0) { // execute ATA command
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: SCSIOP_START_STOP_UNIT PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->PathId, Srb->Lun, Srb->TargetId));
AtapiDisableInterrupts(deviceExtension, lChannel);
- if(AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) {
+ if((AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) || (regs->bOpFlags & UNIATA_SPTI_EX_USE_DMA)) {
if((chan->lun[Srb->TargetId & 0x1]->LimitedTransferMode >= ATA_DMA)) {
use_dma = TRUE;
// this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, regs->bDriveHeadReg);
AtapiStallExecution(10);
- if((regs->bReserved & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command
+ if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command
AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg);
AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountReg);
AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberReg);
AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
}
AtapiWritePort1(chan, IDX_IO1_o_Command, regs->bCommandReg);
-
+
if(use_dma) {
GetBaseStatus(chan, statusByte);
if(statusByte & IDE_STATUS_ERROR) {
ScsiPortStallExecution(1); // wait for busy to be set
- if(regs->bReserved & UNIATA_SPTI_EX_SPEC_TO) {
+ if(regs->bOpFlags & UNIATA_SPTI_EX_SPEC_TO) {
to_lim = Srb->TimeOutValue;
} else {
if(Srb->TimeOutValue <= 2) {
}
}
if(i >= to_lim) {
- //if(regs->bReserved & UNIATA_SPTI_EX_FREEZE_TO) {
+ //if(regs->bOpFlags & UNIATA_SPTI_EX_FREEZE_TO) {
//}
AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_NONE);
goto passthrough_err;
regs->bDriveHeadReg = AtapiReadPort1(chan, IDX_IO1_i_DriveSelect);
- if((regs->bReserved & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command
+ if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command
regs->bFeaturesReg = AtapiReadPort1(chan, IDX_IO1_i_Error);
regs->bSectorCountReg = AtapiReadPort1(chan, IDX_IO1_i_BlockCount);
regs->bSectorNumberReg = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
default:
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeSendCommand: Unsupported command %#x\n",
Srb->Cdb[0]));
--*/
VOID
+NTAPI
IdeMediaStatus(
BOOLEAN EnableMSN,
IN PVOID HwDeviceExtension,
// Read the error register.
errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"IdeMediaStatus: Error enabling media status. Status %#x, error byte %#x\n",
statusByte,
errorByte));
--*/
ULONG
+NTAPI
IdeBuildSenseBuffer(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
}// End of IdeBuildSenseBuffer
VOID
+NTAPI
UniataUserDeviceReset(
PHW_DEVICE_EXTENSION deviceExtension,
PHW_LU_EXTENSION LunExt,
} else {
KdPrint2((PRINT_PREFIX "UniataUserDeviceReset: Reset IDE -> reset entire channel\n"));
AtapiResetController__(deviceExtension, PathId, RESET_COMPLETE_NONE);
+ deviceExtension->chan[PathId].lun[0]->DeviceFlags |= DFLAGS_REINIT_DMA;
+ deviceExtension->chan[PathId].lun[1]->DeviceFlags |= DFLAGS_REINIT_DMA;
}
LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit
AtapiEnableInterrupts(deviceExtension, PathId);
} // end UniataUserDeviceReset()
BOOLEAN
+NTAPI
UniataNeedQueueing(
PHW_DEVICE_EXTENSION deviceExtension,
PHW_CHANNEL chan,
{
BOOLEAN PostReq = FALSE;
if(TopLevel) {
+ KdPrint3((PRINT_PREFIX "UniataNeedQueueing: TopLevel, qd=%x\n", chan->queue_depth));
if(chan->queue_depth > 0) {
#if 0
if(atapiDev &&
if(deviceExtension->simplexOnly && deviceExtension->queue_depth > 0) {
PostReq = TRUE;
}
+ } else {
+ KdPrint3((PRINT_PREFIX "UniataNeedQueueing: qd=%x\n", chan->queue_depth));
}
return PostReq;
} // end UniataNeedQueueing()
} // end AtapiStartIo()
BOOLEAN
+NTAPI
AtapiStartIo__(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
PSCSI_REQUEST_BLOCK tmpSrb;
BOOLEAN PostReq = FALSE;
BOOLEAN atapiDev;
+ BOOLEAN commPort = FALSE;
+ // deviceExtension->Isr2DevObj must always be NULL for non-PCI
if(deviceExtension->Isr2DevObj && !BMList[deviceExtension->DevIndex].Isr2Enable) {
KdPrint2((PRINT_PREFIX "Isr2Enable -> 1\n"));
BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
/* KeBugCheckEx(0xc000000e,
(Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
- Srb->Function,
+ Srb->Function,
TopLevel, 0x80000001);
*/
if(TopLevel && Srb && Srb->SrbExtension) {
//ASSERT(deviceExtension);
//ASSERT(chan);
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"** AtapiStartIo: Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->Function, Srb->PathId, Srb->Lun, Srb->TargetId));
KdPrint2((PRINT_PREFIX " VendorID+DeviceID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
+ if(lChannel == deviceExtension->NumberChannels &&
+ !Srb->Lun && !Srb->TargetId &&
+ ((Srb->Function == SRB_FUNCTION_IO_CONTROL) ||
+ (Srb->Function == SRB_FUNCTION_EXECUTE_SCSI && Srb->Cdb[0] == SCSIOP_INQUIRY))
+ ) {
+ KdPrint2((PRINT_PREFIX
+ "AtapiStartIo: Communication port\n"));
+ if(Srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
+
+ PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
+
+ KdPrint2((PRINT_PREFIX
+ " INQUIRY\n"));
+ // Zero INQUIRY data structure.
+ RtlZeroMemory((PCHAR)(Srb->DataBuffer), Srb->DataTransferLength);
+
+ inquiryData->DeviceType = COMMUNICATION_DEVICE;
+
+ // Fill in vendor identification fields.
+ RtlCopyMemory(&inquiryData->VendorId, &uniata_comm_name, 28);
+
+ status = SRB_STATUS_SUCCESS;
+ goto complete_req;
+ }
+ commPort = TRUE;
+ /* Pass IOCTL request down */
+ } else
if(GET_CDEV(Srb) >= 2 ||
ldev >= deviceExtension->NumberChannels*2 ||
lChannel >= deviceExtension->NumberChannels ||
reject_srb:
//if(!CheckDevice(HwDeviceExtension, lChannel, ldev & 1, FALSE)) {
- KdPrint2((PRINT_PREFIX
+ KdPrint3((PRINT_PREFIX
"AtapiStartIo: SRB rejected\n"));
// Indicate no device found at this address.
KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
atapiDev = (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
#ifdef _DEBUG
- if(!(chan->lun[ldev & 1])) {
+ if(!commPort && !(chan->lun[ldev & 1])) {
+#if 0
PrintNtConsole("de = %#x, chan = %#x , dev %#x, nchan %#x\n",
deviceExtension,
chan, ldev & 1,
lChannel, ldev, GET_CDEV(Srb), deviceExtension->chan[0].lun[0]);
PrintNtConsole("Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
Srb->Function, Srb->PathId, Srb->Lun, Srb->TargetId);
+#endif //0
/*
int i;
for(i=0; i<1000; i++) {
goto reject_srb;
}
#endif //_DEBUG
- //ASSERT(chan->lun[ldev & 1]);
// Determine which function.
switch (Srb->Function) {
} else {
//if(!CheckDevice(HwDeviceExtension, lChannel, ldev & 1, FALSE)) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiStartIo: EXECUTE_SCSI rejected (2)\n"));
// Indicate no device found at this address.
KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
g_foo += a;
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
- KdPrint2((PRINT_PREFIX
+ KdPrint3((PRINT_PREFIX
"AtapiStartIo: Bad data buffer -> EXECUTE_SCSI rejected\n"));
// Indicate no device found at this address.
- KdPrint2((PRINT_PREFIX "SRB_STATUS_ERROR\n"));
+ KdPrint3((PRINT_PREFIX "SRB_STATUS_ERROR\n"));
status = SRB_STATUS_ERROR;
KdPrint2((PRINT_PREFIX " *** Exception...\n"));
ASSERT(FALSE);
if(PostReq) {
- KdPrint2((PRINT_PREFIX "Non-empty queue\n"));
+ KdPrint3((PRINT_PREFIX "Non-empty queue\n"));
if (atapiDev &&
(Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) {
- KdPrint2((PRINT_PREFIX "Try ATAPI prepare\n"));
+ KdPrint3((PRINT_PREFIX "Try ATAPI prepare\n"));
status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
} else {
}
/*KeBugCheckEx(0xc000000e,
(Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
- Srb->Function,
+ Srb->Function,
status, 0x80000001);*/
if(status == SRB_STATUS_BUSY)
status = SRB_STATUS_PENDING;
//ASSERT(!AtaReq->Flags);
}
+#ifndef NAVO_TEST
if(!(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
if(UniataAnybodyHome(deviceExtension, chan->lChannel, ldev & 1)) {
goto reject_srb;
}
}
+#endif //NAVO_TEST
if(atapiDev &&
(Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) {
- KdPrint2((PRINT_PREFIX "Try ATAPI send\n"));
+ KdPrint3((PRINT_PREFIX "Try ATAPI send\n"));
status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
} else {
KdPrint2((PRINT_PREFIX "Try IDE send\n"));
}
/* KeBugCheckEx(0xc000000e,
(Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
- Srb->Function,
+ Srb->Function,
status, 0x80000002);*/
}
if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_CURRENT)) {
KdPrint2((PRINT_PREFIX "AtapiStartIo: Abort command failed\n"));
// Log reset failure.
- KdPrint2((PRINT_PREFIX
+ KdPrint3((PRINT_PREFIX
"ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
));
break;
case SRB_FUNCTION_RESET_BUS:
-
+do_bus_reset:
// Reset Atapi and SCSI bus.
// Note: reset is immediate command, it cannot be queued since it is usually used to
if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_ALL)) {
KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus failed\n"));
// Log reset failure.
- KdPrint2((PRINT_PREFIX
+ KdPrint3((PRINT_PREFIX
"ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d) - (2)\n",
HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
));
0, ATA_C_F_DIS_WCACHE, ATA_WAIT_BASE_READY);
// Check for errors.
if (status & IDE_STATUS_ERROR) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiHwInitialize: Disable write cacheing on Device %d failed\n",
ldev));
}
0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_BASE_READY);
// Check for errors.
if (status & IDE_STATUS_ERROR) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
ldev));
deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
deviceNumber = versionParameters->bIDEDeviceMap;
+ if(commPort) {
+ KdPrint2((PRINT_PREFIX
+ "AtapiStartIo: SCSIDISK IOCTL for commPort -> EXECUTE_SCSI rejected (2)\n"));
+ // Indicate no device found at this address.
+ KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
+ status = SRB_STATUS_SELECTION_TIMEOUT;
+ break;
+ }
+
if (!(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT) ||
atapiDev) {
case IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES:
case IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS:
+ if(commPort) {
+ KdPrint2((PRINT_PREFIX
+ "AtapiStartIo: SCSIDISK Smart IOCTL for commPort -> EXECUTE_SCSI rejected (3)\n"));
+ // Indicate no device found at this address.
+ KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
+ status = SRB_STATUS_SELECTION_TIMEOUT;
+ break;
+ }
+
PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
if(PostReq || TopLevel) {
PUNIATA_CTL AtaCtl = (PUNIATA_CTL)(Srb->DataBuffer);
ULONG ldev = GET_LDEV2(AtaCtl->addr.PathId, AtaCtl->addr.TargetId, 0);
- PHW_LU_EXTENSION LunExt = &(deviceExtension->lun[ldev]);
+ PHW_LU_EXTENSION LunExt;
BOOLEAN bad_ldev;
ULONG i;
//chan = &(deviceExtension->chan[lChannel]);
if(AtaCtl->addr.Lun ||
ldev >= deviceExtension->NumberChannels*2 ||
- AtaCtl->addr.PathId > deviceExtension->NumberChannels) {
+ AtaCtl->addr.PathId >= deviceExtension->NumberChannels) {
bad_ldev = TRUE;
LunExt = NULL;
} else {
bad_ldev = FALSE;
LunExt = &(deviceExtension->lun[ldev]);
+ lChannel = AtaCtl->addr.PathId;
+ chan = &(deviceExtension->chan[lChannel]);
}
KdPrint2((PRINT_PREFIX "AtapiStartIo: -UNIATA- %#x, ldev %#x\n", AtaCtl->hdr.ControlCode, ldev));
/* check for valid LUN */
switch (AtaCtl->hdr.ControlCode) {
case IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES:
+ case IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE:
+ if(bad_ldev &&
+ (AtaCtl->addr.PathId >= deviceExtension->NumberChannels ||
+ AtaCtl->addr.TargetId != 0xff ||
+ AtaCtl->addr.Lun != 0
+ )) {
+ if(AtaCtl->hdr.ControlCode == IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES &&
+ ldev < deviceExtension->NumberChannels*2) { // AtaCtl->addr.TargetId != 0xff
+ LunExt = &(deviceExtension->lun[ldev]);
+ // OK
+ } else {
+ goto handle_bad_ldev;
+ }
+ }
+ // this would be BUS reset
+ lChannel = AtaCtl->addr.PathId;
+ chan = &(deviceExtension->chan[lChannel]);
+ break;
case IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE:
case IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE:
case IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE:
case IOCTL_SCSI_MINIPORT_UNIATA_RESETBB:
- case IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE:
+// case IOCTL_SCSI_MINIPORT_UNIATA_REG_IO:
if(bad_ldev) {
+handle_bad_ldev:
KdPrint2((PRINT_PREFIX
"AtapiStartIo: bad_ldev -> IOCTL SRB rejected\n"));
// Indicate no device found at this address.
KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
goto complete_req;
- }
- }
+ }
+ } // end switch (AtaCtl->hdr.ControlCode)
/* process request */
switch (AtaCtl->hdr.ControlCode) {
KdPrint2((PRINT_PREFIX "AtapiStartIo: rescan bus\n"));
+ if(AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE) {
+ KdPrint2((PRINT_PREFIX "AtapiStartIo: unhide from further detection\n"));
+ if(AtaCtl->addr.TargetId != 0xff) {
+ deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_HIDDEN;
+ } else {
+ }
+ }
+
for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
AtapiStallExecution(1000 * 1000);
}
- FindDevices(HwDeviceExtension, FALSE, AtaCtl->addr.PathId);
+ FindDevices(HwDeviceExtension,
+ ((AtaCtl->addr.TargetId == 0xff) && (AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE))
+ ? UNIATA_FIND_DEV_UNHIDE : 0,
+ AtaCtl->addr.PathId);
status = SRB_STATUS_SUCCESS;
break;
KdPrint2((PRINT_PREFIX "AtapiStartIo: remove %#x:%#x\n", AtaCtl->addr.PathId, AtaCtl->addr.TargetId));
deviceExtension->lun[ldev].DeviceFlags = 0;
+ if(AtaCtl->FindDelDev.Flags & UNIATA_REMOVE_FLAGS_HIDE) {
+ KdPrint2((PRINT_PREFIX "AtapiStartIo: hide from further detection\n"));
+ deviceExtension->lun[ldev].DeviceFlags |= DFLAGS_HIDDEN;
+ }
for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
AtapiStallExecution(1000 * 1000);
KdPrint2((PRINT_PREFIX "AtapiStartIo: Set transfer mode\n"));
- if(AtaCtl->SetMode.OrigMode != -1) {
+ if(AtaCtl->SetMode.OrigMode != IOMODE_NOT_SPECIFIED) {
LunExt->OrigTransferMode = (UCHAR)(AtaCtl->SetMode.OrigMode);
}
- if(AtaCtl->SetMode.MaxMode != -1) {
+ if(AtaCtl->SetMode.MaxMode != IOMODE_NOT_SPECIFIED) {
LunExt->LimitedTransferMode = (UCHAR)(AtaCtl->SetMode.MaxMode);
if(LunExt->LimitedTransferMode >
LunExt->OrigTransferMode) {
LunExt->OrigTransferMode;
}
}
- LunExt->TransferMode = LunExt->OrigTransferMode;
+ LunExt->TransferMode = min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode);
LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit
if(AtaCtl->SetMode.ApplyImmediately) {
AtaCtl->AdapterInfo.InterruptMode = deviceExtension->InterruptMode;
AtaCtl->AdapterInfo.BusInterruptVector = deviceExtension->BusInterruptVector;
AtaCtl->AdapterInfo.NumberChannels = deviceExtension->NumberChannels;
-
+ AtaCtl->AdapterInfo.AdapterInterfaceType = deviceExtension->AdapterInterfaceType;
+ if(deviceExtension->FullDevName) {
+ strncpy(AtaCtl->AdapterInfo.DeviceName, deviceExtension->FullDevName, 64);
+ }
AtaCtl->AdapterInfo.ChanInfoValid = FALSE;
RtlZeroMemory(&AtaCtl->AdapterInfo.Chan, sizeof(AtaCtl->AdapterInfo.Chan));
break;
}
case IOCTL_SCSI_MINIPORT_UNIATA_RESETBB: {
-
+
KdPrint2((PRINT_PREFIX "AtapiStartIo: Forget BB list\n"));
ForgetBadBlocks(LunExt);
KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device\n"));
- UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId, ldev);
+ if(bad_ldev) {
+ goto do_bus_reset;
+ } else {
+ UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId, ldev);
+ }
status = SRB_STATUS_SUCCESS;
break;
if (status != SRB_STATUS_PENDING) {
- KdPrint2((PRINT_PREFIX
+ KdPrint2((PRINT_PREFIX
"AtapiStartIo: Srb %#x complete with status %#x\n",
Srb,
status));
Srb);
// Remove current Srb & get next one
- if(Srb = UniataGetCurRequest(chan)) {
+ if((Srb = UniataGetCurRequest(chan))) {
AtaReq = (PATA_REQ)(Srb->SrbExtension);
if(AtaReq->ReqState > REQ_STATE_QUEUED) {
// current request is under precessing, thus
NULL);
ScsiPortNotification(NextLuRequest,
- deviceExtension,
+ deviceExtension,
PathId,
TargetId,
Lun);
void
+NTAPI
UniataInitAtaCommands()
{
int i;
UCHAR command;
UCHAR flags;
- for(i=0, command=0; i<256; i++, command++) {
+ KdPrint2((PRINT_PREFIX "UniataInitAtaCommands:\n"));
+
+ for(i=0; i<256; i++) {
+
+ flags = 0;
+ command = i;
+
+ KdPrint2((PRINT_PREFIX "cmd %2.2x: ", command));
switch(command) {
case IDE_COMMAND_READ_DMA48:
case IDE_COMMAND_WRITE_LOG_DMA48:
case IDE_COMMAND_TRUSTED_RCV_DMA:
case IDE_COMMAND_TRUSTED_SEND_DMA:
+ KdPrint2((PRINT_PREFIX "DMA "));
flags |= ATA_CMD_FLAG_DMA;
}
case IDE_COMMAND_FLUSH_CACHE48:
case IDE_COMMAND_VERIFY48:
+ KdPrint2((PRINT_PREFIX "48 "));
flags |= ATA_CMD_FLAG_48;
/* FALL THROUGH */
case IDE_COMMAND_FLUSH_CACHE:
case IDE_COMMAND_VERIFY:
+ KdPrint2((PRINT_PREFIX "LBA "));
flags |= ATA_CMD_FLAG_LBAIOsupp;
}
command = IDE_COMMAND_WRITE_DMA_Q48; break;
case IDE_COMMAND_FLUSH_CACHE:
command = IDE_COMMAND_FLUSH_CACHE48; break;
- case IDE_COMMAND_READ_NATIVE_SIZE:
+ // case IDE_COMMAND_READ_NATIVE_SIZE:
// command = IDE_COMMAND_READ_NATIVE_SIZE48; break;
case IDE_COMMAND_SET_NATIVE_SIZE:
command = IDE_COMMAND_SET_NATIVE_SIZE48; break;
case IDE_COMMAND_VERIFY:
command = IDE_COMMAND_VERIFY48; break;
default:
+ KdPrint2((PRINT_PREFIX "!28->48 "));
flags &= ~ATA_CMD_FLAG_48supp;
}
+ KdPrint2((PRINT_PREFIX "\t -> %2.2x (%2.2x)\n", command, flags));
AtaCommands48[i] = command;
AtaCommandFlags[i] = flags;
}
PUNICODE_STRING RegistryPath = (PUNICODE_STRING)Argument2;
BOOLEAN ReEnter = FALSE;
WCHAR a;
- NTSTATUS status;
PCONFIGURATION_INFORMATION GlobalConfig = IoGetConfigurationInformation();
BOOLEAN PrimaryClaimed = FALSE;
LARGE_INTEGER t0, t1;
Connect_DbgPrint();
- KdPrint2((PRINT_PREFIX (PCCHAR)ver_string));
+ KdPrint2((PRINT_PREFIX "%s", (PCCHAR)ver_string));
a = (WCHAR)strlen(ver_string);
g_opt_Verbose = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PrintLogo", 0);
if(!SavedDriverObject) {
SavedDriverObject = (PDRIVER_OBJECT)DriverObject;
- // we are here for the 1st time
- // init CrossNT and get OS version
- if(!NT_SUCCESS(status = CrNtInit(SavedDriverObject, RegistryPath))) {
- KdPrint(("UniATA Init: CrNtInit failed with status %#x\n", status));
- //HalDisplayString((PUCHAR)"DbgPrnHkInitialize: CrNtInit failed\n");
- return status;
- }
- KdPrint(("UniATA Init: OS ver %x.%x (%d)\n", MajorVersion, MinorVersion, BuildNumber));
+ KdPrint(("UniATA Init: OS should be ReactOS\n"));
KeQuerySystemTime(&t0);
do {
KdPrint(("Performance calibration: dt=%d, counter=%I64d\n", g_PerfDt, g_Perf ));
} else {
+ KdPrint(("UniATA Init: ReEnter\n"));
ReEnter = TRUE;
}
SavedRegPath.Buffer[SavedRegPath.Length/sizeof(WCHAR)] = 0;
}
+ if(WinVer_Id() >= WinVer_2k) {
+ if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"1", 0)) {
+ KdPrint(("UniATA: Behave as WDM, mlia (1)\n"));
+ WinVer_WDM_Model = TRUE;
+ }
+ if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"5", 0)) {
+ KdPrint(("UniATA: Behave as WDM, mlia (5)\n"));
+ WinVer_WDM_Model = TRUE;
+ }
+ }
+
SkipRaids = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"SkipRaids", 1);
ForceSimplex = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", 0);
#ifdef _DEBUG
sizeof(hwInitializationData.comm) +
// sizeof(hwInitializationData.nt4) +
((WinVer_Id() <= WinVer_NT) ? 0 : sizeof(hwInitializationData.w2k));
+ KdPrint(("HwInitializationDataSize = %x\n", hwInitializationData.comm.HwInitializationDataSize));
// Set entry points.
- hwInitializationData.comm.HwInitialize = AtapiHwInitialize;
- hwInitializationData.comm.HwResetBus = AtapiResetController;
- hwInitializationData.comm.HwStartIo = AtapiStartIo;
- hwInitializationData.comm.HwInterrupt = AtapiInterrupt;
+ hwInitializationData.comm.HwInitialize = (PHW_INITIALIZE)AtapiHwInitialize;
+ hwInitializationData.comm.HwResetBus = (PHW_RESET_BUS)AtapiResetController;
+ hwInitializationData.comm.HwStartIo = (PHW_STARTIO)AtapiStartIo;
+ hwInitializationData.comm.HwInterrupt = (PHW_INTERRUPT)AtapiInterrupt;
// Specify size of extensions.
hwInitializationData.comm.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
hwInitializationData.comm.MapBuffers = TRUE;
// Set PnP-specific API
if(WinVer_Id() > WinVer_NT) {
+ KdPrint(("set NeedPhysicalAddresses = TRUE\n"));
hwInitializationData.comm.NeedPhysicalAddresses = TRUE;
- hwInitializationData.w2k.HwAdapterControl = AtapiAdapterControl;
+ KdPrint(("set AtapiAdapterControl() ptr\n"));
+ hwInitializationData.w2k.HwAdapterControl = (PHW_ADAPTER_CONTROL)AtapiAdapterControl;
}
KdPrint2((PRINT_PREFIX "\n\nATAPI IDE enum supported BusMaster Devices\n"));
if(g_opt_Verbose) {
_PrintNtConsole("Init standard Dual-channel PCI ATA controller:");
}
- for(alt = 0; alt < 2; alt++) {
+ for(alt = 0; alt < (ULONG)(WinVer_WDM_Model ? 1 : 2) ; alt++) {
for(c=0; c<2; c++) {
}
}
- if((WinVer_Id() <= WinVer_NT)) {
+ if((WinVer_Id() < WinVer_2k)) {
// do not even try if already claimed
if(c==0) {
GlobalConfig->AtDiskPrimaryAddressClaimed = FALSE;
GlobalConfig->AtDiskSecondaryAddressClaimed = FALSE;
}
}
- hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController;
+ if(!WinVer_WDM_Model) {
+ hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController;
+ } else {
+ // in WDM model things are different....
+ hwInitializationData.comm.HwFindAdapter = (c == 0) ?
+ UniataFindCompatBusMasterController1 : UniataFindCompatBusMasterController2;
+ }
hwInitializationData.comm.NumberOfAccessRanges = 6;
hwInitializationData.comm.AdapterInterfaceType = Isa;
- BMList[i].channel = (UCHAR)c;
+ if(!WinVer_WDM_Model) {
+ BMList[i].channel = (UCHAR)c;
+ }
KdPrint2((PRINT_PREFIX "Try init channel %d, method %d\n", c, alt));
newStatus = ScsiPortInitialize(DriverObject,
*/
}
}
- if(WinVer_Id() > WinVer_NT) {
+ if(WinVer_Id() >= WinVer_2k) {
// the following doesn't work under higher OSes
KdPrint2((PRINT_PREFIX "make still one attempt\n"));
continue;
}
// if (WinVer_Id() == WinVer_NT) and some error occured
// try alternative init method
+ } // for(alt...)
+#if 0
+ if(WinVer_WDM_Model) {
+ hwInitializationData.comm.HwFindAdapter = UniataFindFakeBusMasterController;
+ hwInitializationData.comm.NumberOfAccessRanges = 5;
+ hwInitializationData.comm.AdapterInterfaceType = PCIBus;
+
+ hwInitializationData.comm.VendorId = BMList[i].VendorId;
+ hwInitializationData.comm.VendorIdLength = (USHORT) BMList[i].VendorIdLength;
+ hwInitializationData.comm.DeviceId = BMList[i].DeviceId;
+ hwInitializationData.comm.DeviceIdLength = (USHORT) BMList[i].DeviceIdLength;
+
+ //BMList[i].channel = 0/*(UCHAR)c*/;
+
+ KdPrint2((PRINT_PREFIX "Try init fake: %4.4s %4.4s \n",
+ hwInitializationData.comm.VendorId,
+ hwInitializationData.comm.DeviceId));
+ newStatus = ScsiPortInitialize(DriverObject,
+ Argument2,
+ &hwInitializationData.comm,
+ (PVOID)i);
+ KdPrint2((PRINT_PREFIX "Status %#x\n", newStatus));
}
+#endif //0
if(g_opt_Verbose) {
if(BMList[i].ChanInitOk & 0x03) {
_PrintNtConsole(" OK\n");
/* KeBugCheckEx(0xc000000e,
(i << 16) | BMList[0].ChanInitOk,
- c,
+ c,
newStatus, statusToReturn);*/
// Look for PCI IDE controller
PSCSI_REQUEST_BLOCK
+NTAPI
BuildMechanismStatusSrb(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
#endif //UNIATA_CORE
PSCSI_REQUEST_BLOCK
+NTAPI
BuildRequestSenseSrb (
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
#ifndef UNIATA_CORE
ULONG
+NTAPI
AtapiRegCheckDevLunValue(
IN PVOID HwDeviceExtension,
- IN PWCHAR NamePrefix,
+ IN PCWCH NamePrefix,
IN ULONG chan,
IN ULONG dev,
- IN PWSTR Name,
+ IN PCWSTR Name,
IN ULONG Default
)
{
} // end AtapiRegCheckDevLunValue()
ULONG
+NTAPI
EncodeVendorStr(
OUT PWCHAR Buffer,
IN PUCHAR Str,
} // end EncodeVendorStr()
ULONG
+NTAPI
AtapiRegCheckDevValue(
IN PVOID HwDeviceExtension,
IN ULONG chan,
IN ULONG dev,
- IN PWSTR Name,
+ IN PCWSTR Name,
IN ULONG Default
)
{
HwDeviceExtension, L"Parameters", chan, dev, Name, val);
if(deviceExtension) {
- swprintf(namev, L"\\Ven_%4.4x", VendorID);
- swprintf(named, L"\\Dev_%4.4x", DeviceID);
- swprintf(names, L"\\Slot_%8.8x", SlotNumber);
+ if(deviceExtension->AdapterInterfaceType == PCIBus) {
+ // PCI
+ swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex);
+ swprintf(namex, L"Parameters%s", namev);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+
- swprintf(namex, L"Parameters%s", namev);
- val = AtapiRegCheckDevLunValue(
- HwDeviceExtension, namex, chan, dev, Name, val);
+ swprintf(namev, L"\\Ven_%4.4x", VendorID);
+ swprintf(named, L"\\Dev_%4.4x", DeviceID);
+ swprintf(names, L"\\Slot_%8.8x", SlotNumber);
- swprintf(namex, L"Parameters%s%s", namev, named);
- val = AtapiRegCheckDevLunValue(
- HwDeviceExtension, namex, chan, dev, Name, val);
+ swprintf(namex, L"Parameters%s", namev);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
- swprintf(namex, L"Parameters%s%s%s", namev, named, names);
- val = AtapiRegCheckDevLunValue(
- HwDeviceExtension, namex, chan, dev, Name, val);
+ swprintf(namex, L"Parameters%s%s", namev, named);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+
+ swprintf(namex, L"Parameters%s%s%s", namev, named, names);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+ } else
+ if(deviceExtension->AdapterInterfaceType == Isa) {
+ // Isa
+ swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen);
+ swprintf(namex, L"Parameters%s", namev);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+
+ swprintf(namev, L"\\ISA_%d", deviceExtension->DevIndex);
+ swprintf(namex, L"Parameters%s", namev);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+
+ } else
+ if(deviceExtension->AdapterInterfaceType == MicroChannel) {
+ // MicroChannel
+ swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen+IsaCount);
+ swprintf(namex, L"Parameters%s", namev);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+
+ swprintf(namev, L"\\MCA_%d", deviceExtension->DevIndex);
+ swprintf(namex, L"Parameters%s", namev);
+ val = AtapiRegCheckDevLunValue(
+ HwDeviceExtension, namex, chan, dev, Name, val);
+
+ }
}
KdPrint(( " Parameter %ws = %#x\n", Name, val));
Returns: Registry Key value
*/
ULONG
+NTAPI
AtapiRegCheckParameterValue(
IN PVOID HwDeviceExtension,
- IN PWSTR PathSuffix,
- IN PWSTR Name,
+ IN PCWSTR PathSuffix,
+ IN PCWSTR Name,
IN ULONG Default
)
{
status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
paramPath.Buffer, parameters, NULL, NULL);
- KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
+ //KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
ExFreePool(paramPath.Buffer);
AtapiResetController(deviceExtension, c);
AtapiDisableInterrupts(deviceExtension, c);
}
- status = UniataDisconnectIntr2(HwDeviceExtension);
- BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
+ if(deviceExtension->AdapterInterfaceType == PCIBus) {
+ // we must never get here for non-PCI
+ status = UniataDisconnectIntr2(HwDeviceExtension);
+ BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
+ }
break;
}
case ScsiRestartAdapter: {
status = UniataConnectIntr2(HwDeviceExtension);
for (c = 0; c < numberChannels; c++) {
AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
- FindDevices(HwDeviceExtension, FALSE, c);
+ FindDevices(HwDeviceExtension, 0, c);
AtapiEnableInterrupts(deviceExtension, c);
AtapiHwInitialize__(deviceExtension, c);
}
if(deviceExtension->Isr2DevObj) {
+ // we must never get here for non-PCI
BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
}
VOID
_cdecl
_PrintNtConsole(
- PCHAR DebugMessage,
+ PCCH DebugMessage,
...
)
{
} // end PrintNtConsole()
+