From 4b9cf2e33949a107fe6567632f1ac066c44a9d2c Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 3 May 2016 21:16:08 +0000 Subject: [PATCH] [UNIATA] - Update to 0.46d7. CORE-11157 svn path=/trunk/; revision=71252 --- .../drivers/storage/ide/uniata/CMakeLists.txt | 4 +- .../drivers/storage/ide/uniata/atacmd_map.cpp | 39 + .../drivers/storage/ide/uniata/atacmd_map.h | 43 + reactos/drivers/storage/ide/uniata/atapi.h | 72 +- .../drivers/storage/ide/uniata/bm_devs.cpp | 39 + reactos/drivers/storage/ide/uniata/bm_devs.h | 748 +---------------- .../drivers/storage/ide/uniata/bm_devs_decl.h | 789 ++++++++++++++++++ reactos/drivers/storage/ide/uniata/bsmaster.h | 17 +- reactos/drivers/storage/ide/uniata/id_ata.cpp | 751 +++++++++++------ reactos/drivers/storage/ide/uniata/id_dma.cpp | 152 +++- .../drivers/storage/ide/uniata/id_init.cpp | 73 +- .../drivers/storage/ide/uniata/id_probe.cpp | 361 +++++--- .../drivers/storage/ide/uniata/id_queue.cpp | 4 + .../drivers/storage/ide/uniata/id_sata.cpp | 63 +- reactos/drivers/storage/ide/uniata/id_sata.h | 3 + reactos/drivers/storage/ide/uniata/stdafx.cpp | 1 + reactos/drivers/storage/ide/uniata/tools.h | 3 + reactos/drivers/storage/ide/uniata/uata_ctl.h | 3 + .../drivers/storage/ide/uniata/uniata_ver.h | 18 +- 19 files changed, 1941 insertions(+), 1242 deletions(-) create mode 100644 reactos/drivers/storage/ide/uniata/atacmd_map.cpp create mode 100644 reactos/drivers/storage/ide/uniata/atacmd_map.h create mode 100644 reactos/drivers/storage/ide/uniata/bm_devs.cpp create mode 100644 reactos/drivers/storage/ide/uniata/bm_devs_decl.h create mode 100644 reactos/drivers/storage/ide/uniata/stdafx.cpp diff --git a/reactos/drivers/storage/ide/uniata/CMakeLists.txt b/reactos/drivers/storage/ide/uniata/CMakeLists.txt index 5bb208d63c1..73c9a1e9abb 100644 --- a/reactos/drivers/storage/ide/uniata/CMakeLists.txt +++ b/reactos/drivers/storage/ide/uniata/CMakeLists.txt @@ -8,6 +8,8 @@ include_directories( #add_definitions(-D_DEBUG) list(APPEND SOURCE + atacmd_map.cpp + bm_devs.cpp id_ata.cpp id_badblock.cpp id_dma.cpp @@ -16,7 +18,7 @@ list(APPEND SOURCE id_queue.cpp id_sata.cpp ros_glue/ros_glue.cpp - stdafx.h) + stdafx.cpp) add_library(uniata SHARED ${SOURCE} idedma.rc) diff --git a/reactos/drivers/storage/ide/uniata/atacmd_map.cpp b/reactos/drivers/storage/ide/uniata/atacmd_map.cpp new file mode 100644 index 00000000000..30de2dcc6fc --- /dev/null +++ b/reactos/drivers/storage/ide/uniata/atacmd_map.cpp @@ -0,0 +1,39 @@ +/*++ + +Copyright (c) 2016 Alexandr A. Telyatnikov (Alter) + +Module Name: + bm_devs.cpp + +Abstract: + This file contains stub for pre-generated ATA command map and flags + +Author: + Alexander A. Telyatnikov (Alter) + +Environment: + kernel and user mode + +Notes: + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Revision History: + +Licence: + GPLv2 + +--*/ + +#include "stdafx.h" +#include "atacmd_map.h" + diff --git a/reactos/drivers/storage/ide/uniata/atacmd_map.h b/reactos/drivers/storage/ide/uniata/atacmd_map.h new file mode 100644 index 00000000000..dc3fa9a793b --- /dev/null +++ b/reactos/drivers/storage/ide/uniata/atacmd_map.h @@ -0,0 +1,43 @@ + +// Build Version 0.46d7 + + +UCHAR const AtaCommands48[256] = { +0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf +, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f +, 0x24, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f +, 0x34, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f +, 0x42, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f +, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f +, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f +, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f +, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f +, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf +, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf +, 0xc0, 0xc1, 0xc2, 0xc3, 0x29, 0x39, 0xc6, 0x26, 0x25, 0xc9, 0x35, 0xcb, 0x36, 0xcd, 0xce, 0xcf +, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf +, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xea, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef +, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0x37, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + + +UCHAR const AtaCommandFlags[256] = { +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x3, 0x0, 0x0, 0x0, 0x5, 0x4d, 0x4d, 0x15, 0x0, 0x5, 0x4d, 0x4d, 0x0, 0x0, 0x0, 0x0 +, 0x3, 0x0, 0x0, 0x0, 0x5, 0x8d, 0x8d, 0x15, 0x0, 0x5, 0x8d, 0x8d, 0x0, 0x9d, 0x9d, 0x0 +, 0x3, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0x0, 0x8 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x4b, 0x4b, 0x0, 0x8b, 0x0, 0x8b, 0x0, 0x15, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x5, 0x0, 0x40, 0x0, 0x0, 0x0 +, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + diff --git a/reactos/drivers/storage/ide/uniata/atapi.h b/reactos/drivers/storage/ide/uniata/atapi.h index 6952de2da16..f90f0d7fdf6 100644 --- a/reactos/drivers/storage/ide/uniata/atapi.h +++ b/reactos/drivers/storage/ide/uniata/atapi.h @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter) Module Name: atapi.h @@ -37,7 +37,10 @@ Revision History: Søren Schmidt, Copyright (c) 1998,1999,2000,2001 Code was changed/updated by - Alter, Copyright (c) 2002-2004 + Alter, Copyright (c) 2002-20016 + +Licence: + GPLv2 --*/ @@ -211,21 +214,21 @@ typedef union _IDE_REGISTERS_1 { #define IDX_IO1_o_DriveSelect (FIELD_OFFSET(IDE_REGISTERS_1, o.DriveSelect )+IDX_IO1_o) #define IDX_IO1_o_Command (FIELD_OFFSET(IDE_REGISTERS_1, o.Command )+IDX_IO1_o) -typedef struct _IDE_REGISTERS_2 { +typedef union _IDE_REGISTERS_2 { UCHAR AltStatus; - UCHAR DriveAddress; + UCHAR Control; } IDE_REGISTERS_2, *PIDE_REGISTERS_2; #define IDX_IO2 (IDX_IO1_o+IDX_IO1_o_SZ) #define IDX_IO2_SZ sizeof(IDE_REGISTERS_2) #define IDX_IO2_AltStatus (FIELD_OFFSET(IDE_REGISTERS_2, AltStatus )+IDX_IO2) -#define IDX_IO2_DriveAddress (FIELD_OFFSET(IDE_REGISTERS_2, DriveAddress)+IDX_IO2) +//#define IDX_IO2_DriveAddress (FIELD_OFFSET(IDE_REGISTERS_2, DriveAddress)+IDX_IO2) #define IDX_IO2_o (IDX_IO2+IDX_IO2_SZ) #define IDX_IO2_o_SZ sizeof(IDE_REGISTERS_2) -#define IDX_IO2_o_Control (FIELD_OFFSET(IDE_REGISTERS_2, AltStatus )+IDX_IO2_o) +#define IDX_IO2_o_Control (FIELD_OFFSET(IDE_REGISTERS_2, Control)+IDX_IO2_o) // // Device Extension Device Flags // @@ -657,6 +660,7 @@ typedef struct _IDENTIFY_DATA { USHORT StandbyOverlap:1; USHORT SupportQTag:1; /* supports queuing overlap */ USHORT SupportIDma:1; /* interleaved DMA supported */ + /* USHORT Capabilities; // 62 49 #define IDENTIFY_CAPABILITIES_SUPPORT_DMA 0x0100 #define IDENTIFY_CAPABILITIES_SUPPORT_LBA 0x0200 @@ -708,7 +712,7 @@ typedef struct _IDENTIFY_DATA { USHORT UDMASupport : 7; // 62 ATAPI USHORT MultiWordDMASupport : 3; USHORT DMASupport : 1; - USHORT Reaseved62_11_14 : 4; + USHORT Reserved62_11_14 : 4; USHORT DMADirRequired : 1; } AtapiDMA; }; @@ -867,10 +871,28 @@ typedef struct _IDENTIFY_DATA { ULONG LargeSectorSize; // 117-118 - USHORT Reserved119[8]; // 119-126 + struct { + USHORT Reserved; + } CommandFeatureSetSupport, CommandFeatureSetEnabled; // 119-120 + USHORT Reserved121[4]; // 121-124 + USHORT AtapiByteCount0; // 125 + USHORT Reserved126; // 126 USHORT RemovableStatus; // 127 - USHORT SecurityStatus; // 128 + union { + USHORT SecurityStatus; // 128 + struct { + USHORT Support:1; + USHORT Enabled:1; + USHORT Locked:1; + USHORT Frozen:1; + USHORT CountExpired:1; + USHORT EnhancedEraseSupport:1; + USHORT Reserved7_8:2; + USHORT MasterPasswdCap:1; // 0 - high, 1 - max + USHORT Reserved9_15:7; + } SecurityStatusOpt; + }; USHORT Reserved129[31]; // 129-159 USHORT CfAdvPowerMode; // 160 @@ -1073,12 +1095,12 @@ NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = { #define WriteCommand(chan, _Command) \ AtapiWritePort1(chan, IDX_IO1_o_Command, _Command); - +/* #define SelectDrive(chan, unit) { \ if(chan && chan->lun[unit] && chan->lun[unit]->DeviceFlags & DFLAGS_ATAPI_CHANGER) KdPrint3((" Select %d\n", unit)); \ AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (unit) ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); \ } - +*/ #define ReadBuffer(chan, Buffer, Count, timing) \ AtapiReadBuffer2(chan, IDX_IO1_i_Data, \ @@ -1104,6 +1126,13 @@ NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = { Count, \ timing); +UCHAR +DDKFASTAPI +SelectDrive( + IN struct _HW_CHANNEL* chan, + IN ULONG DeviceNumber + ); + UCHAR DDKFASTAPI WaitOnBusy( @@ -1151,7 +1180,15 @@ DDKFASTAPI AtapiSoftReset( IN struct _HW_CHANNEL* chan,/* PIDE_REGISTERS_1 BaseIoAddress*/ - ULONG DeviceNumber + IN ULONG DeviceNumber + ); + +VOID +DDKFASTAPI +AtapiHardReset( + IN struct _HW_CHANNEL* chan, + IN BOOLEAN DisableInterrupts, + IN ULONG Delay ); @@ -1266,7 +1303,7 @@ IdeMediaStatus( ); ULONG NTAPI -AtapiFindController( +AtapiFindIsaController( IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, @@ -1539,6 +1576,8 @@ UniataAnybodyHome( IN ULONG deviceNumber ); +#endif //USER_MODE + #define ATA_AT_HOME_HDD 0x01 #define ATA_AT_HOME_ATAPI 0x02 #define ATA_AT_HOME_XXX 0x04 @@ -1552,9 +1591,6 @@ UniataAnybodyHome( #define ATA_CMD_FLAG_In 0x40 #define ATA_CMD_FLAG_Out 0x80 -extern UCHAR AtaCommands48[256]; -extern UCHAR AtaCommandFlags[256]; - /* We need LBA48 when requested LBA or BlockCount are too large. But for LBA-based commands we have *special* limitation @@ -1563,11 +1599,15 @@ extern UCHAR AtaCommandFlags[256]; ( ((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) && (supp48) && (((lba+count) >= ATA_MAX_IOLBA28) || (count > 256)) ) || \ (lba > ATA_MAX_LBA28) || (count > 255) ) +#ifndef USER_MODE + #define UniAtaClearAtaReq(AtaReq) \ { \ RtlZeroMemory((PCHAR)(AtaReq), FIELD_OFFSET(ATA_REQ, ata)); \ } +extern UCHAR const AtaCommands48[256]; +extern UCHAR const AtaCommandFlags[256]; //#define ATAPI_DEVICE(de, ldev) (de->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE) #define ATAPI_DEVICE(chan, dev) ((chan->lun[dev]->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE) diff --git a/reactos/drivers/storage/ide/uniata/bm_devs.cpp b/reactos/drivers/storage/ide/uniata/bm_devs.cpp new file mode 100644 index 00000000000..fdc834de4e3 --- /dev/null +++ b/reactos/drivers/storage/ide/uniata/bm_devs.cpp @@ -0,0 +1,39 @@ +/*++ + +Copyright (c) 2016 Alexandr A. Telyatnikov (Alter) + +Module Name: + bm_devs.cpp + +Abstract: + This file contains stub for list of 'well known' PCI IDE controllers + +Author: + Alexander A. Telyatnikov (Alter) + +Environment: + kernel and user mode + +Notes: + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Revision History: + +Licence: + GPLv2 + +--*/ + +#include "stdafx.h" +#include "bm_devs.h" + diff --git a/reactos/drivers/storage/ide/uniata/bm_devs.h b/reactos/drivers/storage/ide/uniata/bm_devs.h index 2af61db9864..b4d0923d19b 100644 --- a/reactos/drivers/storage/ide/uniata/bm_devs.h +++ b/reactos/drivers/storage/ide/uniata/bm_devs.h @@ -1,18 +1,19 @@ /*++ -Copyright (c) 2002-2014 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter) Module Name: bm_devs.h Abstract: - This file contains list of 'well known' PCI IDE controllers + This file contains actual list of 'well known' PCI IDE controllers + and must be included only in stub bm_devs.cpp Author: Alexander A. Telyatnikov (Alter) Environment: - kernel mode only + kernel and user mode Notes: @@ -29,695 +30,14 @@ Notes: Revision History: +Licence: + GPLv2 + --*/ -#ifndef __IDE_BUSMASTER_DEVICES_H__ -#define __IDE_BUSMASTER_DEVICES_H__ +#include "bm_devs_decl.h" -#pragma pack(push, 8) - -#define IDE_MAX_CHAN 16 -#define IDE_DEFAULT_MAX_CHAN 2 -// Thanks to SATA Port Multipliers: -//#define IDE_MAX_LUN_PER_CHAN SATA_MAX_PM_UNITS -#define IDE_MAX_LUN_PER_CHAN 2 - -#define IDE_MAX_LUN (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN) - -#define MAX_QUEUE_STAT 8 - -// define PIO timings in nanoseconds -#define PIO0_TIMING 600 - -//#define UniataGetPioTiming(LunExt) ((LunExt->TransferMode <= ATA_PIO0) ? PIO0_TIMING : 0) -#define UniataGetPioTiming(LunExt) 0 //ktp - -/*#ifdef USER_MODE -#define PVEN_STR PCSTR -#else // USER_MODE -#define PVEN_STR PCHAR -#endif // USER_MODE*/ -#define PVEN_STR PCSTR - -typedef struct _BUSMASTER_CONTROLLER_INFORMATION { - PVEN_STR VendorId; - ULONG VendorIdLength; - ULONG nVendorId; - PVEN_STR DeviceId; - ULONG DeviceIdLength; - ULONG nDeviceId; - ULONG nRevId; - ULONG MaxTransferMode; - PVEN_STR FullDevName; - ULONG RaidFlags; - CHAR VendorIdStr[4]; - CHAR DeviceIdStr[4]; - ULONG slotNumber; - ULONG busNumber; - CHAR channel; -// CHAR numOfChannes; - CHAR MasterDev; - BOOLEAN Known; -#ifndef USER_MODE - UCHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary, 0x80 - PciIde claimed - BOOLEAN Isr2Enable; - union { - PDEVICE_OBJECT Isr2DevObj; - PDEVICE_OBJECT PciIdeDevObj; - }; - KIRQL Isr2Irql; - KAFFINITY Isr2Affinity; - ULONG Isr2Vector; - PKINTERRUPT Isr2InterruptObject; - CHAR AltInitMasterDev; // 0xff - uninitialized, 0x00 - normal, 0x01 - change ISA to PCI - CHAR NeedAltInit; // 0x01 - try change ISA to PCI -#endif - -}BUSMASTER_CONTROLLER_INFORMATION, *PBUSMASTER_CONTROLLER_INFORMATION; - -/* defines for known chipset PCI id's */ -#define ATA_ACARD_ID 0x1191 -#define ATA_ATP850 0x00021191 -#define ATA_ATP850A 0x00041191 -#define ATA_ATP850R 0x00051191 -#define ATA_ATP860A 0x00061191 -#define ATA_ATP860R 0x00071191 -#define ATA_ATP865A 0x00081191 -#define ATA_ATP865R 0x00091191 - -#define ATA_ACER_LABS_ID 0x10b9 -#define ATA_ALI_1533 0x153310b9 -#define ATA_ALI_5228 0x522810b9 -#define ATA_ALI_5229 0x522910b9 -#define ATA_ALI_5281 0x528110b9 -#define ATA_ALI_5287 0x528710b9 -#define ATA_ALI_5288 0x528810b9 -#define ATA_ALI_5289 0x528910b9 - -#define ATA_AMD_ID 0x1022 -#define ATA_AMD755 0x74011022 -#define ATA_AMD756 0x74091022 -#define ATA_AMD766 0x74111022 -#define ATA_AMD768 0x74411022 -#define ATA_AMD8111 0x74691022 -#define ATA_AMD5536 0x209a1022 -#define ATA_AMD_HUDSON2_S1 0x78001022 -#define ATA_AMD_HUDSON2_S2 0x78011022 -#define ATA_AMD_HUDSON2_S3 0x78021022 -#define ATA_AMD_HUDSON2_S4 0x78031022 -#define ATA_AMD_HUDSON2_S5 0x78041022 -#define ATA_AMD_HUDSON2 0x780c1022 - -#define ATA_ADAPTEC_ID 0x9005 -#define ATA_ADAPTEC_1420 0x02419005 -#define ATA_ADAPTEC_1430 0x02439005 - -#define ATA_ATI_ID 0x1002 -#define ATA_ATI_IXP200 0x43491002 -#define ATA_ATI_IXP300 0x43691002 -#define ATA_ATI_IXP300_S1 0x436e1002 -#define ATA_ATI_IXP400 0x43761002 -#define ATA_ATI_IXP400_S1 0x43791002 -#define ATA_ATI_IXP400_S2 0x437a1002 -#define ATA_ATI_IXP600 0x438c1002 -#define ATA_ATI_IXP600_S1 0x43801002 -#define ATA_ATI_IXP700 0x439c1002 -#define ATA_ATI_IXP700_S1 0x43901002 -#define ATA_ATI_IXP700_S2 0x43911002 -#define ATA_ATI_IXP700_S3 0x43921002 -#define ATA_ATI_IXP700_S4 0x43931002 -#define ATA_ATI_IXP800_S1 0x43941002 -#define ATA_ATI_IXP800_S2 0x43951002 -#define ATA_ATI_4385 0x43851002 - -#define ATA_CENATEK_ID 0x16ca -#define ATA_CENATEK_ROCKET 0x000116ca - -#define ATA_CYRIX_ID 0x1078 -#define ATA_CYRIX_5530 0x01021078 - -#define ATA_CYPRESS_ID 0x1080 -#define ATA_CYPRESS_82C693 0xc6931080 - -#define ATA_DEC_21150 0x00221011 -#define ATA_DEC_21150_1 0x00231011 - -#define ATA_HIGHPOINT_ID 0x1103 -#define ATA_HPT366 0x00041103 -#define ATA_HPT372 0x00051103 -#define ATA_HPT302 0x00061103 -#define ATA_HPT371 0x00071103 -#define ATA_HPT374 0x00081103 - -#define ATA_INTEL_ID 0x8086 -#define ATA_I960RM 0x09628086 -#define ATA_I82371FB 0x12308086 -#define ATA_I82371SB 0x70108086 -#define ATA_I82371AB 0x71118086 -#define ATA_I82443MX 0x71998086 -#define ATA_I82451NX 0x84ca8086 -#define ATA_I82372FB 0x76018086 -#define ATA_I82801AB 0x24218086 -#define ATA_I82801AA 0x24118086 -#define ATA_I82801BA 0x244a8086 -#define ATA_I82801BA_1 0x244b8086 -#define ATA_I82801CA 0x248a8086 -#define ATA_I82801CA_1 0x248b8086 -#define ATA_I82801DB 0x24cb8086 -#define ATA_I82801DB_1 0x24ca8086 -#define ATA_I82801EB 0x24db8086 -#define ATA_I82801EB_S1 0x24d18086 -#define ATA_I82801EB_R1 0x24df8086 -#define ATA_I6300ESB 0x25a28086 -#define ATA_I6300ESB_S1 0x25a38086 -#define ATA_I6300ESB_R1 0x25b08086 -#define ATA_I63XXESB2 0x269e8086 -#define ATA_I63XXESB2_S1 0x26808086 -#define ATA_I63XXESB2_S2 0x26818086 -#define ATA_I63XXESB2_R1 0x26828086 -#define ATA_I63XXESB2_R2 0x26838086 -#define ATA_I82801FB 0x266f8086 -#define ATA_I82801FB_S1 0x26518086 -#define ATA_I82801FB_R1 0x26528086 -#define ATA_I82801FB_M 0x26538086 -#define ATA_I82801GB 0x27df8086 -#define ATA_I82801GB_S1 0x27c08086 -#define ATA_I82801GB_AH 0x27c18086 -#define ATA_I82801GB_R1 0x27c38086 -#define ATA_I82801GBM_S1 0x27c48086 -#define ATA_I82801GBM_AH 0x27c58086 -#define ATA_I82801GBM_R1 0x27c68086 -#define ATA_I82801HB_S1 0x28208086 -#define ATA_I82801HB_AH6 0x28218086 -#define ATA_I82801HB_R1 0x28228086 -#define ATA_I82801HB_AH4 0x28248086 -#define ATA_I82801HB_S2 0x28258086 -#define ATA_I82801HBM 0x28508086 -#define ATA_I82801HBM_S1 0x28288086 -#define ATA_I82801HBM_S2 0x28298086 -#define ATA_I82801HBM_S3 0x282a8086 -#define ATA_I82801IB_S1 0x29208086 -#define ATA_I82801IB_AH2 0x29218086 -#define ATA_I82801IB_AH6 0x29228086 -#define ATA_I82801IB_AH4 0x29238086 -#define ATA_I82801IB_R1 0x29258086 -#define ATA_I82801IB_S2 0x29268086 -#define ATA_I82801IBM_S1 0x29288086 -#define ATA_I82801IBM_AH 0x29298086 -#define ATA_I82801IBM_R1 0x292a8086 -#define ATA_I82801IBM_S2 0x292d8086 -#define ATA_I82801JIB_S1 0x3a208086 -#define ATA_I82801JIB_AH 0x3a228086 -#define ATA_I82801JIB_R1 0x3a258086 -#define ATA_I82801JIB_S2 0x3a268086 -#define ATA_I82801JD_S1 0x3a008086 -#define ATA_I82801JD_AH 0x3a028086 -#define ATA_I82801JD_R1 0x3a058086 -#define ATA_I82801JD_S2 0x3a068086 -/* -#define ATA_I82801JI_S1 0x3a208086 -#define ATA_I82801JI_AH 0x3a228086 -#define ATA_I82801JI_R1 0x3a258086 -#define ATA_I82801JI_S2 0x3a268086 -*/ -#define ATA_5Series_S1 0x3b208086 -#define ATA_5Series_S2 0x3b218086 -#define ATA_5Series_AH1 0x3b228086 -#define ATA_5Series_AH2 0x3b238086 -#define ATA_5Series_R1 0x3b258086 -#define ATA_5Series_S3 0x3b268086 -#define ATA_5Series_S4 0x3b288086 -#define ATA_5Series_AH3 0x3b298086 -#define ATA_5Series_R2 0x3b2c8086 -#define ATA_5Series_S5 0x3b2d8086 -#define ATA_5Series_S6 0x3b2e8086 -#define ATA_5Series_AH4 0x3b2f8086 - -#define ATA_CPT_S1 0x1c008086 -#define ATA_CPT_S2 0x1c018086 -#define ATA_CPT_AH1 0x1c028086 -#define ATA_CPT_AH2 0x1c038086 -#define ATA_CPT_R1 0x1c048086 -#define ATA_CPT_R2 0x1c058086 -#define ATA_CPT_S3 0x1c088086 -#define ATA_CPT_S4 0x1c098086 - -#define ATA_PBG_S1 0x1d008086 -#define ATA_PBG_AH1 0x1d028086 -#define ATA_PBG_R1 0x1d048086 -#define ATA_PBG_R2 0x1d068086 -#define ATA_PBG_R3 0x28268086 -#define ATA_PBG_S2 0x1d088086 - -#define ATA_PPT_S1 0x1e008086 -#define ATA_PPT_S2 0x1e018086 -#define ATA_PPT_AH1 0x1e028086 -#define ATA_PPT_AH2 0x1e038086 -#define ATA_PPT_R1 0x1e048086 -#define ATA_PPT_R2 0x1e058086 -#define ATA_PPT_R3 0x1e068086 -#define ATA_PPT_R4 0x1e078086 -#define ATA_PPT_S3 0x1e088086 -#define ATA_PPT_S4 0x1e098086 -#define ATA_PPT_R5 0x1e0e8086 -#define ATA_PPT_R6 0x1e0f8086 - -#define ATA_LPT_S1 0x8c008086 -#define ATA_LPT_S2 0x8c018086 -#define ATA_LPT_AH1 0x8c028086 -#define ATA_LPT_AH2 0x8c038086 -#define ATA_LPT_R1 0x8c048086 -#define ATA_LPT_R2 0x8c058086 -#define ATA_LPT_R3 0x8c068086 -#define ATA_LPT_R4 0x8c078086 -#define ATA_LPT_S3 0x8c088086 -#define ATA_LPT_S4 0x8c098086 -#define ATA_LPT_R5 0x8c0e8086 -#define ATA_LPT_R6 0x8c0f8086 - -#define ATA_I31244 0x32008086 -#define ATA_ISCH 0x811a8086 -#define ATA_DH89XXCC 0x23238086 - -#define ATA_COLETOCRK_AH1 0x23a38086 -#define ATA_COLETOCRK_S1 0x23a18086 -#define ATA_COLETOCRK_S2 0x23a68086 - -#define ATA_JMICRON_ID 0x197b -#define ATA_JMB360 0x2360197b -#define ATA_JMB361 0x2361197b -#define ATA_JMB362 0x2362197b -#define ATA_JMB363 0x2363197b -#define ATA_JMB365 0x2365197b -#define ATA_JMB366 0x2366197b -#define ATA_JMB368 0x2368197b - -#define ATA_MARVELL_ID 0x11ab -#define ATA_M88SX5040 0x504011ab -#define ATA_M88SX5041 0x504111ab -#define ATA_M88SX5080 0x508011ab -#define ATA_M88SX5081 0x508111ab -#define ATA_M88SX6041 0x604111ab -#define ATA_M88SX6042 0x604211ab -#define ATA_M88SX6081 0x608111ab -#define ATA_M88SX7042 0x704211ab -#define ATA_M88SE6101 0x610111ab -#define ATA_M88SE6102 0x610211ab -#define ATA_M88SE6111 0x611111ab -#define ATA_M88SE6121 0x612111ab -#define ATA_M88SE6141 0x614111ab -#define ATA_M88SE6145 0x614511ab -#define ATA_M88SE9123 0x91231b4b -#define ATA_MARVELL2_ID 0x1b4b - -#define ATA_MICRON_ID 0x1042 -#define ATA_MICRON_RZ1000 0x10001042 -#define ATA_MICRON_RZ1001 0x10011042 - -#define ATA_NATIONAL_ID 0x100b -#define ATA_SC1100 0x0502100b - -#define ATA_NETCELL_ID 0x169c -#define ATA_NETCELL_SR 0x0044169c - -#define ATA_NVIDIA_ID 0x10de -#define ATA_NFORCE1 0x01bc10de -#define ATA_NFORCE2 0x006510de -#define ATA_NFORCE2_PRO 0x008510de -#define ATA_NFORCE2_PRO_S1 0x008e10de -#define ATA_NFORCE3 0x00d510de -#define ATA_NFORCE3_PRO 0x00e510de -#define ATA_NFORCE3_PRO_S1 0x00e310de -#define ATA_NFORCE3_PRO_S2 0x00ee10de -#define ATA_NFORCE_MCP04 0x003510de -#define ATA_NFORCE_MCP04_S1 0x003610de -#define ATA_NFORCE_MCP04_S2 0x003e10de -#define ATA_NFORCE_CK804 0x005310de -#define ATA_NFORCE_CK804_S1 0x005410de -#define ATA_NFORCE_CK804_S2 0x005510de -#define ATA_NFORCE_MCP51 0x026510de -#define ATA_NFORCE_MCP51_S1 0x026610de -#define ATA_NFORCE_MCP51_S2 0x026710de -#define ATA_NFORCE_MCP55 0x036e10de -#define ATA_NFORCE_MCP55_S1 0x037e10de -#define ATA_NFORCE_MCP55_S2 0x037f10de -#define ATA_NFORCE_MCP61 0x03ec10de -#define ATA_NFORCE_MCP61_S1 0x03e710de -#define ATA_NFORCE_MCP61_S2 0x03f610de -#define ATA_NFORCE_MCP61_S3 0x03f710de -#define ATA_NFORCE_MCP65 0x044810de -#define ATA_NFORCE_MCP65_A0 0x044c10de -#define ATA_NFORCE_MCP65_A1 0x044d10de -#define ATA_NFORCE_MCP65_A2 0x044e10de -#define ATA_NFORCE_MCP65_A3 0x044f10de -#define ATA_NFORCE_MCP65_A4 0x045c10de -#define ATA_NFORCE_MCP65_A5 0x045d10de -#define ATA_NFORCE_MCP65_A6 0x045e10de -#define ATA_NFORCE_MCP65_A7 0x045f10de -#define ATA_NFORCE_MCP67 0x056010de -#define ATA_NFORCE_MCP67_A0 0x055010de -#define ATA_NFORCE_MCP67_A1 0x055110de -#define ATA_NFORCE_MCP67_A2 0x055210de -#define ATA_NFORCE_MCP67_A3 0x055310de -#define ATA_NFORCE_MCP67_A4 0x055410de -#define ATA_NFORCE_MCP67_A5 0x055510de -#define ATA_NFORCE_MCP67_A6 0x055610de -#define ATA_NFORCE_MCP67_A7 0x055710de -#define ATA_NFORCE_MCP67_A8 0x055810de -#define ATA_NFORCE_MCP67_A9 0x055910de -#define ATA_NFORCE_MCP67_AA 0x055A10de -#define ATA_NFORCE_MCP67_AB 0x055B10de -#define ATA_NFORCE_MCP67_AC 0x058410de -#define ATA_NFORCE_MCP73 0x056c10de -#define ATA_NFORCE_MCP73_A0 0x07f010de -#define ATA_NFORCE_MCP73_A1 0x07f110de -#define ATA_NFORCE_MCP73_A2 0x07f210de -#define ATA_NFORCE_MCP73_A3 0x07f310de -#define ATA_NFORCE_MCP73_A4 0x07f410de -#define ATA_NFORCE_MCP73_A5 0x07f510de -#define ATA_NFORCE_MCP73_A6 0x07f610de -#define ATA_NFORCE_MCP73_A7 0x07f710de -#define ATA_NFORCE_MCP73_A8 0x07f810de -#define ATA_NFORCE_MCP73_A9 0x07f910de -#define ATA_NFORCE_MCP73_AA 0x07fa10de -#define ATA_NFORCE_MCP73_AB 0x07fb10de -#define ATA_NFORCE_MCP77 0x075910de -#define ATA_NFORCE_MCP77_A0 0x0ad010de -#define ATA_NFORCE_MCP77_A1 0x0ad110de -#define ATA_NFORCE_MCP77_A2 0x0ad210de -#define ATA_NFORCE_MCP77_A3 0x0ad310de -#define ATA_NFORCE_MCP77_A4 0x0ad410de -#define ATA_NFORCE_MCP77_A5 0x0ad510de -#define ATA_NFORCE_MCP77_A6 0x0ad610de -#define ATA_NFORCE_MCP77_A7 0x0ad710de -#define ATA_NFORCE_MCP77_A8 0x0ad810de -#define ATA_NFORCE_MCP77_A9 0x0ad910de -#define ATA_NFORCE_MCP77_AA 0x0ada10de -#define ATA_NFORCE_MCP77_AB 0x0adb10de -#define ATA_NFORCE_MCP79_A0 0x0ab410de -#define ATA_NFORCE_MCP79_A1 0x0ab510de -#define ATA_NFORCE_MCP79_A2 0x0ab610de -#define ATA_NFORCE_MCP79_A3 0x0ab710de -#define ATA_NFORCE_MCP79_A4 0x0ab810de -#define ATA_NFORCE_MCP79_A5 0x0ab910de -#define ATA_NFORCE_MCP79_A6 0x0aba10de -#define ATA_NFORCE_MCP79_A7 0x0abb10de -#define ATA_NFORCE_MCP79_A8 0x0abc10de -#define ATA_NFORCE_MCP79_A9 0x0abd10de -#define ATA_NFORCE_MCP79_AA 0x0abe10de -#define ATA_NFORCE_MCP79_AB 0x0abf10de -#define ATA_NFORCE_MCP89_A0 0x0d8410de -#define ATA_NFORCE_MCP89_A1 0x0d8510de -#define ATA_NFORCE_MCP89_A2 0x0d8610de -#define ATA_NFORCE_MCP89_A3 0x0d8710de -#define ATA_NFORCE_MCP89_A4 0x0d8810de -#define ATA_NFORCE_MCP89_A5 0x0d8910de -#define ATA_NFORCE_MCP89_A6 0x0d8a10de -#define ATA_NFORCE_MCP89_A7 0x0d8b10de -#define ATA_NFORCE_MCP89_A8 0x0d8c10de -#define ATA_NFORCE_MCP89_A9 0x0d8d10de -#define ATA_NFORCE_MCP89_AA 0x0d8e10de -#define ATA_NFORCE_MCP89_AB 0x0d8f10de - -#define ATA_PROMISE_ID 0x105a -#define ATA_PDC20246 0x4d33105a -#define ATA_PDC20262 0x4d38105a -#define ATA_PDC20263 0x0d38105a -#define ATA_PDC20265 0x0d30105a -#define ATA_PDC20267 0x4d30105a -#define ATA_PDC20268 0x4d68105a -#define ATA_PDC20269 0x4d69105a -#define ATA_PDC20270 0x6268105a -#define ATA_PDC20271 0x6269105a -#define ATA_PDC20275 0x1275105a -#define ATA_PDC20276 0x5275105a -#define ATA_PDC20277 0x7275105a -#define ATA_PDC20318 0x3318105a -#define ATA_PDC20319 0x3319105a -#define ATA_PDC20371 0x3371105a -#define ATA_PDC20375 0x3375105a -#define ATA_PDC20376 0x3376105a -#define ATA_PDC20377 0x3377105a -#define ATA_PDC20378 0x3373105a -#define ATA_PDC20379 0x3372105a -#define ATA_PDC20571 0x3571105a -#define ATA_PDC20575 0x3d75105a -#define ATA_PDC20579 0x3574105a -#define ATA_PDC20771 0x3570105a -#define ATA_PDC40518 0x3d18105a -#define ATA_PDC40519 0x3519105a -#define ATA_PDC40718 0x3d17105a -#define ATA_PDC40719 0x3515105a -#define ATA_PDC40775 0x3d73105a -#define ATA_PDC40779 0x3577105a -#define ATA_PDC20617 0x6617105a -#define ATA_PDC20618 0x6626105a -#define ATA_PDC20619 0x6629105a -#define ATA_PDC20620 0x6620105a -#define ATA_PDC20621 0x6621105a -#define ATA_PDC20622 0x6622105a -#define ATA_PDC20624 0x6624105a -#define ATA_PDC81518 0x8002105a - -#define ATA_SERVERWORKS_ID 0x1166 -#define ATA_ROSB4_ISA 0x02001166 -#define ATA_ROSB4 0x02111166 -#define ATA_CSB5 0x02121166 -#define ATA_CSB6 0x02131166 -#define ATA_CSB6_1 0x02171166 -#define ATA_HT1000 0x02141166 -#define ATA_HT1000_S1 0x024b1166 -#define ATA_HT1000_S2 0x024a1166 -#define ATA_K2 0x02401166 -#define ATA_FRODO4 0x02411166 -#define ATA_FRODO8 0x02421166 - -#define ATA_SILICON_IMAGE_ID 0x1095 -#define ATA_SII3114 0x31141095 -#define ATA_SII3512 0x35121095 -#define ATA_SII3112 0x31121095 -#define ATA_SII3112_1 0x02401095 -#define ATA_SII3124 0x31241095 -#define ATA_SII3132 0x31321095 -#define ATA_SII3132_1 0x02421095 -#define ATA_SII3132_2 0x02441095 -#define ATA_SII0680 0x06801095 -#define ATA_CMD646 0x06461095 -#define ATA_CMD648 0x06481095 -#define ATA_CMD649 0x06491095 - -#define ATA_SIS_ID 0x1039 -#define ATA_SISSOUTH 0x00081039 -#define ATA_SIS5511 0x55111039 -#define ATA_SIS5513 0x55131039 -#define ATA_SIS5517 0x55171039 -#define ATA_SIS5518 0x55181039 -#define ATA_SIS5571 0x55711039 -#define ATA_SIS5591 0x55911039 -#define ATA_SIS5596 0x55961039 -#define ATA_SIS5597 0x55971039 -#define ATA_SIS5598 0x55981039 -#define ATA_SIS5600 0x56001039 -#define ATA_SIS530 0x05301039 -#define ATA_SIS540 0x05401039 -#define ATA_SIS550 0x05501039 -#define ATA_SIS620 0x06201039 -#define ATA_SIS630 0x06301039 -#define ATA_SIS635 0x06351039 -#define ATA_SIS633 0x06331039 -#define ATA_SIS640 0x06401039 -#define ATA_SIS645 0x06451039 -#define ATA_SIS646 0x06461039 -#define ATA_SIS648 0x06481039 -#define ATA_SIS650 0x06501039 -#define ATA_SIS651 0x06511039 -#define ATA_SIS652 0x06521039 -#define ATA_SIS655 0x06551039 -#define ATA_SIS658 0x06581039 -#define ATA_SIS661 0x06611039 -#define ATA_SIS730 0x07301039 -#define ATA_SIS733 0x07331039 -#define ATA_SIS735 0x07351039 -#define ATA_SIS740 0x07401039 -#define ATA_SIS745 0x07451039 -#define ATA_SIS746 0x07461039 -#define ATA_SIS748 0x07481039 -#define ATA_SIS750 0x07501039 -#define ATA_SIS751 0x07511039 -#define ATA_SIS752 0x07521039 -#define ATA_SIS755 0x07551039 -#define ATA_SIS961 0x09611039 -#define ATA_SIS962 0x09621039 -#define ATA_SIS963 0x09631039 -#define ATA_SIS964 0x09641039 -#define ATA_SIS965 0x09651039 -#define ATA_SIS964_1 0x01801039 -#define ATA_SIS180 0x01801039 -#define ATA_SIS181 0x01811039 -#define ATA_SIS182 0x01821039 - -#define ATA_VIA_ID 0x1106 -#define ATA_VIA82C571 0x05711106 -#define ATA_VIA82C586 0x05861106 -#define ATA_VIA82C596 0x05961106 -#define ATA_VIA82C686 0x06861106 -#define ATA_VIA8231 0x82311106 -#define ATA_VIA8233 0x30741106 -#define ATA_VIA8233A 0x31471106 -#define ATA_VIA8233C 0x31091106 -#define ATA_VIA8235 0x31771106 -#define ATA_VIA8237 0x32271106 -#define ATA_VIA8237A 0x05911106 -#define ATA_VIA8237S 0x53371106 -#define ATA_VIA8237_5372 0x53721106 -#define ATA_VIA8237_7372 0x73721106 -#define ATA_VIA8251 0x33491106 -#define ATA_VIA8361 0x31121106 -#define ATA_VIA8363 0x03051106 -#define ATA_VIA8371 0x03911106 -#define ATA_VIA8662 0x31021106 -#define ATA_VIA6410 0x31641106 -#define ATA_VIA6420 0x31491106 -#define ATA_VIA6421 0x32491106 - -#define ATA_VIACX700IDE 0x05811106 -#define ATA_VIACX700 0x83241106 -#define ATA_VIASATAIDE 0x53241106 -#define ATA_VIAVX800 0x83531106 -#define ATA_VIASATAIDE2 0xc4091106 -#define ATA_VIAVX855 0x84091106 -#define ATA_VIASATAIDE3 0x90011106 -#define ATA_VIAVX900 0x84101106 - -#define ATA_ITE_ID 0x1283 -#define ATA_IT8172G 0x81721283 -#define ATA_IT8211F 0x82111283 -#define ATA_IT8212F 0x82121283 -#define ATA_IT8213F 0x82131283 - -#define ATA_OPTI_ID 0x1045 -#define ATA_OPTI82C621 0xc6211045 -#define ATA_OPTI82C625 0xd5681045 - -#define ATA_HINT_ID 0x3388 -#define ATA_HINTEIDE_ID 0x80133388 - -/* chipset setup related defines */ -/* Used in HW_DEVICE_EXTENSION.InitMethod */ - -#define CHIPTYPE_MASK 0x000000ff -#define CHIPFLAG_MASK 0xffffff00 - -#define UNIATA_RAID_CONTROLLER 0x80000000 -#define UNIATA_SIMPLEX_ONLY 0x40000000 -#define UNIATA_NO_SLAVE 0x20000000 -#define UNIATA_SATA 0x10000000 -#define UNIATA_NO_DPC 0x08000000 -#define UNIATA_NO_DPC_ATAPI 0x04000000 -#define UNIATA_AHCI 0x02000000 -#define UNIATA_NO80CHK 0x01000000 - -#define ATPOLD 0x0100 - -#define ALIOLD 0x0100 -#define ALINEW 0x0200 - -#define HPT366 0 -#define HPT370 1 -#define HPT372 2 -#define HPT374 3 -#define HPTOLD 0x0100 - -#define PROLD 0 -#define PRNEW 1 -#define PRTX 2 -#define PRMIO 3 -#define PRTX4 0x0100 -#define PRSX4K 0x0200 -#define PRSX6K 0x0400 -#define PRSATA 0x0800 -#define PRCMBO 0x1000 -#define PRG2 0x2000 -#define PRCMBO2 (PRCMBO | PRG2) -#define PRSATA2 (PRSATA | PRG2) - -#define SWKS33 0 -#define SWKS66 1 -#define SWKS100 2 -#define SWKSMIO 3 - -#define SIIOLD 0 -#define SIICMD 1 -#define SIIMIO 2 -#define ATI700 3 - -#define SIIINTR 0x0100 -#define SIIENINTR 0x0200 -#define SII4CH 0x0400 -#define SIISETCLK 0x0800 -#define SIIBUG 0x1000 -#define SIINOSATAIRQ 0x2000 - -//#define SIS_SOUTH 1 -#define SISSATA 2 -#define SIS133NEW 3 -#define SIS133OLD 4 -#define SIS100NEW 5 -#define SIS100OLD 6 -#define SIS66 7 -#define SIS33 8 - -#define SIS_BASE 0x0100 -#define SIS_SOUTH 0x0200 - -#define INTEL_STD 0 -#define INTEL_IDX 1 - -#define ICH4_FIX 0x0100 -#define ICH5 0x0200 -#define I6CH 0x0400 -#define I6CH2 0x0800 -//#define I1CH 0x1000 // obsolete -#define ICH7 0x1000 - -#define NV4OFF 0x0100 -#define NVQ 0x0200 - -#define VIA33 4 -#define VIA66 1 -#define VIA100 2 -#define VIA133 3 -#define AMDNVIDIA 0 -#define AMDCABLE 0x0100 -#define AMDBUG 0x0200 -#define VIABAR 0x0400 -#define VIACLK 0x0800 -#define VIABUG 0x1000 -#define VIASOUTH 0x2000 -#define VIAAST 0x4000 -#define VIAPRQ 0x8000 -#define VIASATA 0x10000 - -#define CYRIX_OLD 0 -#define CYRIX_3x 1 -#define CYRIX_NEW 2 -#define CYRIX_35 3 - -#define ITE_33 0 -#define ITE_133 1 -#define ITE_133_NEW 2 - -#ifdef USER_MODE - #define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \ - { (PVEN_STR) #idlo, 4, 0x##idlo, (PVEN_STR) #idhi, 4, 0x##idhi, rev, mode, (PVEN_STR)name, flags} -#else - #define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \ - { (PVEN_STR) #idlo, 4, 0x##idlo, (PVEN_STR) #idhi, 4, 0x##idhi, rev, mode, NULL, flags} -#endif - -#define BMLIST_TERMINATOR (0xffffffffL) - -BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = { +BUSMASTER_CONTROLLER_INFORMATION_BASE const BusMasterAdapters[] = { PCI_DEV_HW_SPEC_BM( 0005, 1191, 0x00, ATA_UDMA2, "Acard ATP850" , ATPOLD | UNIATA_SIMPLEX_ONLY ), PCI_DEV_HW_SPEC_BM( 0006, 1191, 0x00, ATA_UDMA4, "Acard ATP860A" , UNIATA_NO80CHK ), @@ -777,7 +97,7 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = { PCI_DEV_HW_SPEC_BM( 0007, 1103, 0x01, ATA_UDMA6, "HighPoint HPT371" , HPT372 | 0x00 | UNIATA_RAID_CONTROLLER), PCI_DEV_HW_SPEC_BM( 0008, 1103, 0x07, ATA_UDMA6, "HighPoint HPT374" , HPT374 | 0x00 | UNIATA_RAID_CONTROLLER), - PCI_DEV_HW_SPEC_BM( 1230, 8086, 0x00, ATA_WDMA2, "Intel PIIX" , 0 ), + PCI_DEV_HW_SPEC_BM( 1230, 8086, 0x00, ATA_WDMA2, "Intel PIIX" , UNIATA_CHAN_TIMINGS ), PCI_DEV_HW_SPEC_BM( 7010, 8086, 0x00, ATA_WDMA2, "Intel PIIX3" , 0 ), PCI_DEV_HW_SPEC_BM( 7111, 8086, 0x00, ATA_UDMA2, "Intel PIIX3" , 0 ), PCI_DEV_HW_SPEC_BM( 7199, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ), @@ -1233,50 +553,4 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = { PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR, NULL , BMLIST_TERMINATOR ) }; -#define NUM_BUSMASTER_ADAPTERS (sizeof(BusMasterAdapters) / sizeof(BUSMASTER_CONTROLLER_INFORMATION)) - -/* - Looks for device with specified Device/Vendor and Revision - in specified device list and returnts its index. - If no matching record found, -1 is returned -*/ -__inline -ULONG -Ata_is_dev_listed( - PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters, - ULONG VendorId, - ULONG DeviceId, - ULONG RevId, // min suitable revision - ULONG lim - ) -{ - for(ULONG k=0; kBaseClass == PCI_DEV_CLASS_STORAGE && \ - (pciData)->SubClass == PCI_DEV_SUBCLASS_IDE) - -#define Ata_is_ahci_dev(pciData) \ - ((pciData)->BaseClass == PCI_DEV_CLASS_STORAGE && \ - (pciData)->SubClass == PCI_DEV_SUBCLASS_SATA && \ - (pciData)->ProgIf == PCI_DEV_PROGIF_AHCI_1_0 && \ - ((pciData)->u.type0.BaseAddresses[5] & ~0x7)) - - -#pragma pack(pop) - -#endif //__IDE_BUSMASTER_H__ +const ULONG _NUM_BUSMASTER_ADAPTERS = (sizeof(BusMasterAdapters) / sizeof(BUSMASTER_CONTROLLER_INFORMATION_BASE)); diff --git a/reactos/drivers/storage/ide/uniata/bm_devs_decl.h b/reactos/drivers/storage/ide/uniata/bm_devs_decl.h new file mode 100644 index 00000000000..61f8c9598f5 --- /dev/null +++ b/reactos/drivers/storage/ide/uniata/bm_devs_decl.h @@ -0,0 +1,789 @@ +/*++ + +Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter) + +Module Name: + bm_devs.h + +Abstract: + This file contains common definitions for list of PCI IDE controllers + +Author: + Alexander A. Telyatnikov (Alter) + +Environment: + kernel and user mode + +Notes: + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Revision History: + +Licence: + GPLv2 + +--*/ + +#ifndef __IDE_BUSMASTER_DEVICES_H__ +#define __IDE_BUSMASTER_DEVICES_H__ + +#pragma pack(push, 8) + +#define IDE_MAX_CHAN 16 +#define IDE_DEFAULT_MAX_CHAN 2 +// Thanks to SATA Port Multipliers: +//#define IDE_MAX_LUN_PER_CHAN SATA_MAX_PM_UNITS +#define IDE_MAX_LUN_PER_CHAN 2 + +#define IDE_MAX_LUN (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN) + +#define MAX_QUEUE_STAT 8 + +// define PIO timings in nanoseconds +#define PIO0_TIMING 600 + +//#define UniataGetPioTiming(LunExt) ((LunExt->TransferMode <= ATA_PIO0) ? PIO0_TIMING : 0) +#define UniataGetPioTiming(LunExt) 0 //ktp + +/*#ifdef USER_MODE +#define PVEN_STR PCSTR +#else // USER_MODE +#define PVEN_STR PCHAR +#endif // USER_MODE*/ +#define PVEN_STR PCSTR + +typedef struct _BUSMASTER_CONTROLLER_INFORMATION_BASE { + ULONG nVendorId; + ULONG nDeviceId; + ULONG nRevId; + ULONG MaxTransferMode; + ULONG RaidFlags; + PVEN_STR FullDevName; +} BUSMASTER_CONTROLLER_INFORMATION_BASE, *PBUSMASTER_CONTROLLER_INFORMATION_BASE; + +typedef struct _BUSMASTER_CONTROLLER_INFORMATION { + PVEN_STR VendorId; + ULONG VendorIdLength; + ULONG nVendorId; + PVEN_STR DeviceId; + ULONG DeviceIdLength; + ULONG nDeviceId; + ULONG nRevId; + ULONG MaxTransferMode; + PVEN_STR FullDevName; + ULONG RaidFlags; + CHAR VendorIdStr[4]; + CHAR DeviceIdStr[4]; + ULONG slotNumber; + ULONG busNumber; + CHAR channel; +// CHAR numOfChannes; + CHAR MasterDev; + BOOLEAN Known; +#ifndef USER_MODE + UCHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary, 0x80 - PciIde claimed + BOOLEAN Isr2Enable; + union { + PDEVICE_OBJECT Isr2DevObj; + PDEVICE_OBJECT PciIdeDevObj; + }; + KIRQL Isr2Irql; + KAFFINITY Isr2Affinity; + ULONG Isr2Vector; + PKINTERRUPT Isr2InterruptObject; + CHAR AltInitMasterDev; // 0xff - uninitialized, 0x00 - normal, 0x01 - change ISA to PCI + CHAR NeedAltInit; // 0x01 - try change ISA to PCI +#endif // USER_MODE + +} BUSMASTER_CONTROLLER_INFORMATION, *PBUSMASTER_CONTROLLER_INFORMATION; + +/* defines for known chipset PCI id's */ +#define ATA_ACARD_ID 0x1191 +#define ATA_ATP850 0x00021191 +#define ATA_ATP850A 0x00041191 +#define ATA_ATP850R 0x00051191 +#define ATA_ATP860A 0x00061191 +#define ATA_ATP860R 0x00071191 +#define ATA_ATP865A 0x00081191 +#define ATA_ATP865R 0x00091191 + +#define ATA_ACER_LABS_ID 0x10b9 +#define ATA_ALI_1533 0x153310b9 +#define ATA_ALI_5228 0x522810b9 +#define ATA_ALI_5229 0x522910b9 +#define ATA_ALI_5281 0x528110b9 +#define ATA_ALI_5287 0x528710b9 +#define ATA_ALI_5288 0x528810b9 +#define ATA_ALI_5289 0x528910b9 + +#define ATA_AMD_ID 0x1022 +#define ATA_AMD755 0x74011022 +#define ATA_AMD756 0x74091022 +#define ATA_AMD766 0x74111022 +#define ATA_AMD768 0x74411022 +#define ATA_AMD8111 0x74691022 +#define ATA_AMD5536 0x209a1022 +#define ATA_AMD_HUDSON2_S1 0x78001022 +#define ATA_AMD_HUDSON2_S2 0x78011022 +#define ATA_AMD_HUDSON2_S3 0x78021022 +#define ATA_AMD_HUDSON2_S4 0x78031022 +#define ATA_AMD_HUDSON2_S5 0x78041022 +#define ATA_AMD_HUDSON2 0x780c1022 + +#define ATA_ADAPTEC_ID 0x9005 +#define ATA_ADAPTEC_1420 0x02419005 +#define ATA_ADAPTEC_1430 0x02439005 + +#define ATA_ATI_ID 0x1002 +#define ATA_ATI_IXP200 0x43491002 +#define ATA_ATI_IXP300 0x43691002 +#define ATA_ATI_IXP300_S1 0x436e1002 +#define ATA_ATI_IXP400 0x43761002 +#define ATA_ATI_IXP400_S1 0x43791002 +#define ATA_ATI_IXP400_S2 0x437a1002 +#define ATA_ATI_IXP600 0x438c1002 +#define ATA_ATI_IXP600_S1 0x43801002 +#define ATA_ATI_IXP700 0x439c1002 +#define ATA_ATI_IXP700_S1 0x43901002 +#define ATA_ATI_IXP700_S2 0x43911002 +#define ATA_ATI_IXP700_S3 0x43921002 +#define ATA_ATI_IXP700_S4 0x43931002 +#define ATA_ATI_IXP800_S1 0x43941002 +#define ATA_ATI_IXP800_S2 0x43951002 +#define ATA_ATI_4385 0x43851002 + +#define ATA_CENATEK_ID 0x16ca +#define ATA_CENATEK_ROCKET 0x000116ca + +#define ATA_CYRIX_ID 0x1078 +#define ATA_CYRIX_5530 0x01021078 + +#define ATA_CYPRESS_ID 0x1080 +#define ATA_CYPRESS_82C693 0xc6931080 + +#define ATA_DEC_21150 0x00221011 +#define ATA_DEC_21150_1 0x00231011 + +#define ATA_HIGHPOINT_ID 0x1103 +#define ATA_HPT366 0x00041103 +#define ATA_HPT372 0x00051103 +#define ATA_HPT302 0x00061103 +#define ATA_HPT371 0x00071103 +#define ATA_HPT374 0x00081103 + +#define ATA_INTEL_ID 0x8086 +#define ATA_I960RM 0x09628086 +#define ATA_I82371FB 0x12308086 +#define ATA_I82371SB 0x70108086 +#define ATA_I82371AB 0x71118086 +#define ATA_I82443MX 0x71998086 +#define ATA_I82451NX 0x84ca8086 +#define ATA_I82372FB 0x76018086 +#define ATA_I82801AB 0x24218086 +#define ATA_I82801AA 0x24118086 +#define ATA_I82801BA 0x244a8086 +#define ATA_I82801BA_1 0x244b8086 +#define ATA_I82801CA 0x248a8086 +#define ATA_I82801CA_1 0x248b8086 +#define ATA_I82801DB 0x24cb8086 +#define ATA_I82801DB_1 0x24ca8086 +#define ATA_I82801EB 0x24db8086 +#define ATA_I82801EB_S1 0x24d18086 +#define ATA_I82801EB_R1 0x24df8086 +#define ATA_I6300ESB 0x25a28086 +#define ATA_I6300ESB_S1 0x25a38086 +#define ATA_I6300ESB_R1 0x25b08086 +#define ATA_I63XXESB2 0x269e8086 +#define ATA_I63XXESB2_S1 0x26808086 +#define ATA_I63XXESB2_S2 0x26818086 +#define ATA_I63XXESB2_R1 0x26828086 +#define ATA_I63XXESB2_R2 0x26838086 +#define ATA_I82801FB 0x266f8086 +#define ATA_I82801FB_S1 0x26518086 +#define ATA_I82801FB_R1 0x26528086 +#define ATA_I82801FB_M 0x26538086 +#define ATA_I82801GB 0x27df8086 +#define ATA_I82801GB_S1 0x27c08086 +#define ATA_I82801GB_AH 0x27c18086 +#define ATA_I82801GB_R1 0x27c38086 +#define ATA_I82801GBM_S1 0x27c48086 +#define ATA_I82801GBM_AH 0x27c58086 +#define ATA_I82801GBM_R1 0x27c68086 +#define ATA_I82801HB_S1 0x28208086 +#define ATA_I82801HB_AH6 0x28218086 +#define ATA_I82801HB_R1 0x28228086 +#define ATA_I82801HB_AH4 0x28248086 +#define ATA_I82801HB_S2 0x28258086 +#define ATA_I82801HBM 0x28508086 +#define ATA_I82801HBM_S1 0x28288086 +#define ATA_I82801HBM_S2 0x28298086 +#define ATA_I82801HBM_S3 0x282a8086 +#define ATA_I82801IB_S1 0x29208086 +#define ATA_I82801IB_AH2 0x29218086 +#define ATA_I82801IB_AH6 0x29228086 +#define ATA_I82801IB_AH4 0x29238086 +#define ATA_I82801IB_R1 0x29258086 +#define ATA_I82801IB_S2 0x29268086 +#define ATA_I82801IBM_S1 0x29288086 +#define ATA_I82801IBM_AH 0x29298086 +#define ATA_I82801IBM_R1 0x292a8086 +#define ATA_I82801IBM_S2 0x292d8086 +#define ATA_I82801JIB_S1 0x3a208086 +#define ATA_I82801JIB_AH 0x3a228086 +#define ATA_I82801JIB_R1 0x3a258086 +#define ATA_I82801JIB_S2 0x3a268086 +#define ATA_I82801JD_S1 0x3a008086 +#define ATA_I82801JD_AH 0x3a028086 +#define ATA_I82801JD_R1 0x3a058086 +#define ATA_I82801JD_S2 0x3a068086 +/* +#define ATA_I82801JI_S1 0x3a208086 +#define ATA_I82801JI_AH 0x3a228086 +#define ATA_I82801JI_R1 0x3a258086 +#define ATA_I82801JI_S2 0x3a268086 +*/ +#define ATA_5Series_S1 0x3b208086 +#define ATA_5Series_S2 0x3b218086 +#define ATA_5Series_AH1 0x3b228086 +#define ATA_5Series_AH2 0x3b238086 +#define ATA_5Series_R1 0x3b258086 +#define ATA_5Series_S3 0x3b268086 +#define ATA_5Series_S4 0x3b288086 +#define ATA_5Series_AH3 0x3b298086 +#define ATA_5Series_R2 0x3b2c8086 +#define ATA_5Series_S5 0x3b2d8086 +#define ATA_5Series_S6 0x3b2e8086 +#define ATA_5Series_AH4 0x3b2f8086 + +#define ATA_CPT_S1 0x1c008086 +#define ATA_CPT_S2 0x1c018086 +#define ATA_CPT_AH1 0x1c028086 +#define ATA_CPT_AH2 0x1c038086 +#define ATA_CPT_R1 0x1c048086 +#define ATA_CPT_R2 0x1c058086 +#define ATA_CPT_S3 0x1c088086 +#define ATA_CPT_S4 0x1c098086 + +#define ATA_PBG_S1 0x1d008086 +#define ATA_PBG_AH1 0x1d028086 +#define ATA_PBG_R1 0x1d048086 +#define ATA_PBG_R2 0x1d068086 +#define ATA_PBG_R3 0x28268086 +#define ATA_PBG_S2 0x1d088086 + +#define ATA_PPT_S1 0x1e008086 +#define ATA_PPT_S2 0x1e018086 +#define ATA_PPT_AH1 0x1e028086 +#define ATA_PPT_AH2 0x1e038086 +#define ATA_PPT_R1 0x1e048086 +#define ATA_PPT_R2 0x1e058086 +#define ATA_PPT_R3 0x1e068086 +#define ATA_PPT_R4 0x1e078086 +#define ATA_PPT_S3 0x1e088086 +#define ATA_PPT_S4 0x1e098086 +#define ATA_PPT_R5 0x1e0e8086 +#define ATA_PPT_R6 0x1e0f8086 + +#define ATA_LPT_S1 0x8c008086 +#define ATA_LPT_S2 0x8c018086 +#define ATA_LPT_AH1 0x8c028086 +#define ATA_LPT_AH2 0x8c038086 +#define ATA_LPT_R1 0x8c048086 +#define ATA_LPT_R2 0x8c058086 +#define ATA_LPT_R3 0x8c068086 +#define ATA_LPT_R4 0x8c078086 +#define ATA_LPT_S3 0x8c088086 +#define ATA_LPT_S4 0x8c098086 +#define ATA_LPT_R5 0x8c0e8086 +#define ATA_LPT_R6 0x8c0f8086 + +#define ATA_I31244 0x32008086 +#define ATA_ISCH 0x811a8086 +#define ATA_DH89XXCC 0x23238086 + +#define ATA_COLETOCRK_AH1 0x23a38086 +#define ATA_COLETOCRK_S1 0x23a18086 +#define ATA_COLETOCRK_S2 0x23a68086 + +#define ATA_JMICRON_ID 0x197b +#define ATA_JMB360 0x2360197b +#define ATA_JMB361 0x2361197b +#define ATA_JMB362 0x2362197b +#define ATA_JMB363 0x2363197b +#define ATA_JMB365 0x2365197b +#define ATA_JMB366 0x2366197b +#define ATA_JMB368 0x2368197b + +#define ATA_MARVELL_ID 0x11ab +#define ATA_M88SX5040 0x504011ab +#define ATA_M88SX5041 0x504111ab +#define ATA_M88SX5080 0x508011ab +#define ATA_M88SX5081 0x508111ab +#define ATA_M88SX6041 0x604111ab +#define ATA_M88SX6042 0x604211ab +#define ATA_M88SX6081 0x608111ab +#define ATA_M88SX7042 0x704211ab +#define ATA_M88SE6101 0x610111ab +#define ATA_M88SE6102 0x610211ab +#define ATA_M88SE6111 0x611111ab +#define ATA_M88SE6121 0x612111ab +#define ATA_M88SE6141 0x614111ab +#define ATA_M88SE6145 0x614511ab +#define ATA_M88SE9123 0x91231b4b +#define ATA_MARVELL2_ID 0x1b4b + +#define ATA_MICRON_ID 0x1042 +#define ATA_MICRON_RZ1000 0x10001042 +#define ATA_MICRON_RZ1001 0x10011042 + +#define ATA_NATIONAL_ID 0x100b +#define ATA_SC1100 0x0502100b + +#define ATA_NETCELL_ID 0x169c +#define ATA_NETCELL_SR 0x0044169c + +#define ATA_NVIDIA_ID 0x10de +#define ATA_NFORCE1 0x01bc10de +#define ATA_NFORCE2 0x006510de +#define ATA_NFORCE2_PRO 0x008510de +#define ATA_NFORCE2_PRO_S1 0x008e10de +#define ATA_NFORCE3 0x00d510de +#define ATA_NFORCE3_PRO 0x00e510de +#define ATA_NFORCE3_PRO_S1 0x00e310de +#define ATA_NFORCE3_PRO_S2 0x00ee10de +#define ATA_NFORCE_MCP04 0x003510de +#define ATA_NFORCE_MCP04_S1 0x003610de +#define ATA_NFORCE_MCP04_S2 0x003e10de +#define ATA_NFORCE_CK804 0x005310de +#define ATA_NFORCE_CK804_S1 0x005410de +#define ATA_NFORCE_CK804_S2 0x005510de +#define ATA_NFORCE_MCP51 0x026510de +#define ATA_NFORCE_MCP51_S1 0x026610de +#define ATA_NFORCE_MCP51_S2 0x026710de +#define ATA_NFORCE_MCP55 0x036e10de +#define ATA_NFORCE_MCP55_S1 0x037e10de +#define ATA_NFORCE_MCP55_S2 0x037f10de +#define ATA_NFORCE_MCP61 0x03ec10de +#define ATA_NFORCE_MCP61_S1 0x03e710de +#define ATA_NFORCE_MCP61_S2 0x03f610de +#define ATA_NFORCE_MCP61_S3 0x03f710de +#define ATA_NFORCE_MCP65 0x044810de +#define ATA_NFORCE_MCP65_A0 0x044c10de +#define ATA_NFORCE_MCP65_A1 0x044d10de +#define ATA_NFORCE_MCP65_A2 0x044e10de +#define ATA_NFORCE_MCP65_A3 0x044f10de +#define ATA_NFORCE_MCP65_A4 0x045c10de +#define ATA_NFORCE_MCP65_A5 0x045d10de +#define ATA_NFORCE_MCP65_A6 0x045e10de +#define ATA_NFORCE_MCP65_A7 0x045f10de +#define ATA_NFORCE_MCP67 0x056010de +#define ATA_NFORCE_MCP67_A0 0x055010de +#define ATA_NFORCE_MCP67_A1 0x055110de +#define ATA_NFORCE_MCP67_A2 0x055210de +#define ATA_NFORCE_MCP67_A3 0x055310de +#define ATA_NFORCE_MCP67_A4 0x055410de +#define ATA_NFORCE_MCP67_A5 0x055510de +#define ATA_NFORCE_MCP67_A6 0x055610de +#define ATA_NFORCE_MCP67_A7 0x055710de +#define ATA_NFORCE_MCP67_A8 0x055810de +#define ATA_NFORCE_MCP67_A9 0x055910de +#define ATA_NFORCE_MCP67_AA 0x055A10de +#define ATA_NFORCE_MCP67_AB 0x055B10de +#define ATA_NFORCE_MCP67_AC 0x058410de +#define ATA_NFORCE_MCP73 0x056c10de +#define ATA_NFORCE_MCP73_A0 0x07f010de +#define ATA_NFORCE_MCP73_A1 0x07f110de +#define ATA_NFORCE_MCP73_A2 0x07f210de +#define ATA_NFORCE_MCP73_A3 0x07f310de +#define ATA_NFORCE_MCP73_A4 0x07f410de +#define ATA_NFORCE_MCP73_A5 0x07f510de +#define ATA_NFORCE_MCP73_A6 0x07f610de +#define ATA_NFORCE_MCP73_A7 0x07f710de +#define ATA_NFORCE_MCP73_A8 0x07f810de +#define ATA_NFORCE_MCP73_A9 0x07f910de +#define ATA_NFORCE_MCP73_AA 0x07fa10de +#define ATA_NFORCE_MCP73_AB 0x07fb10de +#define ATA_NFORCE_MCP77 0x075910de +#define ATA_NFORCE_MCP77_A0 0x0ad010de +#define ATA_NFORCE_MCP77_A1 0x0ad110de +#define ATA_NFORCE_MCP77_A2 0x0ad210de +#define ATA_NFORCE_MCP77_A3 0x0ad310de +#define ATA_NFORCE_MCP77_A4 0x0ad410de +#define ATA_NFORCE_MCP77_A5 0x0ad510de +#define ATA_NFORCE_MCP77_A6 0x0ad610de +#define ATA_NFORCE_MCP77_A7 0x0ad710de +#define ATA_NFORCE_MCP77_A8 0x0ad810de +#define ATA_NFORCE_MCP77_A9 0x0ad910de +#define ATA_NFORCE_MCP77_AA 0x0ada10de +#define ATA_NFORCE_MCP77_AB 0x0adb10de +#define ATA_NFORCE_MCP79_A0 0x0ab410de +#define ATA_NFORCE_MCP79_A1 0x0ab510de +#define ATA_NFORCE_MCP79_A2 0x0ab610de +#define ATA_NFORCE_MCP79_A3 0x0ab710de +#define ATA_NFORCE_MCP79_A4 0x0ab810de +#define ATA_NFORCE_MCP79_A5 0x0ab910de +#define ATA_NFORCE_MCP79_A6 0x0aba10de +#define ATA_NFORCE_MCP79_A7 0x0abb10de +#define ATA_NFORCE_MCP79_A8 0x0abc10de +#define ATA_NFORCE_MCP79_A9 0x0abd10de +#define ATA_NFORCE_MCP79_AA 0x0abe10de +#define ATA_NFORCE_MCP79_AB 0x0abf10de +#define ATA_NFORCE_MCP89_A0 0x0d8410de +#define ATA_NFORCE_MCP89_A1 0x0d8510de +#define ATA_NFORCE_MCP89_A2 0x0d8610de +#define ATA_NFORCE_MCP89_A3 0x0d8710de +#define ATA_NFORCE_MCP89_A4 0x0d8810de +#define ATA_NFORCE_MCP89_A5 0x0d8910de +#define ATA_NFORCE_MCP89_A6 0x0d8a10de +#define ATA_NFORCE_MCP89_A7 0x0d8b10de +#define ATA_NFORCE_MCP89_A8 0x0d8c10de +#define ATA_NFORCE_MCP89_A9 0x0d8d10de +#define ATA_NFORCE_MCP89_AA 0x0d8e10de +#define ATA_NFORCE_MCP89_AB 0x0d8f10de + +#define ATA_PROMISE_ID 0x105a +#define ATA_PDC20246 0x4d33105a +#define ATA_PDC20262 0x4d38105a +#define ATA_PDC20263 0x0d38105a +#define ATA_PDC20265 0x0d30105a +#define ATA_PDC20267 0x4d30105a +#define ATA_PDC20268 0x4d68105a +#define ATA_PDC20269 0x4d69105a +#define ATA_PDC20270 0x6268105a +#define ATA_PDC20271 0x6269105a +#define ATA_PDC20275 0x1275105a +#define ATA_PDC20276 0x5275105a +#define ATA_PDC20277 0x7275105a +#define ATA_PDC20318 0x3318105a +#define ATA_PDC20319 0x3319105a +#define ATA_PDC20371 0x3371105a +#define ATA_PDC20375 0x3375105a +#define ATA_PDC20376 0x3376105a +#define ATA_PDC20377 0x3377105a +#define ATA_PDC20378 0x3373105a +#define ATA_PDC20379 0x3372105a +#define ATA_PDC20571 0x3571105a +#define ATA_PDC20575 0x3d75105a +#define ATA_PDC20579 0x3574105a +#define ATA_PDC20771 0x3570105a +#define ATA_PDC40518 0x3d18105a +#define ATA_PDC40519 0x3519105a +#define ATA_PDC40718 0x3d17105a +#define ATA_PDC40719 0x3515105a +#define ATA_PDC40775 0x3d73105a +#define ATA_PDC40779 0x3577105a +#define ATA_PDC20617 0x6617105a +#define ATA_PDC20618 0x6626105a +#define ATA_PDC20619 0x6629105a +#define ATA_PDC20620 0x6620105a +#define ATA_PDC20621 0x6621105a +#define ATA_PDC20622 0x6622105a +#define ATA_PDC20624 0x6624105a +#define ATA_PDC81518 0x8002105a + +#define ATA_SERVERWORKS_ID 0x1166 +#define ATA_ROSB4_ISA 0x02001166 +#define ATA_ROSB4 0x02111166 +#define ATA_CSB5 0x02121166 +#define ATA_CSB6 0x02131166 +#define ATA_CSB6_1 0x02171166 +#define ATA_HT1000 0x02141166 +#define ATA_HT1000_S1 0x024b1166 +#define ATA_HT1000_S2 0x024a1166 +#define ATA_K2 0x02401166 +#define ATA_FRODO4 0x02411166 +#define ATA_FRODO8 0x02421166 + +#define ATA_SILICON_IMAGE_ID 0x1095 +#define ATA_SII3114 0x31141095 +#define ATA_SII3512 0x35121095 +#define ATA_SII3112 0x31121095 +#define ATA_SII3112_1 0x02401095 +#define ATA_SII3124 0x31241095 +#define ATA_SII3132 0x31321095 +#define ATA_SII3132_1 0x02421095 +#define ATA_SII3132_2 0x02441095 +#define ATA_SII0680 0x06801095 +#define ATA_CMD646 0x06461095 +#define ATA_CMD648 0x06481095 +#define ATA_CMD649 0x06491095 + +#define ATA_SIS_ID 0x1039 +#define ATA_SISSOUTH 0x00081039 +#define ATA_SIS5511 0x55111039 +#define ATA_SIS5513 0x55131039 +#define ATA_SIS5517 0x55171039 +#define ATA_SIS5518 0x55181039 +#define ATA_SIS5571 0x55711039 +#define ATA_SIS5591 0x55911039 +#define ATA_SIS5596 0x55961039 +#define ATA_SIS5597 0x55971039 +#define ATA_SIS5598 0x55981039 +#define ATA_SIS5600 0x56001039 +#define ATA_SIS530 0x05301039 +#define ATA_SIS540 0x05401039 +#define ATA_SIS550 0x05501039 +#define ATA_SIS620 0x06201039 +#define ATA_SIS630 0x06301039 +#define ATA_SIS635 0x06351039 +#define ATA_SIS633 0x06331039 +#define ATA_SIS640 0x06401039 +#define ATA_SIS645 0x06451039 +#define ATA_SIS646 0x06461039 +#define ATA_SIS648 0x06481039 +#define ATA_SIS650 0x06501039 +#define ATA_SIS651 0x06511039 +#define ATA_SIS652 0x06521039 +#define ATA_SIS655 0x06551039 +#define ATA_SIS658 0x06581039 +#define ATA_SIS661 0x06611039 +#define ATA_SIS730 0x07301039 +#define ATA_SIS733 0x07331039 +#define ATA_SIS735 0x07351039 +#define ATA_SIS740 0x07401039 +#define ATA_SIS745 0x07451039 +#define ATA_SIS746 0x07461039 +#define ATA_SIS748 0x07481039 +#define ATA_SIS750 0x07501039 +#define ATA_SIS751 0x07511039 +#define ATA_SIS752 0x07521039 +#define ATA_SIS755 0x07551039 +#define ATA_SIS961 0x09611039 +#define ATA_SIS962 0x09621039 +#define ATA_SIS963 0x09631039 +#define ATA_SIS964 0x09641039 +#define ATA_SIS965 0x09651039 +#define ATA_SIS964_1 0x01801039 +#define ATA_SIS180 0x01801039 +#define ATA_SIS181 0x01811039 +#define ATA_SIS182 0x01821039 + +#define ATA_VIA_ID 0x1106 +#define ATA_VIA82C571 0x05711106 +#define ATA_VIA82C586 0x05861106 +#define ATA_VIA82C596 0x05961106 +#define ATA_VIA82C686 0x06861106 +#define ATA_VIA8231 0x82311106 +#define ATA_VIA8233 0x30741106 +#define ATA_VIA8233A 0x31471106 +#define ATA_VIA8233C 0x31091106 +#define ATA_VIA8235 0x31771106 +#define ATA_VIA8237 0x32271106 +#define ATA_VIA8237A 0x05911106 +#define ATA_VIA8237S 0x53371106 +#define ATA_VIA8237_5372 0x53721106 +#define ATA_VIA8237_7372 0x73721106 +#define ATA_VIA8251 0x33491106 +#define ATA_VIA8361 0x31121106 +#define ATA_VIA8363 0x03051106 +#define ATA_VIA8371 0x03911106 +#define ATA_VIA8662 0x31021106 +#define ATA_VIA6410 0x31641106 +#define ATA_VIA6420 0x31491106 +#define ATA_VIA6421 0x32491106 + +#define ATA_VIACX700IDE 0x05811106 +#define ATA_VIACX700 0x83241106 +#define ATA_VIASATAIDE 0x53241106 +#define ATA_VIAVX800 0x83531106 +#define ATA_VIASATAIDE2 0xc4091106 +#define ATA_VIAVX855 0x84091106 +#define ATA_VIASATAIDE3 0x90011106 +#define ATA_VIAVX900 0x84101106 + +#define ATA_ITE_ID 0x1283 +#define ATA_IT8172G 0x81721283 +#define ATA_IT8211F 0x82111283 +#define ATA_IT8212F 0x82121283 +#define ATA_IT8213F 0x82131283 + +#define ATA_OPTI_ID 0x1045 +#define ATA_OPTI82C621 0xc6211045 +#define ATA_OPTI82C625 0xd5681045 + +#define ATA_HINT_ID 0x3388 +#define ATA_HINTEIDE_ID 0x80133388 + +/* chipset setup related defines */ +/* Used in HW_DEVICE_EXTENSION.InitMethod */ + +#define CHIPTYPE_MASK 0x000000ff +#define CHIPFLAG_MASK 0xffffff00 + +#define UNIATA_RAID_CONTROLLER 0x80000000 +#define UNIATA_SIMPLEX_ONLY 0x40000000 /* contoller cannot perform operations + on both channels on the same time */ +#define UNIATA_NO_SLAVE 0x20000000 +#define UNIATA_SATA 0x10000000 +#define UNIATA_NO_DPC 0x08000000 +#define UNIATA_NO_DPC_ATAPI 0x04000000 +#define UNIATA_AHCI 0x02000000 +#define UNIATA_NO80CHK 0x01000000 +#define UNIATA_CHAN_TIMINGS 0x00800000 /* controller has common timing settings for master/slave */ + +#define ATPOLD 0x0100 + +#define ALIOLD 0x0100 +#define ALINEW 0x0200 + +#define HPT366 0 +#define HPT370 1 +#define HPT372 2 +#define HPT374 3 +#define HPTOLD 0x0100 + +#define PROLD 0 +#define PRNEW 1 +#define PRTX 2 +#define PRMIO 3 +#define PRTX4 0x0100 +#define PRSX4K 0x0200 +#define PRSX6K 0x0400 +#define PRSATA 0x0800 +#define PRCMBO 0x1000 +#define PRG2 0x2000 +#define PRCMBO2 (PRCMBO | PRG2) +#define PRSATA2 (PRSATA | PRG2) + +#define SWKS33 0 +#define SWKS66 1 +#define SWKS100 2 +#define SWKSMIO 3 + +#define SIIOLD 0 +#define SIICMD 1 +#define SIIMIO 2 +#define ATI700 3 + +#define SIIINTR 0x0100 +#define SIIENINTR 0x0200 +#define SII4CH 0x0400 +#define SIISETCLK 0x0800 +#define SIIBUG 0x1000 +#define SIINOSATAIRQ 0x2000 + +//#define SIS_SOUTH 1 +#define SISSATA 2 +#define SIS133NEW 3 +#define SIS133OLD 4 +#define SIS100NEW 5 +#define SIS100OLD 6 +#define SIS66 7 +#define SIS33 8 + +#define SIS_BASE 0x0100 +#define SIS_SOUTH 0x0200 + +#define INTEL_STD 0 +#define INTEL_IDX 1 + +#define ICH4_FIX 0x0100 +#define ICH5 0x0200 +#define I6CH 0x0400 +#define I6CH2 0x0800 +//#define I1CH 0x1000 // obsolete +#define ICH7 0x1000 + +#define NV4OFF 0x0100 +#define NVQ 0x0200 + +#define VIANEW 5 +#define VIA33 4 +#define VIA66 1 +#define VIA100 2 +#define VIA133 3 +#define AMDNVIDIA 0 +#define AMDCABLE 0x0100 +#define AMDBUG 0x0200 +#define VIABAR 0x0400 +#define VIACLK 0x0800 +#define VIABUG 0x1000 +#define VIASOUTH 0x2000 +#define VIAAST 0x4000 +#define VIAPRQ 0x8000 +#define VIASATA 0x10000 + +#define CYRIX_OLD 0 +#define CYRIX_3x 1 +#define CYRIX_NEW 2 +#define CYRIX_35 3 + +#define ITE_33 0 +#define ITE_133 1 +#define ITE_133_NEW 2 + +#ifdef USER_MODE +/* #define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \ + { (PVEN_STR) #idlo, 4, 0x##idlo, (PVEN_STR) #idhi, 4, 0x##idhi, rev, mode, (PVEN_STR)name, flags}*/ + #define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \ + { 0x##idlo, 0x##idhi, rev, mode, flags, name} +#else +/* #define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \ + { (PVEN_STR) #idlo, 4, 0x##idlo, (PVEN_STR) #idhi, 4, 0x##idhi, rev, mode, NULL, flags}*/ + #define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \ + { 0x##idlo, 0x##idhi, rev, mode, flags, name} +#endif + +#define BMLIST_TERMINATOR (0xffffffffL) + +extern BUSMASTER_CONTROLLER_INFORMATION_BASE const BusMasterAdapters[]; + +#define NUM_BUSMASTER_ADAPTERS _NUM_BUSMASTER_ADAPTERS +// _NUM_BUSMASTER_ADAPTERS = (sizeof(BusMasterAdapters) / sizeof(BUSMASTER_CONTROLLER_INFORMATION_BASE)) +extern ULONG const NUM_BUSMASTER_ADAPTERS; + +/* + Looks for device with specified Device/Vendor and Revision + in specified device list and returnts its index. + If no matching record found, -1 is returned +*/ +__inline +ULONG +Ata_is_dev_listed( + IN PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters, + ULONG VendorId, + ULONG DeviceId, + ULONG RevId, // min suitable revision + ULONG lim + ) +{ + for(ULONG k=0; kBaseClass == PCI_DEV_CLASS_STORAGE && \ + (pciData)->SubClass == PCI_DEV_SUBCLASS_IDE) + +#define Ata_is_ahci_dev(pciData) \ + ((pciData)->BaseClass == PCI_DEV_CLASS_STORAGE && \ + (pciData)->SubClass == PCI_DEV_SUBCLASS_SATA && \ + (pciData)->ProgIf == PCI_DEV_PROGIF_AHCI_1_0 && \ + ((pciData)->u.type0.BaseAddresses[5] & ~0x7)) + + +#pragma pack(pop) + +#endif //__IDE_BUSMASTER_DEVICES_H__ diff --git a/reactos/drivers/storage/ide/uniata/bsmaster.h b/reactos/drivers/storage/ide/uniata/bsmaster.h index a72ef2644c7..ac430b7cbd3 100644 --- a/reactos/drivers/storage/ide/uniata/bsmaster.h +++ b/reactos/drivers/storage/ide/uniata/bsmaster.h @@ -36,6 +36,9 @@ Revision History: Some definitions were taken from FreeBSD 4.3-9.2 ATA driver by Søren Schmidt, Copyright (c) 1998-2014 +Licence: + GPLv2 + --*/ #ifndef __IDE_BUSMASTER_H__ @@ -60,7 +63,7 @@ Revision History: #define ATA_WAIT_IDLE 0x9 -#include "bm_devs.h" +#include "bm_devs_decl.h" #include "uata_ctl.h" @@ -75,6 +78,7 @@ Revision History: #define IO_WD1 0x1F0 /* Primary Fixed Disk Controller */ #define IO_WD2 0x170 /* Secondary Fixed Disk Controller */ #define IP_PC98_BANK 0x432 +#define IO_FLOPPY_INT 0x3F6 /* AltStatus inside Floppy I/O range */ #define PCI_ADDRESS_IOMASK 0xfffffff0 @@ -1008,6 +1012,8 @@ typedef struct _HW_CHANNEL { PATA_REQ cur_req; ULONG cur_cdev; + ULONG last_cdev; /* device for which we have configured timings last time */ + ULONG last_devsel; /* device selected during last call to SelectDrive() */ /* PATA_REQ first_req; PATA_REQ last_req;*/ ULONG queue_depth; @@ -1123,6 +1129,7 @@ typedef struct _HW_CHANNEL { #define CTRFLAGS_LBA48 0x0040 #define CTRFLAGS_DSC_BSY 0x0080 #define CTRFLAGS_NO_SLAVE 0x0100 +//#define CTRFLAGS_DMA_BEFORE_R 0x0200 //#define CTRFLAGS_PATA 0x0200 //#define CTRFLAGS_NOT_PRESENT 0x0200 #define CTRFLAGS_AHCI_PM 0x0400 @@ -1439,7 +1446,7 @@ ScsiPortGetBusDataByOffset( extern ULONG NTAPI AtapiFindListedDev( - PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters, + PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters, ULONG lim, IN PVOID HwDeviceExtension, IN ULONG BusNumber, @@ -1878,6 +1885,10 @@ extern BOOLEAN InDriverEntry; extern BOOLEAN g_opt_Verbose; extern ULONG g_opt_VirtualMachine; +extern ULONG g_opt_WaitBusyResetCount; + +extern ULONG CPU_num; + #define VM_AUTO 0x00 #define VM_NONE 0x01 #define VM_VBOX 0x02 @@ -1885,7 +1896,7 @@ extern ULONG g_opt_VirtualMachine; #define VM_QEMU 0x04 #define VM_BOCHS 0x05 -#define VM_MAX_KNOWN VM_QEMU +#define VM_MAX_KNOWN VM_BOCHS extern BOOLEAN WinVer_WDM_Model; diff --git a/reactos/drivers/storage/ide/uniata/id_ata.cpp b/reactos/drivers/storage/ide/uniata/id_ata.cpp index 3a14017e5ef..e8e7a6c3fcd 100644 --- a/reactos/drivers/storage/ide/uniata/id_ata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_ata.cpp @@ -1,12 +1,12 @@ /*++ -Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter) Module Name: id_ata.cpp Abstract: - This is the miniport driver for ATA/ATAPI IDE controllers + This is the miniport driver for ATA/ATAPI IDE/SATA/AHCI controllers with Busmaster DMA and Serial ATA support Author: @@ -49,9 +49,12 @@ Revision History: 7. XP support (binary compatibility) 8. Serial ATA (SATA/SATA2/SATA3) support 9. NT 3.51 support (binary compatibility) + 10. AHCI support etc. (See todo.txt) +Licence: + GPLv2 --*/ @@ -68,8 +71,8 @@ WCHAR SavedRegPathBuffer[256]; #endif //UNIATA_CORE -UCHAR AtaCommands48[256]; -UCHAR AtaCommandFlags[256]; +//UCHAR AtaCommands48[256]; +//UCHAR AtaCommandFlags[256]; ULONG SkipRaids = 1; ULONG ForceSimplex = 0; @@ -83,14 +86,20 @@ ULONG g_LogToDisplay = 0; ULONG g_WaitBusyInISR = 1; +ULONG g_opt_WaitBusyResetCount = 10000; // 20000 ULONG g_opt_WaitBusyCount = 200; // 20000 ULONG g_opt_WaitBusyDelay = 10; // 150 ULONG g_opt_WaitDrqDelay = 10; // 100 ULONG g_opt_WaitBusyLongCount = 2000; // 2000 ULONG g_opt_WaitBusyLongDelay = 250; // 250 -ULONG g_opt_MaxIsrWait = 40; // +ULONG g_opt_MaxIsrWait = 40; + +ULONG g_opt_DriveSelectNanoDelay = 0; // 400; // ns + BOOLEAN g_opt_AtapiSendDisableIntr = 0; // 0 BOOLEAN g_opt_AtapiDmaRawRead = 1; // 0 +BOOLEAN g_opt_AtapiNoDma = FALSE; +BOOLEAN g_opt_BochsDmaReadWorkaround = FALSE; BOOLEAN hasPCI = FALSE; ULONG g_opt_VirtualMachine = 0; // Auto @@ -100,6 +109,7 @@ BOOLEAN InDriverEntry = TRUE; BOOLEAN g_opt_Verbose = 0; BOOLEAN WinVer_WDM_Model = FALSE; +ULONG CPU_num = 1; //UCHAR EnableDma = FALSE; //UCHAR EnableReorder = FALSE; @@ -559,6 +569,37 @@ AtapiSuckPortBuffer2( return i; } // AtapiSuckPortBuffer2() +UCHAR +DDKFASTAPI +SelectDrive( + IN PHW_CHANNEL chan, + IN ULONG DeviceNumber + ) +{ + if(!chan) { + return 0; + } +/* + if(chan->lun[DeviceNumber] && + (chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_CHANGER)) { + KdPrint3((" Select %d\n", DeviceNumber)); + } +*/ + if(chan->last_devsel == DeviceNumber) { + //KdPrint3((" Selected %d\n", DeviceNumber)); + return 1; + } + AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); \ + chan->last_devsel = DeviceNumber ? 1 : 0; + if(!g_opt_DriveSelectNanoDelay) { + //KdPrint3((" Select %d\n", DeviceNumber)); + return 2; + } + //KdPrint3((" Select %d (%d ns)\n", DeviceNumber, g_opt_DriveSelectNanoDelay)); + UniataNanoSleep(g_opt_DriveSelectNanoDelay); + return 2; +} // end SelectDrive() + UCHAR DDKFASTAPI WaitOnBusy( @@ -751,14 +792,14 @@ VOID DDKFASTAPI AtapiSoftReset( IN PHW_CHANNEL chan, - ULONG DeviceNumber + IN ULONG DeviceNumber ) { //ULONG c = chan->lChannel; ULONG i = 30 * 1000; UCHAR dma_status = 0; KdPrint2((PRINT_PREFIX "AtapiSoftReset:\n")); - UCHAR statusByte2; + UCHAR statusByte0, statusByte2; if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) { UniataAhciSoftReset(chan->DeviceExtension, chan->lChannel, DeviceNumber); @@ -770,24 +811,44 @@ AtapiSoftReset( SelectDrive(chan, DeviceNumber); if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MANUAL_CHS) { // For ESDI/MFM + KdPrint2((PRINT_PREFIX " ESDI/MFM\n")); AtapiStallExecution(10000); for (i = 0; i < 1000; i++) { AtapiStallExecution(999); } +/* } else + // Seems to be unnecessary, verified by KtP + if(!hasPCI) { + // original atapi.sys behavior for old ISA-only hardware + AtapiStallExecution(10000); + AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET); + for (i = 0; i < 1000; i++) { + AtapiStallExecution(999); + } */ } else { AtapiStallExecution(500); GetBaseStatus(chan, statusByte2); + statusByte0 = statusByte2; AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET); // Do not wait for BUSY assertion if it was initially set, jump to // BUSY release wait loop - if(!(statusByte2 & IDE_STATUS_BUSY)) { + if(!(statusByte0 & IDE_STATUS_BUSY)) { // Wait for BUSY assertion, in some cases delay may occure // 100ms should be enough - i = 10*1000; - while (!(AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) && + if(g_opt_VirtualMachine == VM_BOCHS) { + i = 100; + } else { + i = 10*1000; + } + statusByte2 = AtapiReadPort1(chan, IDX_IO1_i_Status); + while (!(statusByte2 & IDE_STATUS_BUSY) && i--) { + if(!(statusByte0 & IDE_STATUS_ERROR) && (statusByte2 & IDE_STATUS_ERROR)) { + KdPrint2((PRINT_PREFIX " Command aborted, statusByte2 %x:\n", statusByte2)); + break; + } AtapiStallExecution(10); } } @@ -806,6 +867,7 @@ AtapiSoftReset( chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_REINIT_DMA; } + chan->last_devsel = -1; // make sure proper drive would be selected SelectDrive(chan, DeviceNumber); WaitOnBusy(chan); GetBaseStatus(chan, statusByte2); @@ -834,6 +896,22 @@ AtapiSoftReset( } // end AtapiSoftReset() +VOID +DDKFASTAPI +AtapiHardReset( + IN struct _HW_CHANNEL* chan, + IN BOOLEAN DisableInterrupts, + IN ULONG Delay + ) +{ + KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts)); + AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER | + (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0)); + chan->last_devsel = -1; + AtapiStallExecution(Delay); + AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); +} // end AtapiHardReset() + /* Send command to device. Translate to 48-Lba form if required @@ -988,7 +1066,7 @@ AtaCommand48( AtapiStallExecution(100); continue; } else - if(statusByte == IDE_STATUS_IDLE) { + if((statusByte & ~IDE_STATUS_INDEX) == IDE_STATUS_IDLE) { break; } else { //if(deviceExtension->HwFlags & UNIATA_SATA) { @@ -1010,7 +1088,6 @@ AtaCommand48( case ATA_IMMEDIATE: GetStatus(chan, statusByte); if (statusByte & IDE_STATUS_ERROR) { - // Note: some diveces doesn't clear ERR immediately KdPrint2((PRINT_PREFIX " Warning: Immed Status %#x :(\n", statusByte)); if(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_ERROR)) { break; @@ -1246,7 +1323,7 @@ AtapiTimerDpc( /* Wrapper for ScsiPort, that implements smart Dpc queueing. We need it to allow parallel functioning - of IDE channles with shared interrupt. Standard Dpc mechanism + of IDE channels with shared interrupt. Standard Dpc mechanism cancels previous Dpc request (if any), but we need Dpc queue. */ VOID @@ -1345,7 +1422,7 @@ UniataDumpATARegs( } return; } // end UniataDumpATARegs() -#endif +#endif //_DEBUG VOID NTAPI @@ -1455,6 +1532,13 @@ IssueIdentify( statusByte = WaitOnBusyLong(chan); // Check that the status register makes sense. GetBaseStatus(chan, statusByte); + /* + // unnecessary + if(!hasPCI) { + // original atapi.sys behavior for old ISA-only hardware + AtapiStallExecution(100); + } + */ } if (Command == IDE_COMMAND_IDENTIFY) { @@ -1656,23 +1740,24 @@ IssueIdentify( GetBaseStatus(chan, statusByte); KdPrint2((PRINT_PREFIX "IssueIdentify: BASE statusByte %#x\n", statusByte)); +#ifdef _DEBUG + if(atapiDev) { + j = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask); + KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j)); + + j = + AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow); + + j |= + (USHORT)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8; + KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j)); + + } +#endif //_DEBUG + if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) { KdPrint2((PRINT_PREFIX " use 16bit IO\n")); -#ifdef _DEBUG - if(atapiDev) { - j = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask); - KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j)); - - j = - AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow); - - j |= - (USHORT)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8; - KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j)); - - } -#endif //DBG // ATI/SII chipsets with memory-mapped IO hangs when // I call ReadBuffer(), probably due to PCI burst/prefetch enabled // Unfortunately, I don't know yet how to workaround it except @@ -1703,6 +1788,24 @@ IssueIdentify( KdPrint2((PRINT_PREFIX "Model: %20.20s\n", deviceExtension->FullIdentifyData.ModelNumber)); KdPrint2((PRINT_PREFIX "FW: %4.4s\n", deviceExtension->FullIdentifyData.FirmwareRevision)); KdPrint2((PRINT_PREFIX "S/N: %20.20s\n", deviceExtension->FullIdentifyData.SerialNumber)); + if(g_opt_VirtualMachine == VM_AUTO) { + if((deviceExtension->FullIdentifyData.FirmwareRevision[0] == 0 || + deviceExtension->FullIdentifyData.FirmwareRevision[0] == ' ') && + (deviceExtension->FullIdentifyData.FirmwareRevision[1] == 0 || + deviceExtension->FullIdentifyData.FirmwareRevision[1] == ' ')) { + // Check for BOCHS VM signature. If no additional PCI devices (e.g. VGA) + // are declared BOCHS looks like regular PC + if (!atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDH00", 6)) { + KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS HDD\n")); + g_opt_VirtualMachine = VM_BOCHS; + } else + if (atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDC00", 6)) { + KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS CD\n")); + g_opt_VirtualMachine = VM_BOCHS; + } + } + } + KdPrint2((PRINT_PREFIX "Pio: %x\n", deviceExtension->FullIdentifyData.PioCycleTimingMode)); if(deviceExtension->FullIdentifyData.PioTimingsValid) { KdPrint2((PRINT_PREFIX "APio: %x\n", deviceExtension->FullIdentifyData.AdvancedPIOModes)); @@ -2073,14 +2176,27 @@ skip_lba_staff: deviceExtension->FullIdentifyData.CurrentSectorsPerTrack )); - if(NumOfSectors) + if(NumOfSectors) { LunExt->NumOfSectors = NumOfSectors; - } else { + } if(deviceExtension->FullIdentifyData.MajorRevision && deviceExtension->FullIdentifyData.DoubleWordIo) { - //LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; + LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; + KdPrint2((PRINT_PREFIX "IssueIdentify: DWORDIO supported\n")); + } + } else { + // ATAPI + if(deviceExtension->FullIdentifyData.MajorRevision && + deviceExtension->FullIdentifyData.DoubleWordIo) { + LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED; KdPrint2((PRINT_PREFIX "IssueIdentify: DFLAGS_DWORDIO_ENABLED.\n")); } + if(deviceExtension->FullIdentifyData.AtapiDMA.DMADirRequired) { + KdPrint2((PRINT_PREFIX "DMADirRequired.\n")); + } + if(deviceExtension->FullIdentifyData.AtapiByteCount0) { + KdPrint2((PRINT_PREFIX "AtapiByteCount0=%x\n", deviceExtension->FullIdentifyData.AtapiByteCount0)); + } } ScsiPortMoveMemory(&LunExt->IdentifyData, @@ -2115,7 +2231,6 @@ skip_lba_staff: LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_CD; LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_CD; statusByte = WaitForDrq(chan); - } else { KdPrint2((PRINT_PREFIX "IssueIdentify: ATAPI drive type %#x.\n", LunExt->IdentifyData.DeviceType)); @@ -2259,7 +2374,7 @@ AtapiResetController__( USHORT tmp16; KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber)); - KdPrint2((PRINT_PREFIX "simplexOnly %d\n", deviceExtension->simplexOnly)); + KdPrint2((PRINT_PREFIX "simplexOnly %d, VM %x\n", deviceExtension->simplexOnly, g_opt_VirtualMachine)); if(!deviceExtension->simplexOnly && (PathId != CHAN_NOT_SPECIFIED)) { // we shall reset both channels on SimplexOnly devices, @@ -2276,7 +2391,9 @@ AtapiResetController__( KdPrint2((PRINT_PREFIX "AtapiResetController: Reset lchannel %d[%d]\n", j, deviceExtension->Channel)); chan = &(deviceExtension->chan[j]); MaxLuns = chan->NumberLuns; - KdPrint2((PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x, sptr %#x\n", CompleteType, MaxLuns, chan, &chan)); + // Save control flags + ChannelCtrlFlags = chan->ChannelCtrlFlags; + KdPrint2((PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x, sptr %#x, flags %#x\n", CompleteType, MaxLuns, chan, &chan, ChannelCtrlFlags)); //MaxLuns = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2; if(CompleteType != RESET_COMPLETE_NONE) { #ifndef UNIATA_CORE @@ -2315,7 +2432,7 @@ AtapiResetController__( ASSERT(AtaReq->Srb == CurSrb); if (CurSrb) { // Complete outstanding request with SRB_STATUS_BUS_RESET. - UCHAR PathId = CurSrb->PathId; + UCHAR CurPathId = CurSrb->PathId; UCHAR TargetId = CurSrb->TargetId; UCHAR Lun = CurSrb->Lun; @@ -2325,7 +2442,7 @@ AtapiResetController__( if (CurSrb->SenseInfoBuffer) { PSENSE_DATA senseBuffer = (PSENSE_DATA)CurSrb->SenseInfoBuffer; - KdPrint2((PRINT_PREFIX " senseBuffer %#x, chan %#x\n", senseBuffer, chan)); + KdPrint2((PRINT_PREFIX " senseBuffer %#x, chan %#x, ReqFlags %#x\n", senseBuffer, chan, AtaReq->Flags)); senseBuffer->ErrorCode = 0x70; senseBuffer->Valid = 1; @@ -2344,10 +2461,37 @@ AtapiResetController__( } if(!ATAPI_DEVICE(chan, i) && AtaReq->bcount && AtaReq->retry < MAX_RETRIES) { - KdPrint2((PRINT_PREFIX "Save retry status %d\n", AtaReq->retry)); + KdPrint2((PRINT_PREFIX "Save IDE retry status %d\n", AtaReq->retry)); LunExt->errLastLba = AtaReq->lba; LunExt->errBCount = AtaReq->bcount; LunExt->errRetry = AtaReq->retry+1; + //KdPrint2((PRINT_PREFIX "AtaReq->Flags & REQ_FLAG_RW_MASK = %x (%x)\n", (AtaReq->Flags & REQ_FLAG_RW_MASK), REQ_FLAG_READ)); + //KdPrint2((PRINT_PREFIX "ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION = %x (%x)\n", ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE, CTRFLAGS_DMA_OPERATION)); + //KdPrint2((PRINT_PREFIX "g_opt_VirtualMachine = %x (%x)\n", g_opt_VirtualMachine, VM_BOCHS)); + if(((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_READ) && + (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) && + (g_opt_VirtualMachine == VM_BOCHS)) { + KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS\n")); + g_opt_BochsDmaReadWorkaround = TRUE; + g_opt_AtapiNoDma = TRUE; + } else { + KdPrint2((PRINT_PREFIX "do nothing\n")); + } + } else + if(ATAPI_DEVICE(chan, i) && AtaReq->bcount && !AtaReq->retry) { + KdPrint2((PRINT_PREFIX "Save ATAPI retry status %d\n", AtaReq->retry)); + LunExt->errLastLba = AtaReq->lba; + LunExt->errBCount = AtaReq->bcount; + LunExt->errRetry = AtaReq->retry+1; + if(((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_READ) && + (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) && + (g_opt_VirtualMachine == VM_BOCHS)) { + KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS ATAPI\n")); + //g_opt_BochsDmaReadWorkaround = TRUE; + g_opt_AtapiNoDma = TRUE; + } else { + KdPrint2((PRINT_PREFIX "do nothing\n")); + } } else { LunExt->errRetry = 0; } @@ -2365,7 +2509,7 @@ AtapiResetController__( // Indicate ready for next request. ScsiPortNotification(NextLuRequest, deviceExtension, - PathId, + CurPathId, TargetId, Lun); } @@ -2375,12 +2519,10 @@ AtapiResetController__( #endif //UNIATA_CORE } // end if (!CompleteType != RESET_COMPLETE_NONE) - // Save control flags - ChannelCtrlFlags = chan->ChannelCtrlFlags; // Clear expecting interrupt flag. UniataExpectChannelInterrupt(chan, FALSE); chan->RDP = FALSE; - chan->ChannelCtrlFlags = 0; + chan->ChannelCtrlFlags = ChannelCtrlFlags & CTRFLAGS_PERMANENT; InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE); @@ -2458,11 +2600,22 @@ AtapiResetController__( AtapiStallExecution(10000); } break; } - case ATA_SIS_ID: + case ATA_SIS_ID: { + KdPrint2((PRINT_PREFIX " SIS\n")); + if(!(ChipFlags & UNIATA_SATA)) + goto default_reset; + break; } +#if 0 + case ATA_NVIDIA_ID: { + KdPrint2((PRINT_PREFIX " nVidia\n")); + if(!(ChipFlags & UNIATA_SATA)) + goto default_reset; + break; } +#else case ATA_NVIDIA_ID: { ULONG offs; ULONG Channel = deviceExtension->Channel + j; - KdPrint2((PRINT_PREFIX " SIS/nVidia\n")); + KdPrint2((PRINT_PREFIX " nVidia\n")); if(!(ChipFlags & UNIATA_SATA)) { goto default_reset; } @@ -2495,6 +2648,7 @@ AtapiResetController__( goto default_reset; } break; } +#endif //0 case ATA_SILICON_IMAGE_ID: { ULONG offset; ULONG Channel = deviceExtension->Channel + j; @@ -2523,9 +2677,10 @@ AtapiResetController__( UniataSataClearErr(HwDeviceExtension, j, UNIATA_SATA_IGNORE_CONNECT, 0); } default_reset: - KdPrint2((PRINT_PREFIX " send reset\n")); +/* AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS | IDE_DC_RESET_CONTROLLER ); + chan->last_devsel = -1; KdPrint2((PRINT_PREFIX " wait a little\n")); AtapiStallExecution(10000); // Disable interrupts @@ -2536,6 +2691,13 @@ default_reset: AtapiEnableInterrupts(deviceExtension, j); KdPrint2((PRINT_PREFIX " wait a little (2)\n")); AtapiStallExecution(100000); +*/ + AtapiHardReset(chan, TRUE, 100000); + KdPrint2((PRINT_PREFIX " disable intr\n")); + AtapiDisableInterrupts(deviceExtension, j); + AtapiStallExecution(100); + KdPrint2((PRINT_PREFIX " re-enable intr\n")); + AtapiEnableInterrupts(deviceExtension, j); KdPrint2((PRINT_PREFIX " done\n")); break; @@ -3809,7 +3971,7 @@ AtapiInterrupt( ULONG hIS; ULONG checked; - KdPrint2((PRINT_PREFIX "Intr: VendorID+DeviceID/Rev %#x/%#x (ex %d)\n", + KdPrint2((PRINT_PREFIX "Intr: DeviceID+VendorID/Rev %#x/%#x (ex %d)\n", deviceExtension->DevID, deviceExtension->RevID, deviceExtension->ExpectingInterrupt )); if(deviceExtension->HwFlags & UNIATA_AHCI) { @@ -4437,7 +4599,7 @@ AtapiCheckInterrupt__( KdPrint2((PRINT_PREFIX "NVIDIA\n")); ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010; - ULONG shift = Channel << ((ChipFlags & NVQ) ? 4 : 2); + ULONG shift = Channel * ((ChipFlags & NVQ) ? 4 : 16); /* get and clear interrupt status */ if(ChipFlags & NVQ) { @@ -4647,7 +4809,8 @@ skip_dma_stat_check: KdPrint2((PRINT_PREFIX " expecting intr + BUSY (3), non ATAPI\n")); return INTERRUPT_REASON_IGNORE; } - if((statusByte & ~IDE_STATUS_DRQ) != (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) { + if((statusByte & ~(IDE_STATUS_DRQ | IDE_STATUS_INDEX)) != + (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) { KdPrint3((PRINT_PREFIX " unexpected status, seems it is not our\n")); return INTERRUPT_REASON_IGNORE; } @@ -4764,7 +4927,7 @@ AtapiInterrupt__( #ifdef _DEBUG UCHAR Channel; -#endif //DBG +#endif //_DEBUG UCHAR lChannel; UCHAR DeviceNumber; BOOLEAN DmaTransfer = FALSE; @@ -4801,7 +4964,7 @@ AtapiInterrupt__( Channel = (UCHAR)(deviceExtension->Channel + lChannel); KdPrint2((PRINT_PREFIX " cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c)); -#endif //DBG +#endif //_DEBUG if((chan->ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) || (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) || @@ -5468,7 +5631,7 @@ IntrPrepareResetController: chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION; goto CompleteRequest; } else - if (interruptReason == ATAPI_IR_COD_Cmd && (statusByte & IDE_STATUS_DRQ)) { + if ((interruptReason == ATAPI_IR_COD_Cmd) && (statusByte & IDE_STATUS_DRQ)) { if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) { AtapiDmaDBPreSync(HwDeviceExtension, chan, srb); } @@ -5477,7 +5640,7 @@ IntrPrepareResetController: // Send CDB to device. WriteBuffer(chan, (PUSHORT)srb->Cdb, LunExt->IdentifyData.AtapiCmdSize ? 8 : 6, - 0); + /*0*/ PIO0_TIMING); AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) { @@ -5487,7 +5650,7 @@ IntrPrepareResetController: goto ReturnEnableIntr; - } else if (interruptReason == ATAPI_IR_IO_toDev && (statusByte & IDE_STATUS_DRQ)) { + } else if ((interruptReason == ATAPI_IR_IO_toDev) && (statusByte & IDE_STATUS_DRQ)) { // Write the data. if (atapiDev) { @@ -5554,25 +5717,25 @@ IntrPrepareResetController: // Ensure that this is a write command. if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) { - KdPrint2((PRINT_PREFIX - "AtapiInterrupt: Write interrupt\n")); + KdPrint2((PRINT_PREFIX + "AtapiInterrupt: Write interrupt\n")); - statusByte = WaitOnBusy(chan); + statusByte = WaitOnBusy(chan); - if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/ + if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/ || (wordCount & 1)) { - WriteBuffer(chan, - AtaReq->DataBuffer, - wordCount, - UniataGetPioTiming(LunExt)); - } else { + WriteBuffer(chan, + AtaReq->DataBuffer, + wordCount, + UniataGetPioTiming(LunExt)); + } else { - WriteBuffer2(chan, - (PULONG)(AtaReq->DataBuffer), - wordCount / 2, - UniataGetPioTiming(LunExt)); - } + WriteBuffer2(chan, + (PULONG)(AtaReq->DataBuffer), + wordCount / 2, + UniataGetPioTiming(LunExt)); + } } else { KdPrint3((PRINT_PREFIX @@ -5580,28 +5743,6 @@ IntrPrepareResetController: interruptReason, srb)); - if(!wordCount && atapiDev && - !(statusByte & (IDE_STATUS_ERROR | IDE_STATUS_BUSY)) && - (statusByte & IDE_STATUS_DRQ)) { - // this can be late Packet interrupt after packet sending - KdPrint2((PRINT_PREFIX " unreliable wordCount ?\n")); - - wordCount = AtapiSuckPortBuffer2(chan, - AtaReq->DataBuffer, - AtaReq->WordsLeft); - KdPrint2((PRINT_PREFIX " transferred %#x\n", wordCount)); - GetBaseStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX " status %#x, statusByte\n")); - if(wordCount) { - interruptReason = ATAPI_IR_IO_toHost; -#ifdef _DEBUG - UniataDumpATARegs(chan); -#endif - } - if(wordCount && AtaReq->WordsLeft) { - goto continue_atapi_pio_read; - } - } // Fail this request. status = SRB_STATUS_ERROR; if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) { @@ -5632,18 +5773,24 @@ IntrPrepareResetController: } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) { +continue_read_drq: if (atapiDev) { // Pick up bytes to transfer and convert to words. wordCount = - AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow) | - (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8); + (ULONG)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow) | + ((ULONG)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8); // Convert bytes to words. - wordCount >>= 1; - KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R wordCount %#x\n", wordCount)); - + KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R byteCount %#x\n", wordCount)); + wordCount >>= 1; + /* + When ATAPI 64k PIO read is requested we may have 0xfffe byte + count reported for 0x10000 bytes in single interrupt. + It is not allowed to read entire 64k block with DwordIo intead of + wait for last word. + */ if (wordCount != AtaReq->WordsLeft) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: %d words requested; %d words xferred\n", @@ -5689,7 +5836,6 @@ IntrPrepareResetController: chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION; goto CompleteRequest; } -continue_read_drq: // Ensure that this is a read command. if (srb->SrbFlags & SRB_FLAGS_DATA_IN) { @@ -5698,8 +5844,21 @@ continue_read_drq: statusByte = WaitOnBusy(chan); - if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/ - || (wordCount & 1)) { + if(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) { + KdPrint2((PRINT_PREFIX + "IdeIntr: pre-Read %#x Dwords\n", wordCount/2)); + + ReadBuffer2(chan, + (PULONG)(AtaReq->DataBuffer), + wordCount / 2, + UniataGetPioTiming(LunExt)); + // Advance data buffer pointer and bytes left. + AtaReq->DataBuffer += wordCount & ~1; + AtaReq->WordsLeft -= wordCount & ~1; + AtaReq->WordsTransfered += wordCount & ~1; + wordCount &= 1; + } + if (wordCount) { KdPrint2((PRINT_PREFIX "IdeIntr: Read %#x words\n", wordCount)); @@ -5707,39 +5866,33 @@ continue_read_drq: AtaReq->DataBuffer, wordCount, 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); - } + } + 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); + } + + GetBaseStatus(chan, statusByte); + KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte)); + + if(DataOverrun) { + KdPrint2((PRINT_PREFIX " DataOverrun\n")); + AtapiSuckPort2(chan); GetBaseStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte)); + } - if(DataOverrun) { - KdPrint2((PRINT_PREFIX " DataOverrun\n")); - AtapiSuckPort2(chan); + if(statusByte & IDE_STATUS_BUSY) { + for (i = 0; i < 2; i++) { + AtapiStallExecution(10); GetBaseStatus(chan, statusByte); - } - - if(statusByte & IDE_STATUS_BUSY) { - for (i = 0; i < 2; i++) { - AtapiStallExecution(10); - GetBaseStatus(chan, statusByte); - if (!(statusByte & IDE_STATUS_BUSY)) { - break; - } + if (!(statusByte & IDE_STATUS_BUSY)) { + break; } } - } else { - KdPrint2((PRINT_PREFIX - "IdeIntr: Read %#x Dwords\n", wordCount/2)); - - ReadBuffer2(chan, - (PULONG)(AtaReq->DataBuffer), - wordCount / 2, - UniataGetPioTiming(LunExt)); } + } else { KdPrint3((PRINT_PREFIX @@ -5751,7 +5904,7 @@ continue_read_drq: status = SRB_STATUS_ERROR; goto CompleteRequest; } -continue_atapi_pio_read: +//continue_atapi_pio_read: // Advance data buffer pointer and bytes left. AtaReq->DataBuffer += wordCount; AtaReq->WordsLeft -= wordCount; @@ -5763,23 +5916,35 @@ continue_atapi_pio_read: KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n")); if (atapiDev) { - // Work around to make many atapi devices return correct sector size - // of 2048. Also certain devices will have sector count == 0x00, check - // for that also. - if ((srb->Cdb[0] == SCSIOP_READ_CAPACITY) && - (LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM)) { + if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) { - AtaReq->DataBuffer -= wordCount; - if (AtaReq->DataBuffer[0] == 0x00) { + // Work around to make many atapi devices return correct sector size + // of 2048. Also certain devices will have sector count == 0x00, check + // for that also. + if (srb->Cdb[0] == SCSIOP_READ_CAPACITY) { - *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F; + AtaReq->DataBuffer -= wordCount; + if (AtaReq->DataBuffer[0] == 0x00) { + *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F; + } + *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000; + AtaReq->DataBuffer += wordCount; } +#ifndef UNIATA_INIT_CHANGERS + else + if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) { - *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000; - AtaReq->DataBuffer += wordCount; + KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status)); + // Bingo!! + AtapiHwInitializeChanger (HwDeviceExtension, + srb, + (PMECHANICAL_STATUS_INFORMATION_HEADER) srb->DataBuffer); + LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED; + KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n")); + } +#endif // UNIATA_INIT_CHANGERS } - GetStatus(chan, statusByte); if(!(statusByte & IDE_STATUS_BUSY)) { // Assume command is completed if BUSY is cleared @@ -5824,7 +5989,7 @@ continue_atapi_pio_read: } } else { if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) && - (statusByte == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) { + ((statusByte & ~IDE_STATUS_INDEX) == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) { KdPrint2((PRINT_PREFIX " HDD read data ready \n")); goto continue_read_drq; } @@ -5880,7 +6045,7 @@ continue_atapi_pio_read: } KdPrint(("--\n")); - KdPrint2(("VendorID+DeviceID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID)); + KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID)); KdPrint2(("P:T:D=%d:%d:%d\n", Srb->PathId, Srb->TargetId, @@ -5925,7 +6090,8 @@ CompleteRequest: KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n")); if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) { - +#ifdef UNIATA_INIT_CHANGERS + // We can get here only when UNIATA_INIT_CHANGERS is defined KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status)); if (status == SRB_STATUS_SUCCESS) { // Bingo!! @@ -5966,7 +6132,10 @@ CompleteRequest: AtapiDisableInterrupts(HwDeviceExtension, c); } */ - +#else + KdPrint((PRINT_PREFIX "AtapiInterrupt: ERROR: internal SCSIOP_MECHANISM_STATUS !!!!\n")); + ASSERT(FALSE); +#endif // UNIATA_INIT_CHANGERS } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE) PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer; @@ -5982,7 +6151,9 @@ CompleteRequest: if (status == SRB_STATUS_SUCCESS) { #ifndef UNIATA_CORE +#ifdef UNIATA_INIT_CHANGERS if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) && + FALSE && chan->MechStatusRetryCount) { KdPrint3((PRINT_PREFIX "AtapiInterrupt: MechStatusRetryCount %#x\n", chan->MechStatusRetryCount)); @@ -5991,14 +6162,9 @@ CompleteRequest: srb = AtaReq->Srb = BuildMechanismStatusSrb ( HwDeviceExtension, AtaReq->OriginalSrb); - } else { - - // last request was illegal. No point trying again. - // Do-nothing call ? - AtapiHwInitializeChanger (HwDeviceExtension, - srb, - (PMECHANICAL_STATUS_INFORMATION_HEADER) NULL); - + } else +#endif // UNIATA_INIT_CHANGERS + { // Get ready to issue the original srb srb = AtaReq->Srb = AtaReq->OriginalSrb; AtaReq->OriginalSrb = NULL; @@ -6036,11 +6202,6 @@ CompleteRequest: KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n")); if (AtaReq->OriginalSrb) { - KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiHwInitializeChanger()\n")); - // Do-nothing call ? - AtapiHwInitializeChanger (HwDeviceExtension, - srb, - (PMECHANICAL_STATUS_INFORMATION_HEADER) NULL); srb = AtaReq->Srb = AtaReq->OriginalSrb; AtaReq->OriginalSrb = NULL; } @@ -6575,6 +6736,7 @@ UniAtaCalculateLBARegs( ULONG tmp; if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) { + (*max_bcount) = 0; if(LunExt->LimitedTransferMode >= ATA_DMA) { if(LunExt->DeviceExtension) { (*max_bcount) = LunExt->DeviceExtension->MaximumDmaTransferLength / DEV_BSIZE; @@ -6598,7 +6760,6 @@ UniAtaCalculateLBARegs( KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n", cylinder, drvSelect, sectorNumber, (*max_bcount))); } - (*max_bcount) = 0; return (ULONG)(sectorNumber&0xff) | (((ULONG)cylinder&0xffff)<<8) | (((ULONG)drvSelect&0xf)<<24); } // end UniAtaCalculateLBARegs() @@ -6664,7 +6825,7 @@ IdeReadWrite( //ULONG ldev = GET_LDEV(Srb); UCHAR DeviceNumber = GET_CDEV(Srb);; ULONGLONG startingSector=0; - ULONG max_bcount; + ULONG max_bcount = 0; ULONG wordCount = 0; UCHAR statusByte,statusByte2; UCHAR cmd; @@ -6743,6 +6904,7 @@ IdeReadWrite( AtaReq->lba = lba; if(LunExt->errRetry && lba == LunExt->errLastLba && + /* AtaReq->bcount && */ // errRetry can be set only for non-zero bcount AtaReq->bcount == LunExt->errBCount) { KdPrint3((PRINT_PREFIX "IdeReadWrite: Retry after BUS_RESET %d @%#I64x (%#x)\n", LunExt->errRetry, LunExt->errLastLba, LunExt->errBCount)); @@ -6750,6 +6912,7 @@ IdeReadWrite( AtaReq->retry = LunExt->errRetry; AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE; } + LunExt->errRetry = 0; } // assume best case here @@ -6878,6 +7041,11 @@ IdeReadWrite( use_dma) { if(use_dma) { AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb); + if(g_opt_BochsDmaReadWorkaround && + (Srb->SrbFlags & SRB_FLAGS_DATA_IN)) { + KdPrint2((PRINT_PREFIX "CTRFLAGS_DMA_BEFORE_R on BOCHS\n")); + AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb); + } } statusByte2 = AtaCommand48(deviceExtension, DeviceNumber, lChannel, cmd, lba, @@ -6896,8 +7064,11 @@ IdeReadWrite( return SRB_STATUS_ERROR; } if(use_dma) { - //GetStatus(chan, statusByte2); - AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb); + if(!g_opt_BochsDmaReadWorkaround || + !(Srb->SrbFlags & SRB_FLAGS_DATA_IN)) { + //GetStatus(chan, statusByte2); + AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb); + } } return SRB_STATUS_PENDING; } @@ -7116,10 +7287,11 @@ AtapiSendCommand( ULONG DeviceNumber = GET_CDEV(Srb); ULONG flags; UCHAR statusByte,statusByte0,byteCountLow,byteCountHigh; + UCHAR interruptReason; BOOLEAN use_dma = FALSE; BOOLEAN dma_reinited = FALSE; BOOLEAN retried = FALSE; - ULONG fis_size; + ULONG fis_size, i; UCHAR FeatureReg=0; LunExt = chan->lun[DeviceNumber]; @@ -7147,7 +7319,7 @@ AtapiSendCommand( } KdPrint(("--\n")); - KdPrint2(("VendorID+DeviceID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID)); + KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID)); KdPrint2(("P:T:D=%d:%d:%d\n", Srb->PathId, Srb->TargetId, @@ -7231,20 +7403,30 @@ AtapiSendCommand( return SRB_STATUS_BUSY; } // +#ifdef UNIATA_INIT_CHANGERS if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) && !AtaReq->OriginalSrb) { KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY (2)\n")); return SRB_STATUS_BUSY; } +#endif // UNIATA_INIT_CHANGERS } #ifndef UNIATA_CORE + // standard atapi.sys claims: + // We need to know how many platters our atapi cd-rom device might have. // Before anyone tries to send a srb to our target for the first time, // we must "secretly" send down a separate mechanism status srb in order to // initialize our device extension changer data. That's how we know how // many platters our target has. + // BUT! + // some devices freeze (sometimes) forever on this command + // Let CD-ROM driver send this command itself, if it find it necessary + // We shall just parse output (if any) + +#ifdef UNIATA_INIT_CHANGERS if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) && !AtaReq->OriginalSrb) { @@ -7282,17 +7464,12 @@ AtapiSendCommand( } // failed again ? should not get here - AtaReq->Srb = AtaReq->OriginalSrb; AtaReq->OriginalSrb = NULL; - - KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiHwInitializeChanger()\n")); - // Do-nothing call ? - AtapiHwInitializeChanger (HwDeviceExtension, Srb, - (PMECHANICAL_STATUS_INFORMATION_HEADER) NULL); // fall out } } +#endif // UNIATA_INIT_CHANGERS #endif //UNIATA_CORE if((CmdAction & CMD_ACTION_PREPARE) && @@ -7360,6 +7537,10 @@ GetLba2: } // check if DMA read/write + if(g_opt_AtapiNoDma) { + KdPrint2((PRINT_PREFIX "AtapiSendCommand: CTRFLAGS_DMA_BEFORE_R => no dma\n")); + use_dma = FALSE; + } else if(deviceExtension->HwFlags & UNIATA_AHCI) { KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (ahci)\n")); use_dma = TRUE; @@ -7373,8 +7554,9 @@ GetLba2: if(Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) { KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE, no DMA setup\n")); } else - if(AtaReq->TransferLength) { - // try use DMA + if(AtaReq->TransferLength && !(AtaReq->TransferLength & 0x0f)) { + KdPrint2((PRINT_PREFIX "AtapiSendCommand: try DMA setup\n")); + // try use DMA if TransferLength is 16-byte aligned switch(Srb->Cdb[0]) { case SCSIOP_WRITE: case SCSIOP_WRITE12: @@ -7444,7 +7626,7 @@ setup_dma: } } } else { - KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero transfer, no DMA setup\n")); + KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero/unaligned transfer %x, no DMA setup\n", AtaReq->TransferLength)); } @@ -7466,9 +7648,11 @@ setup_dma: AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION; } else { FeatureReg |= ATA_F_DMA; - if(LunExt->IdentifyData.AtapiDMA.DMADirRequired && - (Srb->SrbFlags & SRB_FLAGS_DATA_IN)) { - FeatureReg |= ATA_F_DMAREAD; + if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) { + if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) { + KdPrint2((PRINT_PREFIX "Set DMADir.\n")); + FeatureReg |= ATA_F_DMAREAD; + } } } @@ -7659,9 +7843,8 @@ retry: } */ if (statusByte & IDE_STATUS_DRQ) { + KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted. Status (%#x)\n", statusByte)); make_reset: - KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted.Status (%#x)\n", statusByte)); - AtapiDisableInterrupts(deviceExtension, lChannel); AtapiSoftReset(chan, DeviceNumber); @@ -7728,29 +7911,25 @@ make_reset: if(use_dma) { FeatureReg |= ATA_F_DMA; - if(LunExt->IdentifyData.AtapiDMA.DMADirRequired && - (Srb->SrbFlags & SRB_FLAGS_DATA_IN)) { - FeatureReg |= ATA_F_DMAREAD; + if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) { + if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) { + FeatureReg |= ATA_F_DMAREAD; + } } } - AtapiWritePort1(chan, IDX_IO1_o_Feature, FeatureReg); - // Write transfer byte count to registers. - byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF); - byteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8); - if (Srb->DataTransferLength >= 0x10000) { byteCountLow = byteCountHigh = 0xFF; + } else { + byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF); + byteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8); } - AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountLow, byteCountLow); - AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, byteCountHigh); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: F:%#x, CntHL:%#x:%#x.\n", FeatureReg, byteCountHigh, byteCountLow)); if (flags & DFLAGS_INT_DRQ) { - // This device interrupts when ready to receive the packet. - KdPrint3((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n", statusByte)); @@ -7758,43 +7937,50 @@ make_reset: AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_CMD_INTR; InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE); + // inform driver that packet command must be sent in ISR + flags |= DFLAGS_INT_DRQ; + } else { + // This device quickly sets DRQ when ready to receive the packet. + KdPrint2((PRINT_PREFIX "AtapiSendCommand: Poll for int. to send packet. Status (%#x)\n", + statusByte)); - // Write ATAPI packet command. - AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET); + UniataExpectChannelInterrupt(chan, TRUE); + AtaReq->ReqState = REQ_STATE_ATAPI_DO_NOTHING_INTR; + InterlockedExchange(&(chan->CheckIntr), + CHECK_INTR_IDLE); + if(g_opt_AtapiSendDisableIntr) { + AtapiDisableInterrupts(deviceExtension, lChannel); + } + // remember status. Later we may check if error appeared after cmd packet + statusByte0 = statusByte; + } + + // must be already selected, experimental for ROS BUG-9119 + //AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) ); + AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Feature /*IDX_IO1_o_Feature*/, FeatureReg); + //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused0, 0); // experimental for ROS BUG-9119 + //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused1, 0); // experimental for ROS BUG-9119 + AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountLow, byteCountLow); + AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, byteCountHigh); + // Write ATAPI packet command. + AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Command /*IDX_IO1_o_Command*/, IDE_COMMAND_ATAPI_PACKET); + + if (flags & DFLAGS_INT_DRQ) { + // Wait for interrupt and send PACKET there KdPrint3((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (DRQ)\n")); return SRB_STATUS_PENDING; - } - // This device quickly sets DRQ when ready to receive the packet. - - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Poll for int. to send packet. Status (%#x)\n", - statusByte)); - - UniataExpectChannelInterrupt(chan, TRUE); - AtaReq->ReqState = REQ_STATE_ATAPI_DO_NOTHING_INTR; - InterlockedExchange(&(chan->CheckIntr), - CHECK_INTR_IDLE); - - if(g_opt_AtapiSendDisableIntr) { - AtapiDisableInterrupts(deviceExtension, lChannel); - } - // remember status. Later we may check if error appeared after cmd packet - statusByte0 = statusByte; - - // Write ATAPI packet command. - AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET); - - // Wait for DRQ. WaitOnBusy(chan); +/* + // Wait for DRQ. statusByte = WaitForDrq(chan); // Need to read status register and clear interrupt (if any) GetBaseStatus(chan, statusByte); if (!(statusByte & IDE_STATUS_DRQ)) { - if(g_opt_AtapiSendDisableIntr) { AtapiEnableInterrupts(deviceExtension, lChannel); } @@ -7802,27 +7988,57 @@ make_reset: AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; return SRB_STATUS_ERROR; } - +*/ GetStatus(chan, statusByte); KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte)); - // Send CDB to device. - statusByte = WaitOnBaseBusy(chan); + //statusByte = WaitOnBaseBusy(chan); // Indicate expecting an interrupt and wait for it. UniataExpectChannelInterrupt(chan, TRUE); - InterlockedExchange(&(chan->CheckIntr), - CHECK_INTR_IDLE); - AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; + for(i=0; i<5000; i++) { + if(g_opt_AtapiSendDisableIntr) { + GetStatus(chan, statusByte); + } else { + GetBaseStatus(chan, statusByte); + } + interruptReason = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason); + //KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i)); + if(((interruptReason & ATAPI_IR_COD) == ATAPI_IR_COD_Cmd) && + (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) == IDE_STATUS_DRQ))) { + break; + } + AtapiStallExecution(g_opt_WaitDrqDelay*2); +#ifdef _DEBUG +// KdPrint3((PRINT_PREFIX "AtapiSendCommand: wait CoD, status (%#x)\n", interruptReason)); +#endif // _DEBUG + } + if(((interruptReason & ATAPI_IR_COD) != ATAPI_IR_COD_Cmd) || + (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) != IDE_STATUS_DRQ)) ) { + KdPrint3((PRINT_PREFIX "AtapiSendCommand: no CoD raised, abort cmd\n")); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte)); + if(g_opt_AtapiSendDisableIntr) { + AtapiEnableInterrupts(deviceExtension, lChannel); + } + KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ+CoD never asserted\n")); + statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte)); + if(statusByte >> 4) { + GetBaseStatus(chan, statusByte); + AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; + return MapError(deviceExtension, Srb); + } + goto make_reset; +// AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; +// return SRB_STATUS_ERROR; + } else { + KdPrint3((PRINT_PREFIX "AtapiSendCommand: ready for packet, status %#x, i=%d\n", interruptReason, i)); + } // clear interrupt GetBaseStatus(chan, statusByte); -#ifdef _DEBUG - statusByte = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask); - KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", statusByte)); -#endif //DBG - if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) { AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb); } @@ -7830,10 +8046,11 @@ make_reset: AtapiEnableInterrupts(deviceExtension, lChannel); } + // Send CDB to device. WriteBuffer(chan, (PUSHORT)Srb->Cdb, LunExt->IdentifyData.AtapiCmdSize ? 8 : 6, - 0); + /*0*/ PIO0_TIMING); GetStatus(chan, statusByte); KdPrint3((PRINT_PREFIX "AtapiSendCommand: cmd status (%#x)\n", statusByte)); @@ -7841,7 +8058,6 @@ make_reset: // When we operate in DMA mode, we should not start transfer when there is an error on entry // Interrupt may never come in such case. if(statusByte & IDE_STATUS_ERROR) { - UCHAR interruptReason; GetBaseStatus(chan, statusByte); KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on cmd: (%#x)\n", statusByte)); @@ -7855,8 +8071,11 @@ make_reset: AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; return MapError(deviceExtension, Srb); } -/* if(statusByte & IDE_STATUS_DSC) { - KdPrint3((PRINT_PREFIX "AtapiSendCommand: DSC on cmd: (%#x)\n", statusByte)); + if(statusByte & IDE_STATUS_DRQ) { + // Some devices require this. If error condition is not checked in such a way, + // device may not operate correctly and would be treated as failed + // (and finally invisible for OS) + KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ on cmd: (%#x)\n", statusByte)); // Read the error reg. to clear it and fail this request. statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error); KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte)); @@ -7866,11 +8085,15 @@ make_reset: return MapError(deviceExtension, Srb); } } -*/ + if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) { AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb); } + InterlockedExchange(&(chan->CheckIntr), + CHECK_INTR_IDLE); + AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; + KdPrint3((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt)); KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (3)\n")); @@ -9010,7 +9233,7 @@ AtapiStartIo__( 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)); + KdPrint2((PRINT_PREFIX " DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID)); if(lChannel == deviceExtension->NumberChannels && !Srb->Lun && !Srb->TargetId && @@ -10084,7 +10307,7 @@ complete_req: } // end AtapiStartIo__() - +#if 0 void NTAPI UniataInitAtaCommands() @@ -10249,6 +10472,7 @@ UniataInitAtaCommands() AtaCommandFlags[i] = flags; } } // end UniataInitAtaCommands() +#endif /*++ @@ -10275,7 +10499,7 @@ DriverEntry( { HW_INITIALIZATION_DATA_COMMON hwInitializationData; ULONG adapterCount; - ULONG i, c, alt; + ULONG i, c, alt, pref_alt; ULONG statusToReturn, newStatus; PUNICODE_STRING RegistryPath = (PUNICODE_STRING)Argument2; BOOLEAN ReEnter = FALSE; @@ -10287,6 +10511,8 @@ DriverEntry( PCONFIGURATION_INFORMATION GlobalConfig = IoGetConfigurationInformation(); BOOLEAN PrimaryClaimed = FALSE; BOOLEAN SecondaryClaimed = FALSE; + BOOLEAN IgnoreIsaCompatiblePci = FALSE; + BOOLEAN IgnoreNativePci = FALSE; LARGE_INTEGER t0, t1; @@ -10298,6 +10524,8 @@ DriverEntry( if(g_opt_Verbose) { _PrintNtConsole("Universal ATA driver v 0." UNIATA_VER_STR "\n"); } + IgnoreIsaCompatiblePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", IgnoreIsaCompatiblePci) ? TRUE : FALSE; + IgnoreNativePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreNativePci", IgnoreNativePci) ? TRUE : FALSE; if(!SavedDriverObject) { SavedDriverObject = (PDRIVER_OBJECT)DriverObject; @@ -10306,6 +10534,7 @@ DriverEntry( MajorVersion=0x04; MinorVersion=0x01; BuildNumber=1; + CPU_num = KeNumberProcessors; #else // we are here for the 1st time // init CrossNT and get OS version @@ -10314,8 +10543,9 @@ DriverEntry( //HalDisplayString((PUCHAR)"DbgPrnHkInitialize: CrNtInit failed\n"); return status; } + CPU_num = *KeNumberProcessors; #endif // USE_REACTOS_DDK - KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, *KeNumberProcessors)); + KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, CPU_num)); KeQuerySystemTime(&t0); do { @@ -10339,7 +10569,8 @@ DriverEntry( if(!ReEnter) { // init ATA command translation table - UniataInitAtaCommands(); + //UniataInitAtaCommands(); + // get registry path to settings RtlCopyMemory(&SavedRegPath, RegistryPath, sizeof(UNICODE_STRING)); SavedRegPath.Buffer = (PWCHAR)&SavedRegPathBuffer; @@ -10399,8 +10630,7 @@ DriverEntry( hwInitializationData.w2k.HwAdapterControl = (PHW_ADAPTER_CONTROL)AtapiAdapterControl; } - KdPrint2((PRINT_PREFIX "\n\nATAPI IDE enum supported BusMaster Devices\n")); - + KdPrint2((PRINT_PREFIX "\n\nUniATA init... (%d)\n", ReEnter)); if(!ReEnter) { g_opt_VirtualMachine = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"VirtualMachineType", g_opt_VirtualMachine); @@ -10411,7 +10641,11 @@ DriverEntry( g_opt_VirtualMachine = VM_VBOX; } // Pre-scan PCI bus, also check if we are under VM - UniataEnumBusMasterController(DriverObject, Argument2); + // But do not perform scan if PCI bus is claimed as unused + if(!IgnoreIsaCompatiblePci || !IgnoreNativePci) { + KdPrint2((PRINT_PREFIX "\nATAPI IDE enum supported PCI BusMaster Devices\n")); + UniataEnumBusMasterController(DriverObject, Argument2); + } switch(g_opt_VirtualMachine) { case VM_VBOX: @@ -10425,16 +10659,27 @@ DriverEntry( g_opt_AtapiSendDisableIntr = FALSE; g_opt_AtapiDmaRawRead = FALSE; break; + case VM_BOCHS: + KdPrint2((PRINT_PREFIX "adjust options for Bochs\n")); + g_opt_AtapiNoDma = TRUE; } if(!hasPCI) { KdPrint2((PRINT_PREFIX "old slow machine, adjust timings\n")); - // old slow machine, adjust timings + // old slow machine, adjust timings (us) + g_opt_WaitBusyResetCount = 20000; g_opt_WaitBusyCount = 20000; g_opt_WaitBusyDelay = 150; g_opt_WaitDrqDelay = 100; g_opt_WaitBusyLongCount = 20000; g_opt_MaxIsrWait = 200; + g_opt_DriveSelectNanoDelay = 400; + } + if(g_opt_VirtualMachine > VM_NONE) { + g_opt_DriveSelectNanoDelay = 0; + } + if(CPU_num > 1) { + g_opt_AtapiSendDisableIntr = TRUE; } g_opt_WaitBusyCount = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyCount", g_opt_WaitBusyCount); // 200 vs 20000 @@ -10444,8 +10689,10 @@ DriverEntry( g_opt_WaitBusyLongDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongDelay", g_opt_WaitBusyLongDelay); // 250 vs 250 g_opt_AtapiSendDisableIntr = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiSendDisableIntr", g_opt_AtapiSendDisableIntr) ? TRUE : FALSE; // 1 vs 0 g_opt_AtapiDmaRawRead = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead", g_opt_AtapiDmaRawRead) ? TRUE : FALSE; // 1 vs 0 - g_opt_MaxIsrWait = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxIsrWait", g_opt_MaxIsrWait); // 40 vs xxx - } + g_opt_AtapiNoDma = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiNoDma", g_opt_AtapiNoDma) ? TRUE : FALSE; // 1 vs 0 + g_opt_MaxIsrWait = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxIsrWait", g_opt_MaxIsrWait); // 40 vs xxx + g_opt_DriveSelectNanoDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"DriveSelectNanoDelay", g_opt_DriveSelectNanoDelay); + } // end !re-enter // Look for legacy ISA-bridged PCI IDE controller (onboard) KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for legacy ISA-bridged PCI IDE controller (onboard)\n")); @@ -10456,7 +10703,7 @@ DriverEntry( KdPrint2((PRINT_PREFIX "!BMList[i].MasterDev\n")); break; } - if(AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", 0)) { + if(IgnoreIsaCompatiblePci) { break; } if(ReEnter) { @@ -10474,10 +10721,33 @@ DriverEntry( PrimaryClaimed = TRUE; if(GlobalConfig->AtDiskSecondaryAddressClaimed) SecondaryClaimed = TRUE; + pref_alt = 0; if(!WinVer_WDM_Model && !PrimaryClaimed && !SecondaryClaimed && !(BMList[i].ChanInitOk & 0x80)) { - newStatus = UniataClaimLegacyPCIIDE(i); + + // We just want to claim our PCI device in compatible mode, since we shall not + // tell system that we use it inside HwInitialize + // Even more, we shall cheat system, that work with ISA + // Note: this call may (but not 'must' or 'can') cause IO resource + // reallocation and switch to native mode if HAL supports this + newStatus = (ULONG)UniataClaimLegacyPCIIDE(i); + // Special check for NT3.51/NT4 (not ReactOS !!!) + if(((NTSTATUS)newStatus == STATUS_CONFLICTING_ADDRESSES) && + //(BMList[i].ChanInitOk & 0x40) && + /*CPU_num > 1 &&*/ + (WinVer_Id() <= WinVer_NT)) { + // Some NT3/4 SMP (but not only) HALs cannot reallocate IO resources of + // BusMaster PCI controller + // Since nobody claimed Primary/Secondary yet, try init and claim them + // However it is not 100% safe way, especially under ReactOS, which doesn't resolve + // conflicts yet. + // We relay on ScsiPort internal checks + KdPrint2((PRINT_PREFIX "Can't acquire PCI part of BusMaster on SMP NT3/4 system, try init anyway.\n")); + newStatus = STATUS_SUCCESS; + // Prefer alternative init method (try to change Isa -> PCI in ConfigInfo first) + pref_alt = 1; + } if(newStatus != STATUS_SUCCESS) { KdPrint2((PRINT_PREFIX "Can't acquire PCI part of BusMaster, try as pure ISA later.\n")); break; @@ -10488,11 +10758,10 @@ DriverEntry( _PrintNtConsole("Init standard Dual-channel PCI ATA controller:"); } - for(alt = 0; alt < (ULONG)(WinVer_WDM_Model ? 1 : 2) ; alt++) { for(c=0; c<2; c++) { - + // check is channel is manually excluded if(AtapiRegCheckDevValue(NULL, c, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", 0)) { break; } @@ -10536,7 +10805,7 @@ DriverEntry( newStatus = ScsiPortInitialize(DriverObject, Argument2, &hwInitializationData.comm, - (PVOID)(i | (alt ? 0x80000000 : 0))); + (PVOID)(i | ((alt ^ pref_alt) ? 0x80000000 : 0))); KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus)); if (newStatus < statusToReturn) { statusToReturn = newStatus; @@ -10601,7 +10870,7 @@ DriverEntry( KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: i %d, BMListLen %d\n", i, BMListLen)); for (; i ahci.ahci_base64 = NULL; return FALSE; } - KdPrint2((PRINT_PREFIX " get Phys(data[n=%d]=%x)\n", i, data )); + KdPrint2((PRINT_PREFIX " get Phys(data[n=%d+%x]=%x)\n", i, dma_count0, data )); dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu); if(dma_baseu && dma_count) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: block of buffer above 4Gb: %8.8x%8.8x, cnt=%x\n", dma_baseu, dma_base, dma_count)); @@ -601,6 +604,7 @@ AtapiDmaStart( KdPrint2((PRINT_PREFIX "AtapiDmaStart: *** !AtaReq->ata.dma_base\n")); return; } + KdPrint2((PRINT_PREFIX "AtapiDmaStart: lchan=%d\n", lChannel)); /* // GetStatus(chan, statusByte2); @@ -827,14 +831,15 @@ limit_pio: if(/*!(LunExt->DeviceFlags & DFLAGS_FORCE_DOWNRATE) &&*/ (LunExt->LimitedTransferMode > LunExt->TransferMode) || - (LunExt->DeviceFlags & DFLAGS_REINIT_DMA)) { + (LunExt->DeviceFlags & DFLAGS_REINIT_DMA) || + ((deviceExtension->HwFlags & UNIATA_CHAN_TIMINGS) && ((ULONG)LunExt->Lun != LunExt->chan->last_cdev))) { // restore IO mode KdPrint2((PRINT_PREFIX - "AtapiDmaReinit: restore IO mode on Device %d\n", LunExt->Lun)); + "AtapiDmaReinit: restore IO mode on Device %d, last dev %d\n", LunExt->Lun, LunExt->chan->last_cdev)); AtapiDmaInit__(deviceExtension, LunExt); } else { KdPrint2((PRINT_PREFIX - "AtapiDmaReinit: LimitedTransferMode == TransferMode = %x (%x)\n", LunExt->TransferMode, LunExt->DeviceFlags)); + "AtapiDmaReinit: LimitedTransferMode == TransferMode = %x (%x), Device %d, last dev %d\n", LunExt->TransferMode, LunExt->DeviceFlags, LunExt->Lun, LunExt->chan->last_cdev)); } exit: @@ -890,17 +895,32 @@ AtaSetTransferMode( "AtaSetTransferMode: Set %#x on Device %d/%d\n", mode, lChannel, DeviceNumber)); LONG statusByte = 0; CHAR apiomode; - + BOOLEAN disable_intr = (deviceExtension->HwFlags & UNIATA_AHCI) || (CPU_num>1); +/* + if(deviceExtension->HwFlags & UNIATA_SATA) { + // experimental do nothing, see ROS BUG-9119, v0.46a1 + statusByte = IDE_STATUS_IDLE; + } else */ if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) { statusByte = mode <= ATA_PIO2 ? IDE_STATUS_IDLE : IDE_STATUS_ERROR; } else { - if(deviceExtension->HwFlags & UNIATA_AHCI) { + UCHAR umode; + if(disable_intr) { AtapiDisableInterrupts(deviceExtension, lChannel); } + if(mode > ATA_UDMA6) { + // for SATA, it doesn't have option to set transfer rate + // We need this just to switch between PIO and DMA modes + // Devices may support only some lower transfer rates (e.g. UDMA0-4) + umode = min((UCHAR)AtaUmode(&(LunExt->IdentifyData)), 6); + umode += ATA_UDMA0; + } else { + umode = (UCHAR)mode; + } statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_SET_FEATURES, 0, 0, 0, - (UCHAR)((mode > ATA_UDMA6) ? ATA_UDMA6 : mode), ATA_C_F_SETXFER, ATA_WAIT_BASE_READY); - if(deviceExtension->HwFlags & UNIATA_AHCI) { + (UCHAR)umode, ATA_C_F_SETXFER, ATA_WAIT_BASE_READY); + if(disable_intr) { AtapiEnableInterrupts(deviceExtension, lChannel); } } @@ -1048,6 +1068,7 @@ AtapiDmaInit( } //} + chan->last_cdev = DeviceNumber; if(UniataIsSATARangeAvailable(deviceExtension, lChannel) || (ChipFlags & UNIATA_AHCI) || (chan->MaxTransferMode >= ATA_SA150) ) { @@ -1225,33 +1246,48 @@ set_new_acard: /********************/ /* AMD, nVidia, VIA */ /********************/ - if((VendorID == ATA_VIA_ID) && - (ChipFlags & VIASATA) && - (Channel == 0)) { - AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_SA150); - return; + if(VendorID == ATA_VIA_ID) { + if((ChipFlags & VIASATA) && + (Channel == 0)) { + AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_SA150); + return; + } + if((ChipFlags & VIABAR) && + (Channel < 2)) { + AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_SA150); + return; + } } - static const UCHAR via_modes[5][7] = { + static const UCHAR via_modes[6][7] = { { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* ATA33 and New Chips */ { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* ATA66 */ { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* ATA100 */ { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */ - { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }}; /* AMD/nVIDIA */ + { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }, /* AMD/nVIDIA */ + { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 }}; /* VIA new */ static const UCHAR via_pio[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; const UCHAR *reg_val = NULL; UCHAR reg = 0x53-(UCHAR)dev; + UCHAR reg2 = reg-0x08; + + if(ChipFlags & VIABAR) { + reg = 0xb3; + reg2 = 0xab; + } reg_val = &via_modes[ChipType][0]; - if(VendorID == ATA_NVIDIA_ID) + if(VendorID == ATA_NVIDIA_ID) { reg += 0x10; + reg2 += 0x10; + } for(i = udmamode; i>=0; i--) { - SetPciConfig1(reg-0x08, via_pio[8+i]); if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) { + SetPciConfig1(reg2, via_pio[8+i]); SetPciConfig1(reg, (UCHAR)reg_val[i]); return; } @@ -1259,19 +1295,20 @@ set_new_acard: if(!(ChipFlags & VIABAR)) { /* This chip can't do WDMA. */ for(i = wdmamode; i>=0; i--) { - SetPciConfig1(reg-0x08, via_pio[5+i]); if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { + SetPciConfig1(reg2, via_pio[5+i]); SetPciConfig1(reg, 0x8b); return; } } } /* set PIO mode timings */ - AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); if((apiomode >= 0) && (ChipType != VIA133)) { - SetPciConfig1(reg-0x08, via_pio[apiomode]); + SetPciConfig1(reg2, via_pio[apiomode]); + } + if(VendorID == ATA_VIA_ID /*&& (ChipType == VIA33 || ChipType == VIA66)*/) { + via82c_timing(deviceExtension, dev, ATA_PIO0 + apiomode); } - via82c_timing(deviceExtension, dev, ATA_PIO0 + apiomode); AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); return; @@ -1494,27 +1531,50 @@ dma_cs55xx: UCHAR intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 }; UCHAR intel_utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 }; + const UCHAR needed_pio[3] = { + ATA_PIO0, ATA_PIO3, ATA_PIO4 + }; if(deviceExtension->DevID == ATA_I82371FB) { KdPrint2((PRINT_PREFIX " I82371FB\n")); - if (wdmamode >= 2 && apiomode >= 4) { - ULONG word40; - - GetPciConfig4(0x40, word40); - word40 >>= Channel * 16; - - /* Check for timing config usable for DMA on controller */ - if (!((word40 & 0x3300) == 0x2300 && - ((word40 >> ((!(DeviceNumber & 1)) ? 0 : 4)) & 1) == 1)) { - udmamode = wdmamode = -1; + USHORT reg4x; + USHORT control; + for(i=wdmamode; i>=0; i--) { + idx = 5+i; + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) { + udma_ok = TRUE; break; } - - if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { - return; + } + if(!udma_ok) { + AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode); + idx = apiomode; + } else { + /* If the drive MWDMA is faster than it can do PIO then + we must force PIO into PIO0 */ + if (apiomode < needed_pio[wdmamode]) { + /* Enable DMA timing only */ + control |= 8; /* PIO cycles in PIO0 */ } } - break; + GetPciConfig2(0x40+Channel*2, reg4x); + if(apiomode > ATA_PIO0) { + control = 0x03; /* IORDY|TIME0 */ + } else { + control = 0x02; /* IORDY */ + } + // if (ata_pio_need_iordy(adev)) + //control |= 2; /* IE */ + if (!isAtapi) { + control |= 4; /* PPE enable */ + } + /* Mask out the relevant control and timing bits we will load. Also + clear the other drive TIME register as a precaution */ + reg4x &= 0xCC00 | (0x0E << (DeviceNumber*4)); + reg4x |= control << (DeviceNumber*4); + reg4x |= intel_timings[idx] << 8; + SetPciConfig2(0x40+Channel*2, reg4x); + return; } if(deviceExtension->DevID == ATA_ISCH) { @@ -1557,7 +1617,7 @@ dma_cs55xx: tim |= (apiomode & 0x7); SetPciConfig4(0x80 + dev*4, tim); - break; + return; } GetPciConfig2(0x48, reg48); @@ -2594,6 +2654,12 @@ via82c_timing( ULONG slotNumber = deviceExtension->slotNumber; ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; + // Newer chips dislike this: + if(/*!(deviceExtension->HwFlags & VIAAST)*/ + deviceExtension->MaxTransferMode < ATA_UDMA6) { + return; + } + USHORT T = 1000 / /* PciBusClockMHz()*/ 33; USHORT setup = 0; @@ -2623,14 +2689,10 @@ via82c_timing( recover = cycle - active; } - // Newer chips dislike this: - if(/*!(deviceExtension->HwFlags & VIAAST)*/ - deviceExtension->MaxTransferMode < ATA_UDMA6) { - /* PIO address setup */ - GetPciConfig1(0x4c, t); - t = (t & ~(3 << ((3 - dev) << 1))) | (FIT(setup - 1, 0, 3) << ((3 - dev) << 1)); - SetPciConfig1(0x4c, t); - } + /* PIO address setup */ + GetPciConfig1(0x4c, t); + t = (t & ~(3 << ((3 - dev) << 1))) | (FIT(setup - 1, 0, 3) << ((3 - dev) << 1)); + SetPciConfig1(0x4c, t); /* PIO active & recover */ SetPciConfig1(0x4b-dev, (FIT(active - 1, 0, 0xf) << 4) | FIT(recover - 1, 0, 0xf) ); diff --git a/reactos/drivers/storage/ide/uniata/id_init.cpp b/reactos/drivers/storage/ide/uniata/id_init.cpp index 5c86c156eac..56f3e6f7ede 100644 --- a/reactos/drivers/storage/ide/uniata/id_init.cpp +++ b/reactos/drivers/storage/ide/uniata/id_init.cpp @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004-2012 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2004-2016 Alexandr A. Telyatnikov (Alter) Module Name: id_init.cpp @@ -38,12 +38,16 @@ Revision History: VIA, nVidia added support for non-standard layout of registers added SATA support + added AHCI support + +Licence: + GPLv2 --*/ #include "stdafx.h" -static BUSMASTER_CONTROLLER_INFORMATION const AtiSouthAdapters[] = { +static BUSMASTER_CONTROLLER_INFORMATION_BASE const AtiSouthAdapters[] = { PCI_DEV_HW_SPEC_BM( 4385, 1002, 0x00, ATA_MODE_NOT_SPEC, "ATI South", 0 ), PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR, NULL , BMLIST_TERMINATOR ) }; @@ -165,7 +169,7 @@ UniataChipDetectChannels( case ATA_ATI_IXP700: { UCHAR satacfg = 0; PCI_SLOT_NUMBER slotData; - ULONG i, slotNumber; + ULONG j, slotNumber; KdPrint2((PRINT_PREFIX " IXP700\n")); /* @@ -173,8 +177,8 @@ UniataChipDetectChannels( * emulated with two SATA ports and appears on this device. * This mode can only be detected via SMB controller. */ - i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION*)&AtiSouthAdapters[0], -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, &slotData); - if(i != BMLIST_TERMINATOR) { + j = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION_BASE*)&AtiSouthAdapters[0], -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, &slotData); + if(j != BMLIST_TERMINATOR) { slotNumber = slotData.u.AsULONG; GetPciConfig1(0xad, satacfg); @@ -340,7 +344,7 @@ UniataChipDetect( ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff; ULONG RevID = deviceExtension->RevID; ULONG i, c; - BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo; + BUSMASTER_CONTROLLER_INFORMATION_BASE* DevTypeInfo; PHW_CHANNEL chan; ULONG ChipType; ULONG ChipFlags; @@ -356,7 +360,7 @@ UniataChipDetect( KdPrint2((PRINT_PREFIX "UniataChipDetect:\n" )); KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags)); - i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[0], VendorID, 0xffff, 0, NUM_BUSMASTER_ADAPTERS); + i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION_BASE)&BusMasterAdapters[0], VendorID, 0xffff, 0, NUM_BUSMASTER_ADAPTERS); c = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", 0); if(c) { @@ -374,7 +378,7 @@ UniataChipDetect( KdPrint2((PRINT_PREFIX "i: %#x\n", i)); if(i != BMLIST_TERMINATOR) { - DevTypeInfo = (PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[i]; + DevTypeInfo = (PBUSMASTER_CONTROLLER_INFORMATION_BASE)&BusMasterAdapters[i]; } else { unknown_dev: if(Ata_is_ahci_dev(pciData)) { @@ -400,7 +404,7 @@ unknown_dev: return STATUS_SUCCESS; } - static BUSMASTER_CONTROLLER_INFORMATION const SiSAdapters[] = { + static BUSMASTER_CONTROLLER_INFORMATION_BASE const SiSAdapters[] = { PCI_DEV_HW_SPEC_BM( 1183, 1039, 0x00, ATA_SA150, "SiS 1183 IDE" , SIS133NEW), PCI_DEV_HW_SPEC_BM( 1182, 1039, 0x00, ATA_SA150, "SiS 1182" , SISSATA | UNIATA_SATA), PCI_DEV_HW_SPEC_BM( 0183, 1039, 0x00, ATA_SA150, "SiS 183 RAID" , SISSATA | UNIATA_SATA), @@ -441,7 +445,7 @@ unknown_dev: PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR , NULL , BMLIST_TERMINATOR ) }; - static BUSMASTER_CONTROLLER_INFORMATION const ViaAdapters[] = { + static BUSMASTER_CONTROLLER_INFORMATION_BASE const ViaAdapters[] = { PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x41, ATA_UDMA2, "VIA 82C586B", VIA33 | 0x00 ), PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x40, ATA_UDMA2, "VIA 82C586B", VIA33 | VIAPRQ ), PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x02, ATA_UDMA2, "VIA 82C586B", VIA33 | 0x00 ), @@ -463,14 +467,14 @@ unknown_dev: PCI_DEV_HW_SPEC_BM( 5372, 1106, 0x00, ATA_UDMA6, "VIA 8237" , VIA133 | 0x00 ), PCI_DEV_HW_SPEC_BM( 7372, 1106, 0x00, ATA_UDMA6, "VIA 8237" , VIA133 | 0x00 ), PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6, "VIA 8251" , VIA133 | 0x00 ), - PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150, "VIA CX700" , VIA133 | VIASATA), - PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150, "VIA VX800" , VIA133 | VIASATA), + PCI_DEV_HW_SPEC_BM( 8324, 1106, 0x00, ATA_SA150, "VIA CX700" , VIANEW | VIASATA), + PCI_DEV_HW_SPEC_BM( 8353, 1106, 0x00, ATA_SA150, "VIA VX800" , VIANEW | VIASATA), PCI_DEV_HW_SPEC_BM( 8409, 1106, 0x00, ATA_UDMA6, "VIA VX855" , VIA133 | 0x00 ), - PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300, "VIA VX900" , VIA133 | VIASATA), + PCI_DEV_HW_SPEC_BM( 8410, 1106, 0x00, ATA_SA300, "VIA VX900" , VIANEW | VIASATA), PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR , NULL , BMLIST_TERMINATOR ) }; - static BUSMASTER_CONTROLLER_INFORMATION const ViaSouthAdapters[] = { + static BUSMASTER_CONTROLLER_INFORMATION_BASE const ViaSouthAdapters[] = { PCI_DEV_HW_SPEC_BM( 3112, 1106, 0x00, ATA_MODE_NOT_SPEC, "VIA 8361", VIASOUTH ), PCI_DEV_HW_SPEC_BM( 0305, 1106, 0x00, ATA_MODE_NOT_SPEC, "VIA 8363", VIASOUTH ), PCI_DEV_HW_SPEC_BM( 0391, 1106, 0x00, ATA_MODE_NOT_SPEC, "VIA 8371", VIASOUTH ), @@ -488,7 +492,7 @@ unknown_dev: Then perform bus scan to find SIS bridge and decide what to do with controller */ KdPrint2((PRINT_PREFIX "ATA_SIS_ID\n")); - DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&SiSAdapters[0]; + DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION_BASE*)&SiSAdapters[0]; i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL); if(i != BMLIST_TERMINATOR) { deviceExtension->FullDevName = SiSAdapters[i].FullDevName; @@ -509,7 +513,7 @@ unknown_dev: KdPrint2((PRINT_PREFIX "Via-old-style %x\n", deviceExtension->DevID)); // Traditionally, chips have same DeviceId, we can distinguish between them // only by ISA Bridge DeviceId - DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaSouthAdapters[0]; + DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION_BASE*)&ViaSouthAdapters[0]; i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED/*slotNumber*/, NULL); /* if(i == BMLIST_TERMINATOR) { @@ -519,7 +523,7 @@ unknown_dev: KdPrint2((PRINT_PREFIX "VIASOUTH\n")); deviceExtension->HwFlags |= VIASOUTH; } - DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaAdapters[0]; + DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION_BASE*)&ViaAdapters[0]; i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED/*slotNumber*/, NULL); if(i != BMLIST_TERMINATOR) { @@ -960,7 +964,7 @@ for_ugly_chips: // Restore device ID ChangePciConfig1(0x57, (a | 0x80)); } else { - static BUSMASTER_CONTROLLER_INFORMATION const SiSSouthAdapters[] = { + static BUSMASTER_CONTROLLER_INFORMATION_BASE const SiSSouthAdapters[] = { PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x10, ATA_MODE_NOT_SPEC, "SiS 961", 0 ), // PCI_DEV_HW_SPEC_BM( 0008, 1039, 0x00, ATA_MODE_NOT_SPEC, "SiS 961", 0 ), PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, ATA_MODE_NOT_SPEC, NULL , -1 ) @@ -970,7 +974,7 @@ for_ugly_chips: ChangePciConfig1(0x4a, (a | 0x10)); if(tmp32 == ATA_SIS5513 || tmp32 == ATA_SIS5517) { - i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION*)&SiSSouthAdapters[0], + i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION_BASE*)&SiSSouthAdapters[0], -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL); if(i != BMLIST_TERMINATOR) { deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD; @@ -1038,7 +1042,7 @@ for_ugly_chips: if(ChipFlags & UNIATA_SATA) { ULONG IoSize = 0; - ULONG BaseMemAddress = 0; + BaseMemAddress = 0; switch(DeviceID) { case 0x3149: // VIA 6420 @@ -1870,13 +1874,13 @@ AtapiChipInit( ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff; ULONG RevID = deviceExtension->RevID; // ULONG i; -// BUSMASTER_CONTROLLER_INFORMATION* DevTypeInfo; +// BUSMASTER_CONTROLLER_INFORMATION_BASE* DevTypeInfo; ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK; PHW_CHANNEL chan; UCHAR tmp8; USHORT tmp16; - //ULONG tmp32; + ULONG tmp32; ULONG c; // logical channel (for Compatible Mode controllers) BOOLEAN CheckCable = FALSE; BOOLEAN GlobalInit = FALSE; @@ -2045,7 +2049,6 @@ AtapiChipInit( case ATA_INTEL_ID: { BOOLEAN IsPata; USHORT reg54; - UCHAR tmp8; if(ChipFlags & UNIATA_SATA) { KdPrint2((PRINT_PREFIX "Intel SATA\n")); @@ -2195,13 +2198,29 @@ AtapiChipInit( AtapiStallExecution(10); KdPrint2((PRINT_PREFIX "BaseIoAddressSATA_0=%x\n", deviceExtension->BaseIoAddressSATA_0.Addr)); if(ChipFlags & NVQ) { + KdPrint2((PRINT_PREFIX "Disable NCQ\n")); + tmp32 = AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400); + KdPrint2((PRINT_PREFIX "MODE=%#x\n", tmp32)); + if(tmp32 & ~0xfffffff9) { + AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400, + tmp32 & 0xfffffff9); + } + ChipFlags &= ~NVQ; + deviceExtension->HwFlags = ChipFlags; + } + if(ChipFlags & NVQ) { + /* disable ECO 398 */ + ChangePciConfig1(0x7f, (a & ~(1 << 7))); + + KdPrint2((PRINT_PREFIX "Enable NCQ\n")); + /* enable NCQ support */ + AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400, + tmp32 | ~0x00000006); + /* clear interrupt status */ AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0x00ff00ff); /* enable device and PHY state change interrupts */ AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 0x000d000d); - /* disable NCQ support */ - AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400, - AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),0x0400) & 0xfffffff9); } else { /* clear interrupt status */ AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, 0xff); @@ -2465,7 +2484,6 @@ AtapiChipInit( // do nothing for SATA } else if(ChipType == SIS133NEW) { - USHORT tmp16; // check 80-pin cable if(c == CHAN_NOT_SPECIFIED) { // do nothing @@ -2755,6 +2773,7 @@ AtapiSetupLunPtrs( } chan->AltRegMap = deviceExtension->AltRegMap; chan->NextDpcChan = -1; + chan->last_devsel = -1; for(i=0; iNumberLuns; i++) { chan->lun[i]->DeviceExtension = deviceExtension; chan->lun[i]->chan = chan; diff --git a/reactos/drivers/storage/ide/uniata/id_probe.cpp b/reactos/drivers/storage/ide/uniata/id_probe.cpp index 5a7994edf34..517bd29f480 100644 --- a/reactos/drivers/storage/ide/uniata/id_probe.cpp +++ b/reactos/drivers/storage/ide/uniata/id_probe.cpp @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter) Module Name: id_probe.cpp @@ -43,6 +43,9 @@ Revision History: Fixes for Native/Compatible modes of onboard IDE controller by Vitaliy Vorobyov, deathsoft@yandex.ru (c) 2004 +Licence: + GPLv2 + --*/ #include "stdafx.h" @@ -285,6 +288,8 @@ UniataCheckPCISubclass( return TRUE; } // end UniataCheckPCISubclass() +static CONST ULONG StdIsaPorts[] = {IO_WD1, IO_WD1 + ATA_ALTOFFSET, IO_WD2, IO_WD2 + ATA_ALTOFFSET, 0, 0}; + /* Device initializaton callback Builds PCI device list using Hal routines (not ScsiPort wrappers) @@ -305,6 +310,7 @@ UniataEnumBusMasterController__( ULONG funcNumber; BOOLEAN no_buses = FALSE; BOOLEAN no_ranges = FALSE; + BOOLEAN non_isa = TRUE; ULONG busDataRead; // BOOLEAN SimplexOnly; @@ -330,6 +336,7 @@ UniataEnumBusMasterController__( BOOLEAN found; BOOLEAN known; BOOLEAN NeedPciAltInit; + BOOLEAN NonZeroSubId = 0; UCHAR IrqForCompat = 10; @@ -337,22 +344,26 @@ UniataEnumBusMasterController__( deviceStrPtr = deviceString; slotData.u.AsULONG = 0; + KdPrint2((PRINT_PREFIX "UniataEnumBusMasterController__: maxPciBus=%d\n", maxPciBus)); if(!maxPciBus) { return(SP_RETURN_NOT_FOUND); } /*HwDeviceExtension =*/ deviceExtension = (PHW_DEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_DEVICE_EXTENSION)); if(!deviceExtension) { + KdPrint2((PRINT_PREFIX "!deviceExtension\n")); return(SP_RETURN_NOT_FOUND); } RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); PciDevMap = (PCHAR)ExAllocatePool(NonPagedPool, maxPciBus*PCI_MAX_DEVICES); if(!PciDevMap) { + KdPrint2((PRINT_PREFIX "!PciDevMap\n")); goto exit; } RtlZeroMemory(PciDevMap, maxPciBus*PCI_MAX_DEVICES); for(pass=0; pass<3; pass++) { + KdPrint2((PRINT_PREFIX " pass %d\n", pass)); no_buses = FALSE; for(busNumber=0 ;busNumber0 && !NonZeroSubId && + VendorID == 0x8086 && + (DeviceID == 0x7010 || + DeviceID == 0x1230)) { + KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - Bochs PIIX emulation\n",busNumber,slotNumber,funcNumber)); + if(g_opt_VirtualMachine == VM_AUTO) { + g_opt_VirtualMachine = VM_BOCHS; + }*/ } if(BaseClass != PCI_DEV_CLASS_STORAGE) { @@ -474,7 +500,7 @@ UniataEnumBusMasterController__( } //known = UniataChipDetect(HwDeviceExtension, NULL, -1, ConfigInfo, &SimplexOnly); - i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[0], VendorID, DeviceID, 0, NUM_BUSMASTER_ADAPTERS); + i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION_BASE)&BusMasterAdapters[0], VendorID, DeviceID, 0, NUM_BUSMASTER_ADAPTERS); known = (i != BMLIST_TERMINATOR); if(known) { @@ -520,17 +546,26 @@ UniataEnumBusMasterController__( } // validate Mem/Io ranges no_ranges = TRUE; + non_isa = TRUE; for(i=0; iNeedAltInit = NeedPciAltInit; newBMListPtr->Known = known; + if(!non_isa) { + KdPrint2((PRINT_PREFIX "* ISA ranges on PCI, special case !\n")); + // Do not fail init after unseccessfull call of UniataClaimLegacyPCIIDE() + // some SMP HALs fails to reallocate IO range + newBMListPtr->ChanInitOk |= 0x40; + } + KdPrint2((PRINT_PREFIX "Add to BMList, AltInit %d\n", NeedPciAltInit)); } else { KdPrint2((PRINT_PREFIX "count: BMListLen++\n")); @@ -735,8 +778,8 @@ ScsiPortGetBusDataByOffset( ULONG NTAPI AtapiFindListedDev( - PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters, - ULONG lim, + IN PBUSMASTER_CONTROLLER_INFORMATION_BASE BusMasterAdapters, + IN ULONG lim, IN PVOID HwDeviceExtension, IN ULONG BusNumber, IN ULONG SlotNumber, @@ -1255,12 +1298,12 @@ UniataFindBusMasterController( // validate Mem/Io ranges //no_ranges = TRUE; { - ULONG i; - for(i=0; iCount = 1; resourceList->List[0].InterfaceType = PCIBus; resourceList->List[0].BusNumber = BMList[i].busNumber; @@ -1946,7 +1993,8 @@ del_do: if (!NT_SUCCESS(status)) { KdPrint2((PRINT_PREFIX "HalAssignSlotResources failed %#x\n", status)); - ExFreePool(resourceList); + // this is always deallocated inside HalAssignSlotResources() implementation + //ExFreePool(resourceList); goto del_do; } @@ -1983,7 +2031,7 @@ UniataConnectIntr2( ULONG i = deviceExtension->DevIndex; NTSTATUS status; PISR2_DEVICE_EXTENSION Isr2DevExt; - WCHAR devname_str[32]; + WCHAR devname_str[33]; UNICODE_STRING devname; KdPrint2((PRINT_PREFIX "Init ISR:\n")); @@ -2015,8 +2063,9 @@ UniataConnectIntr2( KdPrint2((PRINT_PREFIX "Create DO\n")); devname.Length = - _snwprintf(devname_str, sizeof(devname_str)/sizeof(WCHAR), + _snwprintf(devname_str, sizeof(devname_str)/sizeof(WCHAR)-1, L"\\Device\\uniata%d_2ch", i); + devname_str[devname.Length] = 0; devname.Length *= sizeof(WCHAR); devname.MaximumLength = devname.Length; devname.Buffer = devname_str; @@ -2114,6 +2163,25 @@ UniataDisconnectIntr2( #endif //UNIATA_CORE +BOOLEAN +NTAPI +AtapiCheckIOInterference( + IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, + ULONG portBase) { + // check if Primary/Secondary Master IDE claimed + if((portBase == IO_WD1) && + (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) { + KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskPrimaryClaimed\n")); + return TRUE; + } else + if((portBase == IO_WD2) && + (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) { + KdPrint2((PRINT_PREFIX "AtapiCheckIOInterference: AtdiskSecondaryClaimed\n")); + return TRUE; + } + return FALSE; +} // end AtapiCheckIOInterference() + /*++ Routine Description: @@ -2137,7 +2205,7 @@ Return Value: --*/ ULONG NTAPI -AtapiFindController( +AtapiFindIsaController( IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, @@ -2152,10 +2220,10 @@ AtapiFindController( PUCHAR ioSpace = NULL; ULONG i; ULONG irq=0; - ULONG portBase; + ULONG portBase=0; ULONG retryCount; // BOOLEAN atapiOnly; - UCHAR statusByte; + UCHAR statusByte, statusByte2; BOOLEAN preConfig = FALSE; // PIDE_REGISTERS_1 BaseIoAddress1; @@ -2170,7 +2238,7 @@ AtapiFindController( // port addresses in the previous table. static CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0}; - KdPrint2((PRINT_PREFIX "AtapiFindController:\n")); + KdPrint2((PRINT_PREFIX "AtapiFindIsaController (ISA):\n")); if (!deviceExtension) { return SP_RETURN_ERROR; @@ -2217,23 +2285,40 @@ AtapiFindController( } #endif //UNIATA_CORE - - - // Scan though the adapter address looking for adapters. - if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) { - ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, - ConfigInfo->AdapterInterfaceType, - ConfigInfo->SystemIoBusNumber, - (*ConfigInfo->AccessRanges)[0].RangeStart, - (*ConfigInfo->AccessRanges)[0].RangeLength, - (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory)); +/* + for(i=0; i<2; i++) { + if((*ConfigInfo->AccessRanges)[i].RangeStart) { + KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n", + i, + ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart), + (*ConfigInfo->AccessRanges)[i].RangeLength, + (*ConfigInfo->AccessRanges)[i].RangeInMemory + )); + } + } +*/ +// if((*ConfigInfo->AccessRanges)[0].RangeStart) { + portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart); +// } + if(portBase) { + if(!AtapiCheckIOInterference(ConfigInfo, portBase)) { + ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, + ConfigInfo->AdapterInterfaceType, + ConfigInfo->SystemIoBusNumber, + (*ConfigInfo->AccessRanges)[0].RangeStart, + (*ConfigInfo->AccessRanges)[0].RangeLength, + (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory)); + } else { + // do not touch resources, just fail later inside loop on next call to + // AtapiCheckIOInterference() + } *Again = FALSE; // Since we have pre-configured information we only need to go through this loop once preConfig = TRUE; - portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart); - KdPrint2((PRINT_PREFIX " preconfig, portBase=%x\n", portBase)); + KdPrint2((PRINT_PREFIX " preconfig, portBase=%x, len=%x\n", portBase, (*ConfigInfo->AccessRanges)[0].RangeLength)); } + // Scan through the adapter address looking for adapters. #ifndef UNIATA_CORE while (AdapterAddresses[*adapterCount] != 0) { #else @@ -2241,10 +2326,8 @@ AtapiFindController( #endif //UNIATA_CORE retryCount = 4; - deviceExtension->DevIndex = (*adapterCount); - - portBase = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", portBase); - irq = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", irq); + deviceExtension->DevIndex = (*adapterCount); // this is used inside AtapiRegCheckDevValue() + KdPrint2((PRINT_PREFIX "AtapiFindIsaController: adapterCount=%d\n", *adapterCount)); for (i = 0; i < deviceExtension->NumberLuns; i++) { // Zero device fields to ensure that if earlier devices were found, @@ -2257,50 +2340,51 @@ AtapiFindController( // if not, we go and find ourselves if (preConfig == FALSE) { - if (portBase) { - ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, - ConfigInfo->AdapterInterfaceType, - ConfigInfo->SystemIoBusNumber, - ScsiPortConvertUlongToPhysicalAddress(portBase), - 8, - TRUE); + if (!portBase) { + portBase = AdapterAddresses[*adapterCount]; + KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase)); } else { - ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, - ConfigInfo->AdapterInterfaceType, - ConfigInfo->SystemIoBusNumber, - ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]), - 8, - TRUE); + KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase)); } + portBase = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", portBase); + irq = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", irq); + // check if Primary/Secondary Master IDE claimed + if(AtapiCheckIOInterference(ConfigInfo, portBase)) { + goto next_adapter; + } + ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, + ConfigInfo->AdapterInterfaceType, + ConfigInfo->SystemIoBusNumber, + ScsiPortConvertUlongToPhysicalAddress(portBase), + ATA_IOSIZE, + TRUE); - } + } else { + KdPrint2((PRINT_PREFIX "preconfig portBase=%x\n", portBase)); + // Check if Primary/Secondary Master IDE claimed + // We can also get here from preConfig branc with conflicting portBase + // (and thus, w/o ioSpace allocated) + if(AtapiCheckIOInterference(ConfigInfo, portBase)) { + goto not_found; + } + } BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace; - +next_adapter: // Update the adapter count. (*adapterCount)++; // Check if ioSpace accessible. if (!ioSpace) { - KdPrint2((PRINT_PREFIX "AtapiFindController: !ioSpace\n")); + KdPrint2((PRINT_PREFIX "AtapiFindIsaController: !ioSpace\n")); + portBase = 0; continue; } - // check if Primary/Secondary Master IDE claimed - if((ioSpace == (PUCHAR)IO_WD1) && - (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) { - KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskPrimaryClaimed\n")); - goto not_found; - } else - if((ioSpace == (PUCHAR)IO_WD2) && - (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) { - KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskSecondaryClaimed\n")); - goto not_found; - } // Get the system physical address for the second IO range. if (BaseIoAddress1) { if(preConfig && !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) { - KdPrint2((PRINT_PREFIX "AtapiFindController: PCMCIA ?\n")); + KdPrint2((PRINT_PREFIX "AtapiFindIsaController: PCMCIA ?\n")); ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, @@ -2334,9 +2418,9 @@ AtapiFindController( SelectDrive(chan, 0); statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status); - - if(statusByte != AtapiReadPort1(chan, IDX_IO2_AltStatus)) { - KdPrint2((PRINT_PREFIX "AtapiFindController: Status vs AlsStatus missmatch, abort init ?\n")); + statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus); + if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) { + KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte, statusByte2)); if(BaseIoAddress2) { ScsiPortFreeDeviceBase(HwDeviceExtension, @@ -2344,6 +2428,7 @@ AtapiFindController( BaseIoAddress2 = NULL; } BaseIoAddress2 = (PIDE_REGISTERS_2)((ULONGIO_PTR)BaseIoAddress1 + 0x0E); + KdPrint2((PRINT_PREFIX " try BaseIoAddress2=%x\n", BaseIoAddress2)); ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, ConfigInfo->AdapterInterfaceType, ConfigInfo->SystemIoBusNumber, @@ -2356,8 +2441,10 @@ AtapiFindController( goto not_found; } UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); - if(statusByte != AtapiReadPort1(chan, IDX_IO2_AltStatus)) { - KdPrint2((PRINT_PREFIX " abort\n")); + statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status); + statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus); + if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) { + KdPrint2((PRINT_PREFIX " abort: Status %x vs AltStatus %x missmatch\n", statusByte, statusByte2)); goto not_found; } } @@ -2375,7 +2462,7 @@ retryIdentifier: if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA || statusByte == IDE_STATUS_WRONG) { - KdPrint2((PRINT_PREFIX "AtapiFindController: Identifier read back from Master (%#x)\n", + KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Identifier read back from Master (%#x)\n", statusByte)); statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus); @@ -2390,7 +2477,7 @@ retryIdentifier: AtapiStallExecution(1000); statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Status); KdPrint2((PRINT_PREFIX - "AtapiFindController: First access to status %#x\n", + "AtapiFindIsaController: First access to status %#x\n", statusByte)); } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10); @@ -2410,21 +2497,9 @@ retryIdentifier: statusByte == IDE_STATUS_WRONG) { KdPrint2((PRINT_PREFIX - "AtapiFindController: Identifier read back from Slave (%#x)\n", + "AtapiFindIsaController: Identifier read back from Slave (%#x)\n", statusByte)); -not_found: - // No controller at this base address. - if(BaseIoAddress1) { - ScsiPortFreeDeviceBase(HwDeviceExtension, - (PCHAR)BaseIoAddress1); - BaseIoAddress1 = NULL; - } - if(BaseIoAddress2) { - ScsiPortFreeDeviceBase(HwDeviceExtension, - (PCHAR)BaseIoAddress2); - BaseIoAddress2 = NULL; - } - continue; + goto not_found; } } @@ -2441,13 +2516,25 @@ not_found: ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]); } - (*ConfigInfo->AccessRanges)[0].RangeLength = 8; + (*ConfigInfo->AccessRanges)[0].RangeLength = ATA_IOSIZE; (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE; if(BaseIoAddress2) { - (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG)BaseIoAddress2); - (*ConfigInfo->AccessRanges)[1].RangeLength = 2; - (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE; + if(hasPCI) { + (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG)BaseIoAddress2); + (*ConfigInfo->AccessRanges)[1].RangeLength = ATA_ALTIOSIZE; + (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE; + } else { + // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load + // when this range is claimed by other driver. + // However, floppy should use only 0x3f0-3f5,3f7 + if((ULONG)BaseIoAddress2 >= 0x3f0 && (ULONG)BaseIoAddress2 <= 0x3f7) { + KdPrint2((PRINT_PREFIX "!!! Possible AltStatus vs Floppy IO range interference !!!\n")); + } + KdPrint2((PRINT_PREFIX "Do not expose to OS on old ISA\n")); + (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); + (*ConfigInfo->AccessRanges)[1].RangeLength = 0; + } } // Indicate the interrupt level corresponding to this IO range. @@ -2489,7 +2576,7 @@ not_found: AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0); KdPrint2((PRINT_PREFIX - "AtapiFindController: Found IDE at %#x\n", + "AtapiFindIsaController: Found IDE at %#x\n", BaseIoAddress1)); // For Daytona, the atdisk driver gets the first shot at the @@ -2505,12 +2592,12 @@ not_found: #ifndef UNIATA_CORE if (AtapiParseArgumentString(ArgumentString, "dump") == 1) { KdPrint2((PRINT_PREFIX - "AtapiFindController: Crash dump\n")); + "AtapiFindIsaController: Crash dump\n")); //atapiOnly = FALSE; deviceExtension->DriverMustPoll = TRUE; } else { KdPrint2((PRINT_PREFIX - "AtapiFindController: Atapi Only\n")); + "AtapiFindIsaController: Atapi Only\n")); //atapiOnly = TRUE; deviceExtension->DriverMustPoll = FALSE; } @@ -2518,7 +2605,7 @@ not_found: } else { KdPrint2((PRINT_PREFIX - "AtapiFindController: Atapi Only (2)\n")); + "AtapiFindIsaController: Atapi Only (2)\n")); //atapiOnly = TRUE; deviceExtension->DriverMustPoll = FALSE; } @@ -2540,14 +2627,14 @@ not_found: deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector; KdPrint2((PRINT_PREFIX - "AtapiFindController: look for devices\n")); + "AtapiFindIsaController: look for devices\n")); // Search for devices on this controller. if (FindDevices(HwDeviceExtension, 0, 0 /* Channel */)) { KdPrint2((PRINT_PREFIX - "AtapiFindController: detected\n")); + "AtapiFindIsaController: detected\n")); // Claim primary or secondary ATA IO range. if (portBase) { switch (portBase) { @@ -2581,8 +2668,28 @@ not_found: ConfigInfo->NumberOfBuses++; // add virtual channel for communication port KdPrint2((PRINT_PREFIX - "AtapiFindController: return SP_RETURN_FOUND\n")); + "AtapiFindIsaController: return SP_RETURN_FOUND\n")); return(SP_RETURN_FOUND); + } else { +not_found: + // No controller at this base address. + if(BaseIoAddress1) { + ScsiPortFreeDeviceBase(HwDeviceExtension, + (PCHAR)BaseIoAddress1); + BaseIoAddress1 = NULL; + } + if(BaseIoAddress2) { + ScsiPortFreeDeviceBase(HwDeviceExtension, + (PCHAR)BaseIoAddress2); + BaseIoAddress2 = NULL; + } + for(i=0; i<2; i++) { + KdPrint2((PRINT_PREFIX + "AtapiFindIsaController: cleanup AccessRanges %d\n", i)); + (*ConfigInfo->AccessRanges)[i].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); + (*ConfigInfo->AccessRanges)[i].RangeLength = 0; + (*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE; + } } #ifndef UNIATA_CORE } @@ -2597,7 +2704,7 @@ not_found: *(adapterCount) = 0; KdPrint2((PRINT_PREFIX - "AtapiFindController: return SP_RETURN_NOT_FOUND\n")); + "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n")); UniataFreeLunExt(deviceExtension); return(SP_RETURN_NOT_FOUND); @@ -2605,7 +2712,7 @@ exit_error: UniataFreeLunExt(deviceExtension); return SP_RETURN_ERROR; -} // end AtapiFindController() +} // end AtapiFindIsaController() ULONG NTAPI @@ -2676,7 +2783,7 @@ legacy_select: KdPrint2((PRINT_PREFIX " AHCI HDD at home\n")); return ATA_AT_HOME_HDD; } - if(g_opt_VirtualMachine /*== VM_BOCHS || + if(g_opt_VirtualMachine > VM_NONE /*== VM_BOCHS || g_opt_VirtualMachine == VM_VBOX*/) { GetStatus(chan, signatureLow); if(!signatureLow) { @@ -2744,7 +2851,7 @@ CheckDevice( signatureHigh; UCHAR statusByte; ULONG RetVal=0; - ULONG waitCount = 10000; + ULONG waitCount = g_opt_WaitBusyResetCount; ULONG at_home = 0; KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n", @@ -2807,9 +2914,13 @@ CheckDevice( KdPrint2((PRINT_PREFIX "CheckDevice: BUSY\n")); + AtapiHardReset(chan, FALSE, 500 * 1000); +/* AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER ); + chan->last_devsel = -1; AtapiStallExecution(500 * 1000); AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); +*/ SelectDrive(chan, deviceNumber & 0x01); do { @@ -2970,7 +3081,7 @@ forget_device: LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT; LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE; } else - if(!g_opt_VirtualMachine) { + if(g_opt_VirtualMachine <= VM_NONE) { // This can be ATAPI on broken hardware GetBaseStatus(chan, statusByte); if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { @@ -2995,7 +3106,7 @@ forget_device: Routine Description: - This routine is called from AtapiFindController to identify + This routine is called from AtapiFindXxxController to identify devices attached to an IDE controller. Arguments: @@ -3072,49 +3183,35 @@ FindDevices( // garbage geometry in the IDENTIFY data. // This is ONLY for the crashdump environment as // these are ESDI devices. - if (LunExt->IdentifyData.SectorsPerTrack == - 0x35 && - LunExt->IdentifyData.NumberOfHeads == - 0x07) { + if (LunExt->IdentifyData.SectorsPerTrack == 0x35 && + LunExt->IdentifyData.NumberOfHeads == 0x07) { - KdPrint2((PRINT_PREFIX - "FindDevices: Found nasty Compaq ESDI!\n")); + KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n")); // Change these values to something reasonable. - LunExt->IdentifyData.SectorsPerTrack = - 0x34; - LunExt->IdentifyData.NumberOfHeads = - 0x0E; + LunExt->IdentifyData.SectorsPerTrack = 0x34; + LunExt->IdentifyData.NumberOfHeads = 0x0E; } - if (LunExt->IdentifyData.SectorsPerTrack == - 0x35 && - LunExt->IdentifyData.NumberOfHeads == - 0x0F) { + if (LunExt->IdentifyData.SectorsPerTrack == 0x35 && + LunExt->IdentifyData.NumberOfHeads == 0x0F) { - KdPrint2((PRINT_PREFIX - "FindDevices: Found nasty Compaq ESDI!\n")); + KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n")); // Change these values to something reasonable. - LunExt->IdentifyData.SectorsPerTrack = - 0x34; - LunExt->IdentifyData.NumberOfHeads = - 0x0F; + LunExt->IdentifyData.SectorsPerTrack = 0x34; + LunExt->IdentifyData.NumberOfHeads = 0x0F; } - if (LunExt->IdentifyData.SectorsPerTrack == - 0x36 && - LunExt->IdentifyData.NumberOfHeads == - 0x07) { + if (LunExt->IdentifyData.SectorsPerTrack == 0x36 && + LunExt->IdentifyData.NumberOfHeads == 0x07) { KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n")); // Change these values to something reasonable. - LunExt->IdentifyData.SectorsPerTrack = - 0x3F; - LunExt->IdentifyData.NumberOfHeads = - 0x10; + LunExt->IdentifyData.SectorsPerTrack = 0x3F; + LunExt->IdentifyData.NumberOfHeads = 0x10; skipSetParameters = TRUE; } @@ -3134,9 +3231,13 @@ FindDevices( KdPrint2((PRINT_PREFIX "FindDevices: Resetting controller before SetDriveParameters.\n")); + AtapiHardReset(chan, FALSE, 500 * 1000); +/* AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER ); + chan->last_devsel = -1; AtapiStallExecution(500 * 1000); AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER); +*/ SelectDrive(chan, i & 0x01); do { diff --git a/reactos/drivers/storage/ide/uniata/id_queue.cpp b/reactos/drivers/storage/ide/uniata/id_queue.cpp index c275f6cb44b..bdafe2fd8e6 100644 --- a/reactos/drivers/storage/ide/uniata/id_queue.cpp +++ b/reactos/drivers/storage/ide/uniata/id_queue.cpp @@ -29,6 +29,9 @@ Notes: Revision History: +Licence: + GPLv2 + --*/ #include "stdafx.h" @@ -228,6 +231,7 @@ UniataQueueRequest( AtaReq->next_req = NULL; LunExt->first_req = LunExt->last_req = AtaReq; + chan->cur_cdev = GET_CDEV(Srb); } LunExt->queue_depth++; chan->queue_depth++; diff --git a/reactos/drivers/storage/ide/uniata/id_sata.cpp b/reactos/drivers/storage/ide/uniata/id_sata.cpp index d01ffe11e16..5306fbe92f8 100644 --- a/reactos/drivers/storage/ide/uniata/id_sata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_sata.cpp @@ -1,12 +1,12 @@ /*++ -Copyright (c) 2008-2014 Alexandr A. Telyatnikov (Alter) +Copyright (c) 2008-2016 Alexandr A. Telyatnikov (Alter) Module Name: id_probe.cpp Abstract: - This module handles SATA-related staff + This module handles SATA- and AHCI-related staff Author: Alexander A. Telyatnikov (Alter) @@ -29,6 +29,12 @@ Notes: Revision History: + SATA support + AHCI support + +Licence: + GPLv2 + --*/ #include "stdafx.h" @@ -631,7 +637,7 @@ UniataDumpAhciPortRegs( } return; } // end UniataDumpAhciPortRegs() -#endif //DBG +#endif //_DEBUG BOOLEAN @@ -656,7 +662,7 @@ UniataAhciInit( #ifdef _DEBUG UniataDumpAhciRegs(deviceExtension); -#endif //DBG +#endif //_DEBUG CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2); if(CAP2 & AHCI_CAP2_BOH) { @@ -894,7 +900,7 @@ UniataAhciDetect( #ifdef _DEBUG ULONG BOHC; ULONG v_Mn, v_Mj; -#endif //DBG +#endif //_DEBUG ULONG NumberChannels; ULONG BaseMemAddress; BOOLEAN MemIo = FALSE; @@ -921,7 +927,7 @@ UniataAhciDetect( #ifdef _DEBUG UniataDumpAhciRegs(deviceExtension); -#endif //DBG +#endif //_DEBUG GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC); if(GHC & AHCI_GHC_HR) { @@ -966,7 +972,7 @@ UniataAhciDetect( BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC); KdPrint2((PRINT_PREFIX " BOHC %#x", BOHC)); } -#endif //DBG +#endif //_DEBUG if(CAP & AHCI_CAP_NCQ) { KdPrint2((PRINT_PREFIX " NCQ")); } @@ -1039,7 +1045,7 @@ UniataAhciDetect( v_Mj, v_Mn, NumberChannels, PI)); KdPrint((" AHCI SATA Gen %d\n", (((CAP & AHCI_CAP_ISS_MASK) >> 20)) )); -#endif //DBG +#endif //_DEBUG if(CAP & AHCI_CAP_SPM) { KdPrint2((PRINT_PREFIX " PM supported\n")); @@ -1140,7 +1146,7 @@ UniataAhciStatus( if(CI & (1 << tag)) { #ifdef _DEBUG UniataDumpAhciPortRegs(chan); -#endif //DBG +#endif //_DEBUG //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts if(IS.Reg & (ATA_AHCI_P_IX_OF | ATA_AHCI_P_IX_INF | ATA_AHCI_P_IX_IF | @@ -1238,8 +1244,6 @@ UniataAhciSetupFIS_H2D( if(((AtaCommandFlags[command] & (ATA_CMD_FLAG_LBAIOsupp|ATA_CMD_FLAG_FUA)) == ATA_CMD_FLAG_LBAIOsupp) && CheckIfBadBlock(chan->lun[DeviceNumber], lba, count)) { KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count)); - //return IDE_STATUS_ERROR; - //return SRB_STATUS_ERROR; return 0; } @@ -1279,22 +1283,15 @@ UniataAhciSetupFIS_H2D( chan->ChannelCtrlFlags |= CTRFLAGS_LBA48; } else { -//#ifdef _MSC_VER -//#pragma warning(push) -//#pragma warning(disable:4333) // right shift by too large amount, data loss -//#endif fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f); chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48; -//#ifdef _MSC_VER -//#pragma warning(pop) -//#endif } //fis[14] = 0x00; } - KdDump(fis, 20); + //KdDump(fis, 20); return 20; } // end UniataAhciSetupFIS_H2D() @@ -1446,7 +1443,7 @@ UniataAhciWaitCommandReady( TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD); KdPrint2((" TFD %#x\n", TFD)); -#endif //DBG +#endif //_DEBUG return IDE_STATUS_WRONG; } @@ -1534,7 +1531,7 @@ UniataAhciSendPIOCommand( #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG if(!Srb) { Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length); @@ -1592,13 +1589,13 @@ UniataAhciSendPIOCommand( #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb); #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG if(wait_flags == ATA_IMMEDIATE) { statusByte = 0; @@ -1647,7 +1644,7 @@ UniataAhciSendPIOCommandDirect( #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG if(!Srb) { KdPrint((" !Srb\n")); @@ -1702,13 +1699,13 @@ UniataAhciSendPIOCommandDirect( #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb); #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG if(wait_flags == ATA_IMMEDIATE) { statusByte = 0; @@ -1865,7 +1862,7 @@ UniataAhciHardReset( #ifdef _DEBUG UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG (*signature) = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG); KdPrint((" sig: %#x\n", *signature)); @@ -2181,7 +2178,7 @@ UniataAhciBeginTransaction( #ifdef _DEBUG KdPrint2((" prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags, AHCI_CL->cmd_table_phys)); -#endif // DBG +#endif // _DEBUG CMD0 = CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); KdPrint2((" CMD %#x\n", CMD)); @@ -2352,7 +2349,7 @@ UniataAhciResume( #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG /* Disable port interrupts */ UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE, 0); @@ -2392,14 +2389,14 @@ UniataAhciResume( #ifdef _DEBUG //UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG UniataAhciStartFR(chan); UniataAhciStart(chan); #ifdef _DEBUG UniataDumpAhciPortRegs(chan); -#endif // DBG +#endif // _DEBUG return; } // end UniataAhciResume() @@ -2577,7 +2574,7 @@ IN OUT PATA_REQ AtaReq }; #ifdef _DEBUG ULONG d; -#endif // DBG +#endif // _DEBUG prd_base64_0 = prd_base64 = 0; prd_base = (PUCHAR)(&AtaReq->ahci_cmd0); @@ -2588,7 +2585,7 @@ IN OUT PATA_REQ AtaReq #ifdef _DEBUG d = (ULONG)(prd_base64 - prd_base64_0); KdPrint2((PRINT_PREFIX " AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d)); -#endif // DBG +#endif // _DEBUG AtaReq->ahci.ahci_cmd_ptr = (PIDE_AHCI_CMD)prd_base64; KdPrint2((PRINT_PREFIX " ahci_cmd_ptr %#x\n", AtaReq->ahci.ahci_cmd_ptr)); diff --git a/reactos/drivers/storage/ide/uniata/id_sata.h b/reactos/drivers/storage/ide/uniata/id_sata.h index e6452706047..692d6bdf6a4 100644 --- a/reactos/drivers/storage/ide/uniata/id_sata.h +++ b/reactos/drivers/storage/ide/uniata/id_sata.h @@ -29,6 +29,9 @@ Notes: Revision History: +Licence: + GPLv2 + --*/ #ifndef __UNIATA_SATA__H__ diff --git a/reactos/drivers/storage/ide/uniata/stdafx.cpp b/reactos/drivers/storage/ide/uniata/stdafx.cpp new file mode 100644 index 00000000000..fd4f341c7b2 --- /dev/null +++ b/reactos/drivers/storage/ide/uniata/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/reactos/drivers/storage/ide/uniata/tools.h b/reactos/drivers/storage/ide/uniata/tools.h index bbcef20607f..251ef023e2a 100644 --- a/reactos/drivers/storage/ide/uniata/tools.h +++ b/reactos/drivers/storage/ide/uniata/tools.h @@ -29,6 +29,9 @@ Notes: Revision History: +Licence: + GPLv2 + --*/ #ifndef __TOOLS_H__ diff --git a/reactos/drivers/storage/ide/uniata/uata_ctl.h b/reactos/drivers/storage/ide/uniata/uata_ctl.h index c3e671edcbe..d5ae233620c 100644 --- a/reactos/drivers/storage/ide/uniata/uata_ctl.h +++ b/reactos/drivers/storage/ide/uniata/uata_ctl.h @@ -29,6 +29,9 @@ Notes: Revision History: +Licence: + GPLv2 + --*/ #ifndef __UNIATA_IO_CONTROL_CODES__H__ diff --git a/reactos/drivers/storage/ide/uniata/uniata_ver.h b/reactos/drivers/storage/ide/uniata/uniata_ver.h index 8b43eab3242..d4008195c57 100644 --- a/reactos/drivers/storage/ide/uniata/uniata_ver.h +++ b/reactos/drivers/storage/ide/uniata/uniata_ver.h @@ -1,10 +1,10 @@ -#define UNIATA_VER_STR "45j1" -#define UNIATA_VER_DOT 0.45.10.1 +#define UNIATA_VER_STR "46d7" +#define UNIATA_VER_DOT 0.46.4.7 #define UNIATA_VER_MJ 0 -#define UNIATA_VER_MN 45 -#define UNIATA_VER_SUB_MJ 10 -#define UNIATA_VER_SUB_MN 1 -#define UNIATA_VER_DOT_COMMA 0,45,10,1 -#define UNIATA_VER_DOT_STR "0.45.10.1" -#define UNIATA_VER_YEAR 2015 -#define UNIATA_VER_YEAR_STR "2015" +#define UNIATA_VER_MN 46 +#define UNIATA_VER_SUB_MJ 4 +#define UNIATA_VER_SUB_MN 7 +#define UNIATA_VER_DOT_COMMA 0,46,4,7 +#define UNIATA_VER_DOT_STR "0.46.4.7" +#define UNIATA_VER_YEAR 2016 +#define UNIATA_VER_YEAR_STR "2016"