- Copy uniata source code to the drivers/storage/ide directory.

svn path=/trunk/; revision=29256
This commit is contained in:
Aleksey Bragin 2007-09-27 18:37:22 +00:00
parent 8f33e033e4
commit 1daf74908e
31 changed files with 25426 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
/*++
Copyright (C) 2006 VorontSOFT
Module Name:
badblock.h
Abstract:
This is the artificial badblock simulation part of the
miniport driver for ATA/ATAPI IDE controllers
with Busmaster DMA support
Author:
Nikolai Vorontsov (NickViz)
Environment:
kernel mode only
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:
2006/08/03 Initial implementation.
2006/08/06 Added registry work.
--*/
#ifndef _BADBLOCK_H_INCLUDED_
#define _BADBLOCK_H_INCLUDED_
#pragma pack(push, 4)
typedef struct _SBadBlockRange
{
// ULONG m_ldev;
ULONGLONG m_lbaStart;
ULONGLONG m_lbaEnd;
} SBadBlockRange, *PSBadBlockRange;
typedef struct _SBadBlockListItem {
LIST_ENTRY List;
PHW_LU_EXTENSION LunExt;
WCHAR SerNumStr[128];
SBadBlockRange* arrBadBlocks;
ULONG nBadBlocks;
} SBadBlockListItem, *PSBadBlockListItem;
#pragma pack(pop)
void
InitBadBlocks(
IN PHW_LU_EXTENSION LunExt
);
void
ForgetBadBlocks(
IN PHW_LU_EXTENSION LunExt
);
bool
CheckIfBadBlock(
IN PHW_LU_EXTENSION LunExt,
// IN UCHAR command,
IN ULONGLONG lba,
IN ULONG count
);
#endif // _BADBLOCK_H_INCLUDED_

View file

@ -0,0 +1,737 @@
/*++
Copyright (c) 2002-2005 Alexandr A. Telyatnikov (Alter)
Module Name:
bm_devs.h
Abstract:
This file contains list of 'well known' PCI IDE controllers
Author:
Alexander A. Telyatnikov (Alter)
Environment:
kernel mode only
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:
--*/
#define IDE_MAX_CHAN 8
// Thanks to SATA Port Multipliers:
#define IDE_MAX_LUN_PER_CHAN 16
#define IDE_MAX_LUN (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN)
#define MAX_QUEUE_STAT 8
//
// values for TransferMode
//
#define ATA_PIO 0x00
#define ATA_PIO_NRDY 0x01
#define ATA_PIO0 0x08
#define ATA_PIO1 0x09
#define ATA_PIO2 0x0a
#define ATA_PIO3 0x0b
#define ATA_PIO4 0x0c
#define ATA_PIO5 0x0d
#define ATA_DMA 0x10
#define ATA_SDMA 0x10
#define ATA_SDMA0 0x10
#define ATA_SDMA1 0x11
#define ATA_SDMA2 0x12
#define ATA_WDMA 0x20
#define ATA_WDMA0 0x20
#define ATA_WDMA1 0x21
#define ATA_WDMA2 0x22
#define ATA_UDMA 0x40
#define ATA_UDMA0 0x40 // ATA-16
#define ATA_UDMA1 0x41 // ATA-25
#define ATA_UDMA2 0x42 // ATA-33
#define ATA_UDMA3 0x43 // ATA-44
#define ATA_UDMA4 0x44 // ATA-66
#define ATA_UDMA5 0x45 // ATA-100
#define ATA_UDMA6 0x46 // ATA-133
//#define ATA_UDMA7 0x47 // ATA-166
#define ATA_SA150 0x47 /*0x80*/
#define ATA_SA300 0x48 /*0x81*/
// define PIO timings in nanoseconds
#define PIO0_TIMING 600
#define UniataGetPioTiming(LunExt) ((LunExt->TransferMode <= ATA_PIO0) ? PIO0_TIMING : 0)
#ifndef __IDE_BUSMASTER_DEVICES_H__
#define __IDE_BUSMASTER_DEVICES_H__
typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
PCHAR VendorId;
ULONG VendorIdLength;
ULONG nVendorId;
PCHAR DeviceId;
ULONG DeviceIdLength;
ULONG nDeviceId;
ULONG nRevId;
ULONG MaxTransferMode;
PCHAR FullDevName;
ULONG RaidFlags;
CHAR VendorIdStr[4];
CHAR DeviceIdStr[4];
ULONG slotNumber;
ULONG busNumber;
CHAR channel;
// CHAR numOfChannes;
CHAR MasterDev;
#ifndef USER_MODE
CHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary
BOOLEAN Isr2Enable;
PDEVICE_OBJECT Isr2DevObj;
KIRQL Isr2Irql;
KAFFINITY Isr2Affinity;
ULONG Isr2Vector;
PKINTERRUPT Isr2InterruptObject;
CHAR AltInitMasterDev; // 0xff - uninitialized, 0x00 - normal, 0x01 - 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_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_ACER_LABS_ID 0x10b9
#define ATA_ALI_1533 0x153310b9
#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_ATI_ID 0x1002
#define ATA_ATI_IXP200 0x43491002
#define ATA_ATI_IXP300 0x43691002
#define ATA_ATI_IXP400 0x43761002
#define ATA_ATI_IXP300_S1 0x436e1002
#define ATA_ATI_IXP400_S1 0x43791002
#define ATA_ATI_IXP400_S2 0x437a1002
#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_1 0x24d18086
#define ATA_I82801EB_2 0x24df8086
#define ATA_I6300ESB 0x25a28086
#define ATA_I6300ESB_1 0x25a38086
#define ATA_I6300ESB_2 0x25b08086
#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_R1 0x27c38086
#define ATA_I82801GB_AH 0x27c18086
#define ATA_I82801GB_M 0x27c58086
#define ATA_NATIONAL_ID 0x100b
#define ATA_SC1100 0x0502100b
#define ATA_NVIDIA_ID 0x10de
#define ATA_NFORCE1 0x01bc10de
#define ATA_NFORCE2 0x006510de
#define ATA_NFORCE2_MCP 0x008510de
#define ATA_NFORCE3 0x00d510de
#define ATA_NFORCE3_PRO 0x00e510de
#define ATA_NFORCE3_PRO_S1 0x00e310de
#define ATA_NFORCE3_PRO_S2 0x00ee10de
#define ATA_NFORCE3_MCP 0x003510de
#define ATA_NFORCE3_MCP_S1 0x003610de
#define ATA_NFORCE3_MCP_S2 0x003e10de
#define ATA_NFORCE4 0x005310de
#define ATA_NFORCE4_S1 0x005410de
#define ATA_NFORCE4_S2 0x005510de
#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_PDC20617 0x6617105a
#define ATA_PDC20618 0x6626105a
#define ATA_PDC20619 0x6629105a
#define ATA_PDC20620 0x6620105a
#define ATA_PDC20621 0x6621105a
#define ATA_PDC20622 0x6622105a
#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_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_SIS964_1 0x01801039
#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_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_ITE_ID 0x1283
#define ATA_IT8172G 0x81721283
#define ATA_IT8212F 0x82121283
#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 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 PRIDX 4
#define PRTX4 0x0100
#define PRSX4K 0x0200
#define PRSX6K 0x0400
#define PRSATA 0x0800
#define PRDUAL 0x1000
#define SWKS33 0
#define SWKS66 1
#define SWKS100 2
#define SWKSMIO 3
#define SIIOLD 0
#define SIICMD 1
#define SIIMIO 2
#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 ICH4_FIX 0x0100
#define NV4OFF 0x0100
#define NVQ 0x0200
#define VIA33 0
#define VIA66 1
#define VIA100 2
#define VIA133 3
#define AMDNVIDIA 4
#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 ITE_33 0
#define ITE_133 1
#ifdef USER_MODE
#define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \
{ #idlo, 4, 0x##idlo, #idhi, 4, 0x##idhi, rev, mode, name, flags}
#else
#define PCI_DEV_HW_SPEC_BM(idhi, idlo, rev, mode, name, flags) \
{ #idlo, 4, 0x##idlo, #idhi, 4, 0x##idhi, rev, mode, NULL, flags}
#endif
#define BMLIST_TERMINATOR (0xffffffffL)
BUSMASTER_CONTROLLER_INFORMATION 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" , 0 ),
PCI_DEV_HW_SPEC_BM( 0007, 1191, 0x00, ATA_UDMA4, "Acard ATP860R" , 0 ),
PCI_DEV_HW_SPEC_BM( 0008, 1191, 0x00, ATA_UDMA6, "Acard ATP865A" , 0 ),
PCI_DEV_HW_SPEC_BM( 0009, 1191, 0x00, ATA_UDMA6, "Acard ATP865R" , 0 ),
PCI_DEV_HW_SPEC_BM( 5289, 10b9, 0x00, ATA_SA150, "ALI M5289" , UNIATA_SATA | UNIATA_NO_SLAVE ),
PCI_DEV_HW_SPEC_BM( 5288, 10b9, 0x00, ATA_SA300, "ALI M5288" , UNIATA_SATA | UNIATA_NO_SLAVE ),
PCI_DEV_HW_SPEC_BM( 5287, 10b9, 0x00, ATA_SA150, "ALI M5287" , UNIATA_SATA | UNIATA_NO_SLAVE ),
PCI_DEV_HW_SPEC_BM( 5281, 10b9, 0x00, ATA_SA150, "ALI M5281" , UNIATA_SATA | UNIATA_NO_SLAVE ),
PCI_DEV_HW_SPEC_BM( 5229, 10b9, 0xc5, ATA_UDMA6, "ALI M5229 UDMA6" , ALINEW ),
PCI_DEV_HW_SPEC_BM( 5229, 10b9, 0xc4, ATA_UDMA5, "ALI M5229 UDMA5" , ALINEW ),
PCI_DEV_HW_SPEC_BM( 5229, 10b9, 0xc2, ATA_UDMA4, "ALI M5229 UDMA4" , ALINEW ),
PCI_DEV_HW_SPEC_BM( 5229, 10b9, 0x20, ATA_UDMA2, "ALI M5229 UDMA2" , ALIOLD ),
PCI_DEV_HW_SPEC_BM( 5229, 10b9, 0x00, ATA_WDMA2, "ALI M5229 WDMA2" , ALIOLD ),
PCI_DEV_HW_SPEC_BM( 7409, 1022, 0x00, ATA_UDMA4, "AMD 756" , AMDNVIDIA | 0x00 ),
PCI_DEV_HW_SPEC_BM( 7411, 1022, 0x00, ATA_UDMA5, "AMD 766" , AMDNVIDIA | AMDCABLE|AMDBUG ),
PCI_DEV_HW_SPEC_BM( 7441, 1022, 0x00, ATA_UDMA5, "AMD 768" , AMDNVIDIA | AMDCABLE ),
PCI_DEV_HW_SPEC_BM( 7469, 1022, 0x00, ATA_UDMA6, "AMD 8111" , AMDNVIDIA | AMDCABLE ),
PCI_DEV_HW_SPEC_BM( 4349, 1002, 0x00, ATA_UDMA5, "ATI IXP200" , 0 ),
PCI_DEV_HW_SPEC_BM( 4369, 1002, 0x00, ATA_UDMA6, "ATI IXP300" , 0 ),
PCI_DEV_HW_SPEC_BM( 4376, 1002, 0x00, ATA_UDMA6, "ATI IXP400" , 0 ),
PCI_DEV_HW_SPEC_BM( 436e, 1002, 0x00, ATA_SA150, "ATI IXP300" , SIIMIO | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 4379, 1002, 0x00, ATA_SA150, "ATI IXP400" , SIIMIO | SIINOSATAIRQ | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 437a, 1002, 0x00, ATA_SA150, "ATI IXP400" , SIIMIO | SIINOSATAIRQ | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0004, 1103, 0x05, ATA_UDMA6, "HighPoint HPT372" , HPT372 | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0004, 1103, 0x03, ATA_UDMA5, "HighPoint HPT370" , HPT370 | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0004, 1103, 0x02, ATA_UDMA4, "HighPoint HPT368" , HPT366 | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0004, 1103, 0x00, ATA_UDMA4, "HighPoint HPT366" , HPT366 | HPTOLD | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0005, 1103, 0x01, ATA_UDMA6, "HighPoint HPT372" , HPT372 | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0005, 1103, 0x00, ATA_UDMA4, "HighPoint HPT372" , HPT372 | HPTOLD | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0006, 1103, 0x01, ATA_UDMA6, "HighPoint HPT302" , HPT372 | 0x00 | UNIATA_RAID_CONTROLLER),
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( 7010, 8086, 0x00, ATA_WDMA2, "Intel PIIX3" , 0 ),
PCI_DEV_HW_SPEC_BM( 7111, 8086, 0x00, ATA_UDMA3, "Intel PIIX4" , 0 ),
PCI_DEV_HW_SPEC_BM( 7199, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ),
PCI_DEV_HW_SPEC_BM( 84ca, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ),
PCI_DEV_HW_SPEC_BM( 7601, 8086, 0x00, ATA_UDMA2, "Intel ICH0" , 0 ),
PCI_DEV_HW_SPEC_BM( 2421, 8086, 0x00, ATA_UDMA4, "Intel ICH" , 0 ),
PCI_DEV_HW_SPEC_BM( 2411, 8086, 0x00, ATA_UDMA4, "Intel ICH" , 0 ),
PCI_DEV_HW_SPEC_BM( 244a, 8086, 0x00, ATA_UDMA5, "Intel ICH2" , 0 ),
PCI_DEV_HW_SPEC_BM( 244b, 8086, 0x00, ATA_UDMA5, "Intel ICH2" , 0 ),
PCI_DEV_HW_SPEC_BM( 248a, 8086, 0x00, ATA_UDMA5, "Intel ICH3" , 0 ),
PCI_DEV_HW_SPEC_BM( 248b, 8086, 0x00, ATA_UDMA5, "Intel ICH3" , 0 ),
PCI_DEV_HW_SPEC_BM( 24cb, 8086, 0x00, ATA_UDMA5, "Intel ICH4" , ICH4_FIX | UNIATA_NO_DPC ),
PCI_DEV_HW_SPEC_BM( 24ca, 8086, 0x00, ATA_UDMA5, "Intel ICH4" , ICH4_FIX | UNIATA_NO_DPC ),
PCI_DEV_HW_SPEC_BM( 24db, 8086, 0x00, ATA_UDMA5, "Intel ICH5 EB" , 0 ),
PCI_DEV_HW_SPEC_BM( 24d1, 8086, 0x00, ATA_SA150, "Intel ICH5 EB1" , UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 24df, 8086, 0x00, ATA_SA150, "Intel ICH5 EB2" , UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 25a2, 8086, 0x00, ATA_UDMA5, "Intel 6300ESB" , 0 ),
PCI_DEV_HW_SPEC_BM( 25a3, 8086, 0x00, ATA_SA150, "Intel 6300ESB1" , UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 25b0, 8086, 0x00, ATA_SA150, "Intel 6300ESB2" , UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 266f, 8086, 0x00, ATA_UDMA5, "Intel ICH6" , 0 ),
PCI_DEV_HW_SPEC_BM( 2651, 8086, 0x00, ATA_SA150, "Intel ICH6" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2652, 8086, 0x00, ATA_SA150, "Intel ICH6" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2653, 8086, 0x00, ATA_SA150, "Intel ICH6M" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 27df, 8086, 0x00, ATA_UDMA5, "Intel ICH7" , 0 ),
PCI_DEV_HW_SPEC_BM( 27c0, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 27c1, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 27c3, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 27c4, 8086, 0x00, ATA_SA300, "Intel ICH7M" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 27c5, 8086, 0x00, ATA_SA300, "Intel ICH7M" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 27c6, 8086, 0x00, ATA_SA300, "Intel ICH7M" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 269e, 8086, 0x00, ATA_UDMA5, "Intel 63XXESB2" , 0 ),
PCI_DEV_HW_SPEC_BM( 2680, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2681, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2682, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2683, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2820, 8086, 0x00, ATA_SA300, "Intel ICH8" , 0 ),
PCI_DEV_HW_SPEC_BM( 2821, 8086, 0x00, ATA_SA300, "Intel ICH8" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2822, 8086, 0x00, ATA_SA300, "Intel ICH8" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2824, 8086, 0x00, ATA_SA300, "Intel ICH8" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2825, 8086, 0x00, ATA_SA300, "Intel ICH8" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 2829, 8086, 0x00, ATA_SA300, "Intel ICH8M" , UNIATA_SATA | UNIATA_AHCI ),
PCI_DEV_HW_SPEC_BM( 282a, 8086, 0x00, ATA_SA300, "Intel ICH8M" , UNIATA_SATA | UNIATA_AHCI ),
// PCI_DEV_HW_SPEC_BM( 3200, 8086, 0x00, ATA_SA150, "Intel 31244" , UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 01bc, 10de, 0x00, ATA_UDMA5, "nVidia nForce" , AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 0065, 10de, 0x00, ATA_UDMA6, "nVidia nForce2" , AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 0085, 10de, 0x00, ATA_UDMA6, "nVidia nForce2 Pro",AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 008e, 10de, 0x00, ATA_SA150, "nVidia nForce2 Pro S1",UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 00d5, 10de, 0x00, ATA_UDMA6, "nVidia nForce3" , AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 00e5, 10de, 0x00, ATA_UDMA6, "nVidia nForce3 Pro",AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 00e3, 10de, 0x00, ATA_SA150, "nVidia nForce3 Pro S1",UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 00ee, 10de, 0x00, ATA_SA150, "nVidia nForce3 Pro S2",UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0035, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP", AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 0036, 10de, 0x00, ATA_SA150, "nVidia nForce MCP S1",NV4OFF | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 003e, 10de, 0x00, ATA_SA150, "nVidia nForce MCP S2",NV4OFF | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0053, 10de, 0x00, ATA_UDMA6, "nVidia nForce CK804", AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 0054, 10de, 0x00, ATA_SA300, "nVidia nForce CK804 S1",NV4OFF | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0055, 10de, 0x00, ATA_SA300, "nVidia nForce CK804 S2",NV4OFF | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0265, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP51", AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 0266, 10de, 0x00, ATA_SA300, "nVidia nForce MCP51 S1",NV4OFF | NVQ | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0267, 10de, 0x00, ATA_SA300, "nVidia nForce MCP51 S2",NV4OFF | NVQ | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 036e, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP55", AMDNVIDIA ),
PCI_DEV_HW_SPEC_BM( 037e, 10de, 0x00, ATA_SA300, "nVidia nForce MCP55 S1",NV4OFF | NVQ | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 037f, 10de, 0x00, ATA_SA300, "nVidia nForce MCP55 S2",NV4OFF | NVQ | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0502, 100b, 0x00, ATA_UDMA2, "National Geode SC1100", 0 ),
PCI_DEV_HW_SPEC_BM( 4d33, 105a, 0x00, ATA_UDMA2, "Promise PDC20246" , PROLD | 0x00 ),
PCI_DEV_HW_SPEC_BM( 4d38, 105a, 0x00, ATA_UDMA4, "Promise PDC20262" , PRNEW | 0x00 ),
PCI_DEV_HW_SPEC_BM( 0d38, 105a, 0x00, ATA_UDMA4, "Promise PDC20263" , PRNEW | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0d30, 105a, 0x00, ATA_UDMA5, "Promise PDC20265" , PRNEW | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 4d30, 105a, 0x00, ATA_UDMA5, "Promise PDC20267" , PRNEW | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 4d68, 105a, 0x00, ATA_UDMA5, "Promise PDC20268" , PRTX | PRTX4 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 4d69, 105a, 0x00, ATA_UDMA6, "Promise PDC20269" , PRTX | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6268, 105a, 0x00, ATA_UDMA5, "Promise PDC20270" , PRTX | PRTX4 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6269, 105a, 0x00, ATA_UDMA6, "Promise PDC20271" , PRTX | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 1275, 105a, 0x00, ATA_UDMA6, "Promise PDC20275" , PRTX | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 5275, 105a, 0x00, ATA_UDMA6, "Promise PDC20276" , PRTX | PRSX6K | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 7275, 105a, 0x00, ATA_UDMA6, "Promise PDC20277" , PRTX | 0x00 | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 3318, 105a, 0x00, ATA_SA150, "Promise PDC20318" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3319, 105a, 0x00, ATA_SA150, "Promise PDC20319" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3371, 105a, 0x00, ATA_SA150, "Promise PDC20371" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3375, 105a, 0x00, ATA_SA150, "Promise PDC20375" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3376, 105a, 0x00, ATA_SA150, "Promise PDC20376" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3377, 105a, 0x00, ATA_SA150, "Promise PDC20377" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3373, 105a, 0x00, ATA_SA150, "Promise PDC20378" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 3372, 105a, 0x00, ATA_SA150, "Promise PDC20379" , PRMIO | PRSATA | UNIATA_RAID_CONTROLLER | UNIATA_SATA),
PCI_DEV_HW_SPEC_BM( 6617, 105a, 0x00, ATA_UDMA6, "Promise PDC20617" , PRMIO | PRDUAL | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6626, 105a, 0x00, ATA_UDMA6, "Promise PDC20618" , PRMIO | PRDUAL | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6629, 105a, 0x00, ATA_UDMA6, "Promise PDC20619" , PRMIO | PRDUAL | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6620, 105a, 0x00, ATA_UDMA6, "Promise PDC20620" , PRMIO | PRDUAL | UNIATA_RAID_CONTROLLER),
/* PCI_DEV_HW_SPEC_BM( 6621, 105a, 0x00, ATA_UDMA6, "Promise PDC20621" , PRMIO | PRSX4X | UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6622, 105a, 0x00, ATA_UDMA6, "Promise PDC20622" , PRMIO | PRSX4X | UNIATA_RAID_CONTROLLER),*/
PCI_DEV_HW_SPEC_BM( 0211, 1166, 0x00, ATA_UDMA2, "ServerWorks ROSB4", SWKS33 | UNIATA_NO_DPC ),
PCI_DEV_HW_SPEC_BM( 0212, 1166, 0x92, ATA_UDMA5, "ServerWorks CSB5" , SWKS100 ),
PCI_DEV_HW_SPEC_BM( 0212, 1166, 0x00, ATA_UDMA4, "ServerWorks CSB5" , SWKS66 ),
PCI_DEV_HW_SPEC_BM( 0213, 1166, 0x00, ATA_UDMA5, "ServerWorks CSB6" , SWKS100 ),
PCI_DEV_HW_SPEC_BM( 0217, 1166, 0x00, ATA_UDMA4, "ServerWorks CSB6" , SWKS66 ),
PCI_DEV_HW_SPEC_BM( 0214, 1166, 0x00, ATA_UDMA5, "ServerWorks HT1000" , SWKS100 ),
PCI_DEV_HW_SPEC_BM( 024b, 1166, 0x00, ATA_SA150, "ServerWorks HT1000" , SWKS100 ),
PCI_DEV_HW_SPEC_BM( 024a, 1166, 0x00, ATA_SA150, "ServerWorks HT1000" , SWKSMIO ),
PCI_DEV_HW_SPEC_BM( 0240, 1166, 0x00, ATA_SA150, "ServerWorks K2" , SWKSMIO ),
PCI_DEV_HW_SPEC_BM( 0241, 1166, 0x00, ATA_SA150, "ServerWorks Frodo4" , SWKSMIO ),
PCI_DEV_HW_SPEC_BM( 0242, 1166, 0x00, ATA_SA150, "ServerWorks Frodo8" , SWKSMIO ),
PCI_DEV_HW_SPEC_BM( 3114, 1095, 0x00, ATA_SA150, "SiI 3114" , SIIMIO | SII4CH | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 3512, 1095, 0x02, ATA_SA150, "SiI 3512" , SIIMIO | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 3112, 1095, 0x02, ATA_SA150, "SiI 3112" , SIIMIO | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0240, 1095, 0x02, ATA_SA150, "SiI 3112" , SIIMIO | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 3512, 1095, 0x00, ATA_SA150, "SiI 3512" , SIIMIO | SIIBUG | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 3112, 1095, 0x00, ATA_SA150, "SiI 3112" , SIIMIO | SIIBUG | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0240, 1095, 0x00, ATA_SA150, "SiI 3112" , SIIMIO | SIIBUG | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0680, 1095, 0x00, ATA_UDMA6, "SiI 0680" , SIIMIO | SIISETCLK ),
PCI_DEV_HW_SPEC_BM( 0649, 1095, 0x00, ATA_UDMA5, "CMD 649" , SIICMD | SIIINTR | UNIATA_NO_DPC_ATAPI ),
PCI_DEV_HW_SPEC_BM( 0648, 1095, 0x00, ATA_UDMA4, "CMD 648" , SIICMD | SIIINTR ),
PCI_DEV_HW_SPEC_BM( 0646, 1095, 0x07, ATA_UDMA2, "CMD 646U2" , SIICMD | 0 ),
PCI_DEV_HW_SPEC_BM( 0646, 1095, 0x00, ATA_WDMA2, "CMD 646" , SIICMD | 0 ),
PCI_DEV_HW_SPEC_BM( 0640, 1095, 0x00, ATA_PIO4 , "CMD 640" , SIIOLD | SIIENINTR | UNIATA_SIMPLEX_ONLY),
/** PCI_DEV_HW_SPEC_BM( 0963, 1039, 0x00, ATA_UDMA6, "SiS 963" , SIS133NEW ),
PCI_DEV_HW_SPEC_BM( 0962, 1039, 0x00, ATA_UDMA6, "SiS 962" , SIS133NEW ),
PCI_DEV_HW_SPEC_BM( 0755, 1039, 0x00, ATA_UDMA6, "SiS 755" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0752, 1039, 0x00, ATA_UDMA6, "SiS 752" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0751, 1039, 0x00, ATA_UDMA6, "SiS 751" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0750, 1039, 0x00, ATA_UDMA6, "SiS 750" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0748, 1039, 0x00, ATA_UDMA6, "SiS 748" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0746, 1039, 0x00, ATA_UDMA6, "SiS 746" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0745, 1039, 0x00, ATA_UDMA5, "SiS 745" , SIS100NEW ),
PCI_DEV_HW_SPEC_BM( 0740, 1039, 0x00, ATA_UDMA5, "SiS 740" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0735, 1039, 0x00, ATA_UDMA5, "SiS 735" , SIS100NEW ),
PCI_DEV_HW_SPEC_BM( 0733, 1039, 0x00, ATA_UDMA5, "SiS 733" , SIS100NEW ),
PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5, "SiS 730" , SIS100OLD ),
PCI_DEV_HW_SPEC_BM( 0658, 1039, 0x00, ATA_UDMA6, "SiS 658" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0655, 1039, 0x00, ATA_UDMA6, "SiS 655" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0652, 1039, 0x00, ATA_UDMA6, "SiS 652" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0651, 1039, 0x00, ATA_UDMA6, "SiS 651" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0650, 1039, 0x00, ATA_UDMA6, "SiS 650" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0648, 1039, 0x00, ATA_UDMA6, "SiS 648" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6, "SiS 645DX" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640" , SIS_SOUTH ),
PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5, "SiS 635" , SIS100NEW ),
PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5, "SiS 633" , SIS100NEW ),
PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA5, "SiS 630S" , SIS100OLD ),
PCI_DEV_HW_SPEC_BM( 0630, 1039, 0x00, ATA_UDMA4, "SiS 630" , SIS66, ),
PCI_DEV_HW_SPEC_BM( 0620, 1039, 0x00, ATA_UDMA4, "SiS 620" , SIS66, ),
PCI_DEV_HW_SPEC_BM( 0550, 1039, 0x00, ATA_UDMA5, "SiS 550" , SIS66, ),
PCI_DEV_HW_SPEC_BM( 0540, 1039, 0x00, ATA_UDMA4, "SiS 540" , SIS66, ),
PCI_DEV_HW_SPEC_BM( 0530, 1039, 0x00, ATA_UDMA4, "SiS 530" , SIS66, ),
*/
PCI_DEV_HW_SPEC_BM( 5513, 1039, 0xc2, ATA_UDMA2, "SiS ATA-xxx" , 0 ),
PCI_DEV_HW_SPEC_BM( 5513, 1039, 0x00, ATA_WDMA2, "SiS ATA-xxx" , 0 ),
PCI_DEV_HW_SPEC_BM( 0601, 1039, 0x00, ATA_WDMA2, "SiS ATA-xxx" , 0 ),
/* 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 ),
PCI_DEV_HW_SPEC_BM( 0586, 1106, 0x00, ATA_WDMA2, "VIA 82C586" , VIA33 | 0x00 ),
PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x12, ATA_UDMA4, "VIA 82C596B" , VIA66 | VIACLK ),
PCI_DEV_HW_SPEC_BM( 0596, 1106, 0x00, ATA_UDMA2, "VIA 82C596" , VIA33 | 0x00 ),
PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x40, ATA_UDMA5, "VIA 82C686B" , VIA100 | VIABUG ),
PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x10, ATA_UDMA4, "VIA 82C686A" , VIA66 | VIACLK ),
PCI_DEV_HW_SPEC_BM( 0686, 1106, 0x00, ATA_UDMA2, "VIA 82C686" , VIA33 | 0x00 ),
PCI_DEV_HW_SPEC_BM( 8231, 1106, 0x00, ATA_UDMA5, "VIA 8231" , VIA100 | VIABUG ),
PCI_DEV_HW_SPEC_BM( 3074, 1106, 0x00, ATA_UDMA5, "VIA 8233" , VIA100 | 0x00 ),
PCI_DEV_HW_SPEC_BM( 3109, 1106, 0x00, ATA_UDMA5, "VIA 8233C" , VIA100 | 0x00 ),
PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6, "VIA 8233A" , VIA133 | VIAAST ),
PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6, "VIA 8235" , VIA133 | VIAAST ),
*/
PCI_DEV_HW_SPEC_BM( 0571, 1106, 0x00, ATA_UDMA2, "VIA ATA-xxx" , 0 ),
PCI_DEV_HW_SPEC_BM( 3164, 1106, 0x00, ATA_UDMA6, "VIA 6410" , 0 ),
PCI_DEV_HW_SPEC_BM( 3149, 1106, 0x00, ATA_SA150, "VIA 6420" , 0 | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 3249, 1106, 0x00, ATA_SA150, "VIA 6421" , VIABAR | UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_SA150, "VIA 8237A" , 0 | UNIATA_SATA ),
//PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_SA150, "VIA 8251" , VIAAHCI| UNIATA_SATA ),
PCI_DEV_HW_SPEC_BM( c693, 1080, 0x00, ATA_WDMA2, "Cypress 82C693" ,0 ),
/*
PCI_DEV_HW_SPEC_BM( 4d68, 105a, 0, 0, "Promise TX2 ATA-100 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6268, 105a, 0, 0, "Promise TX2 ATA-100 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 4d69, 105a, 0, 0, "Promise TX2 ATA-133 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 5275, 105a, 0, 0, "Promise TX2 ATA-133 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 6269, 105a, 0, 0, "Promise TX2 ATA-133 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 7275, 105a, 0, 0, "Promise TX2 ATA-133 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 4d33, 105a, 0, 0, "Promise Ultra/FastTrak-33 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0d38, 105a, 0, 0, "Promise FastTrak 66 controller", 0),
PCI_DEV_HW_SPEC_BM( 4d38, 105a, 0, 0, "Promise Ultra/FastTrak-66 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 4d30, 105a, 0, 0, "Promise Ultra/FastTrak-100 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0d30, 105a, 0, 0, "Promise OEM ATA-100 controllers", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0004, 1103, 0, 0, "HighPoint HPT366/368/370/372 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0005, 1103, 0, 0, "HighPoint HPT372 controller", UNIATA_RAID_CONTROLLER),
PCI_DEV_HW_SPEC_BM( 0008, 1103, 0, 0, "HighPoint HPT374 controller", UNIATA_RAID_CONTROLLER),
*/
PCI_DEV_HW_SPEC_BM( 0001, 16ca, 0x00, ATA_WDMA2, "Cenatek Rocket Drive",0 ),
PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530" , 0 ),
PCI_DEV_HW_SPEC_BM( 0102, 1042, 0x00, ATA_PIO4, "RZ 100x" , 0 ),
PCI_DEV_HW_SPEC_BM( 8172, 1283, 0x00, ATA_UDMA2, "IT8172" , 0 ),
PCI_DEV_HW_SPEC_BM( 8212, 1283, 0x00, ATA_UDMA6, "IT8212F" , ITE_133 ),
PCI_DEV_HW_SPEC_BM( 8013, 3388, 0x00, ATA_DMA, "HiNT VXII EIDE" , 0 ),
// Terminator
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; k<lim; k++) {
if(BusMasterAdapters[k].nVendorId == 0xffff &&
BusMasterAdapters[k].nDeviceId == 0xffff &&
BusMasterAdapters[k].nRevId == 0xff) {
if(lim != BMLIST_TERMINATOR)
continue;
return BMLIST_TERMINATOR;
}
if(BusMasterAdapters[k].nVendorId == VendorId &&
(BusMasterAdapters[k].nDeviceId == DeviceId || DeviceId == 0xffff) &&
(!RevId || BusMasterAdapters[k].nRevId <= RevId) )
return k;
}
return BMLIST_TERMINATOR;
}
#define Ata_is_supported_dev(pciData) \
((pciData)->BaseClass == PCI_DEV_CLASS_STORAGE && \
(pciData)->SubClass == PCI_DEV_SUBCLASS_IDE)
#endif //__IDE_BUSMASTER_H__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
#ifndef __UNIATA_CONFIG__H__
#define __UNIATA_CONFIG__H__
/***************************************************/
/* Options */
/***************************************************/
/***************************************/
// Send Debug messages directly to DbgPrintLonner using its SDK
/***************************************/
//#define USE_DBGPRINT_LOGGER
/***************************************/
// Send Debug messages via ScsiPort API
/***************************************/
//#define SCSI_PORT_DBG_PRINT
/***************************************/
// Using DbgPrint on raised IRQL will crash w2k
// this will not happen immediately, so we shall see some logs.
// You can tune Irql checking here
// Note: you can avoid crashes if configure DbgPrintLogger to check Irql
/***************************************/
#define LOG_ON_RAISED_IRQL_W2K TRUE
//#define LOG_ON_RAISED_IRQL_W2K FALSE
/***************************************/
// Use hack to avoid PCI-ISA DMA limitations (physical memory must
// be allocated below 16Mb). Actually there is no such limitation,
// so we have to pretent to be PIO and converl logical addresses
// to physical manually
/***************************************/
#define USE_OWN_DMA
/***************************************/
// Special option, enables dumping of ATAPI cammands and data buffers
// via DbgPrint API
/***************************************/
//#define UNIATA_DUMP_ATAPI
/***************************************/
// Optimization for uni-processor machines
/***************************************/
//#define UNI_CPU_OPTIMIZATION
/***************************************/
// Enable/disable performance statistics
/***************************************/
#define QUEUE_STATISTICS
#define IO_STATISTICS
/***************************************************/
/* Validate Options */
/***************************************************/
#ifdef _DEBUG
#ifndef DBG
#define DBG
#endif //DBG
#else //_DEBUG
#ifdef USE_DBGPRINT_LOGGER
#undef USE_DBGPRINT_LOGGER
#endif //USE_DBGPRINT_LOGGER
#endif // !_DEBUG
/***************************************************/
/* Compiler dependencies */
/***************************************************/
/* ReactOS-specific defines */
#ifdef DDKAPI
#define USE_REACTOS_DDK
#endif DDKAPI
/* Are we under GNU C (mingw) ??? */
#if __GNUC__ >=3
#define DEF_U64(x) (x##ULL)
#define DEF_I64(x) (x##LL)
/* ReactOS-specific defines */
#ifdef USE_REACTOS_DDK
#else //USE_REACTOS_DDK
#define DDKAPI __attribute__((stdcall))
#define DDKFASTAPI __attribute__((fastcall))
#define DDKCDECLAPI __attribute__((cdecl))
#endif //DDKAPI
#define DECLSPEC_NAKED __attribute__((naked))
#else // !__GNUC__ => MSVC/Intel
#define DEF_U64(x) (x##UI64)
#define DEF_I64(x) (x##I64)
/* ReactOS-specific defines */
#ifdef USE_REACTOS_DDK
#else //USE_REACTOS_DDK
#define DDKAPI __stdcall
#define DDKFASTAPI __fastcall
#define DDKCDECLAPI _cdecl
#endif //DDKAPI
#define DECLSPEC_NAKED __declspec(naked)
#endif //__GNUC__
#endif //__UNIATA_CONFIG__H__

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,266 @@
/*++
Copyright (C) 2006 VorontSOFT
Module Name:
id_badblock.cpp
Abstract:
This is the artificial badblock simulation part of the
miniport driver for ATA/ATAPI IDE controllers with Busmaster DMA support
Author:
Nikolai Vorontsov (NickViz)
Environment:
kernel mode only
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:
2006/08/03 Initial implementation.
2006/08/06 Added registry work.
2007/03/27 Added device serial to registry value name instead of LUN.
--*/
#include "stdafx.h"
//#define MAX_BADBLOCKS_ITEMS 512
//SBadBlockRange arrBadBlocks[MAX_BADBLOCKS_ITEMS];
//ULONG nBadBlocks = 0;
LIST_ENTRY BBList;
BOOLEAN BBListInited = FALSE;
// RtlQueryRegistryValues callback function
static NTSTATUS __stdcall
BadBlockQueryRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
)
{
PSBadBlockListItem cur;
PLIST_ENTRY link;
ULONG i;
// The ValueType should be REG_SZ
// The ValueData is UNICODE string of the following format:
// "badblocks_start_from_lba badblocks_end_at_lba"
KdPrint(( "BadBlockQueryRoutine: S/N:%S\n type %#x, len %#x\n", ValueName, ValueType, ValueLength));
if(!BBListInited)
return STATUS_SUCCESS;
if((ValueType == REG_BINARY) && // STRING
ValueLength && // At least "0 0 0"
!(ValueLength % sizeof(SBadBlockRange))) // There is free space for the record
{
cur = NULL;
link = BBList.Flink;
while(link != &BBList) {
cur = CONTAINING_RECORD( link, SBadBlockListItem, List);
link = link->Flink;
if(!wcscmp(cur->SerNumStr, ValueName)) {
KdPrint(( "already loaded\n"));
if(cur->LunExt) {
cur->LunExt->nBadBlocks = 0;
cur->LunExt->arrBadBlocks = NULL;
cur->LunExt->bbListDescr = NULL;
cur->LunExt = NULL;
}
break;
}
}
if(!cur) {
cur = (PSBadBlockListItem)ExAllocatePool(NonPagedPool, sizeof(SBadBlockListItem));
if(!cur)
return STATUS_SUCCESS;
} else {
if(cur->arrBadBlocks) {
ExFreePool(cur->arrBadBlocks);
cur->arrBadBlocks = NULL;
}
}
cur->arrBadBlocks = (SBadBlockRange*)ExAllocatePool(NonPagedPool, ValueLength);
if(!cur->arrBadBlocks) {
ExFreePool(cur);
return STATUS_SUCCESS;
}
RtlCopyMemory(cur->arrBadBlocks, ValueData, ValueLength);
wcsncpy(cur->SerNumStr, ValueName, 127);
cur->SerNumStr[127] = 0;
cur->nBadBlocks = ValueLength/sizeof(SBadBlockRange);
cur->LunExt = NULL;
InitializeListHead(&cur->List);
InsertTailList(&BBList, &(cur->List));
for(i=0; i<cur->nBadBlocks; i++) {
KdPrint(( "BB: %I64x - %I64x\n", cur->arrBadBlocks[i].m_lbaStart, cur->arrBadBlocks[i].m_lbaEnd-1));
}
}
return STATUS_SUCCESS;
} // end BadBlockQueryRoutine()
void
InitBadBlocks(
IN PHW_LU_EXTENSION LunExt
)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[2]; // Main record and zero filled end of array marker
WCHAR DevSerial[128];
ULONG Length;
PLIST_ENTRY link;
PSBadBlockListItem cur;
// Read from the registry necessary badblock pairs and fill in arrBadBlocks array
// HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\UniATA\Parameters\BadBlocks
if(!LunExt) {
// init
KdPrint(( "InitBadBlocks general\n"));
if(!BBListInited) {
InitializeListHead(&BBList);
BBListInited = TRUE;
}
QueryTable[0].QueryRoutine = BadBlockQueryRoutine;
QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
QueryTable[0].Name = NULL; // If Name is NULL, the QueryRoutine function
// specified for this table entry is called
// for all values associated with the current
// registry key.
QueryTable[0].EntryContext = NULL;
QueryTable[0].DefaultType = REG_NONE;
QueryTable[0].DefaultData = 0;
QueryTable[0].DefaultLength = 0;
RtlZeroMemory(QueryTable + 1, sizeof RTL_QUERY_REGISTRY_TABLE); // EOF
NTSTATUS status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
L"UniATA\\Parameters\\BadBlocks",
QueryTable, 0, 0);
KdPrint(( "InitBadBlocks returned: %#x\n", status));
} else {
KdPrint(( "InitBadBlocks local\n"));
Length = EncodeVendorStr(DevSerial, (PUCHAR)LunExt->IdentifyData.ModelNumber, sizeof(LunExt->IdentifyData.ModelNumber));
DevSerial[Length] = '-';
Length++;
Length += EncodeVendorStr(DevSerial+Length, LunExt->IdentifyData.SerialNumber, sizeof(LunExt->IdentifyData.SerialNumber));
KdPrint(( "LunExt %#x\n", LunExt));
KdPrint(( "S/N:%S\n", DevSerial));
LunExt->nBadBlocks = 0;
LunExt->arrBadBlocks = NULL;
link = BBList.Flink;
while(link != &BBList) {
cur = CONTAINING_RECORD( link, SBadBlockListItem, List);
link = link->Flink;
if(cur->LunExt == LunExt) {
KdPrint(( " deassociate BB list (by LunExt)\n"));
cur->LunExt->nBadBlocks = 0;
cur->LunExt->arrBadBlocks = NULL;
cur->LunExt->bbListDescr = NULL;
cur->LunExt = NULL;
} else
if(!wcscmp(cur->SerNumStr, DevSerial)) {
KdPrint(( " deassociate BB list (by Serial)\n"));
if(cur->LunExt) {
cur->LunExt->nBadBlocks = 0;
cur->LunExt->arrBadBlocks = NULL;
cur->LunExt->bbListDescr = NULL;
cur->LunExt = NULL;
}
}
}
if(!(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
link = BBList.Flink;
while(link != &BBList) {
cur = CONTAINING_RECORD( link, SBadBlockListItem, List);
link = link->Flink;
if(!wcscmp(cur->SerNumStr, DevSerial)) {
KdPrint(( "found BB:List\n"));
cur->LunExt = LunExt;
LunExt->arrBadBlocks = cur->arrBadBlocks;
LunExt->nBadBlocks = cur->nBadBlocks;
LunExt->bbListDescr = cur;
return;
}
}
}
}
return;
} // end InitBadBlocks()
void
ForgetBadBlocks(
IN PHW_LU_EXTENSION LunExt
)
{
if(LunExt->bbListDescr) {
LunExt->bbListDescr->LunExt = NULL;
LunExt->nBadBlocks = 0;
LunExt->arrBadBlocks = NULL;
LunExt->bbListDescr = NULL;
}
} // end ForgetBadBlocks()
bool
CheckIfBadBlock(
IN PHW_LU_EXTENSION LunExt,
// IN UCHAR command,
IN ULONGLONG lba,
IN ULONG count
)
{
if (LunExt->nBadBlocks == 0)
return false;
/*
// this is checked by caller
if(!(AtaCommandFlags[command] & ATA_CMD_FLAG_LBAsupp)) {
return false;
*/
ULONG nBadBlocks = LunExt->nBadBlocks;
SBadBlockRange* arrBadBlocks = LunExt->arrBadBlocks;
// back transform for possibly CHS'ed LBA
lba = UniAtaCalculateLBARegsBack(LunExt, lba);
for (ULONG i = 0; i < nBadBlocks; i++)
{
if (lba + count > arrBadBlocks->m_lbaStart &&
lba < arrBadBlocks->m_lbaEnd) {
KdPrint(( "listed BB @ %I64x\n", lba));
return true;
}
arrBadBlocks++;
}
return false;
} // end CheckIfBadBlock()

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,371 @@
#include "stdafx.h"
/*
Get cost of insertion Req1 before Req2
*/
LONGLONG
UniataGetCost(
PHW_LU_EXTENSION LunExt,
IN PATA_REQ AtaReq1,
IN PATA_REQ AtaReq2
)
{
BOOLEAN write1;
BOOLEAN write2;
UCHAR flags1;
UCHAR flags2;
LONGLONG cost;
// can't insert Req1 before tooooo old Req2
if(!AtaReq2->ttl)
return REORDER_COST_TTL;
// check if reorderable
flags1 = AtaReq1->Flags;
flags2 = AtaReq2->Flags;
if(!((flags2 & flags1) & REQ_FLAG_REORDERABLE_CMD))
return REORDER_COST_DENIED;
// if at least one Req is WRITE, target areas
// can not intersect
write1 = (flags1 & REQ_FLAG_RW_MASK) == REQ_FLAG_WRITE;
write2 = (flags2 & REQ_FLAG_RW_MASK) == REQ_FLAG_WRITE;
cost = AtaReq1->lba+AtaReq1->bcount - AtaReq2->lba;
if( write1 || write2 ) {
// check for intersection
if((AtaReq1->lba < AtaReq2->lba+AtaReq2->bcount) &&
(AtaReq1->lba+AtaReq1->bcount > AtaReq2->lba)) {
// Intersection...
return REORDER_COST_INTERSECT;
}
}
if(cost < 0) {
cost *= (1-LunExt->SeekBackMCost);
} else {
cost *= (LunExt->SeekBackMCost-1);
}
if( write1 == write2 ) {
return cost;
}
return (cost * LunExt->RwSwitchMCost) + LunExt->RwSwitchCost;
} // end UniataGetCost()
/*
Insert command to proper place of command queue
Perform reorder if necessary
*/
VOID
UniataQueueRequest(
IN PHW_CHANNEL chan,
IN PSCSI_REQUEST_BLOCK Srb
)
{
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
PATA_REQ AtaReq1;
PATA_REQ AtaReq2;
LONGLONG best_cost;
LONGLONG new_cost;
LONGLONG new_cost1;
LONGLONG new_cost2;
PATA_REQ BestAtaReq1;
BOOLEAN use_reorder = chan->UseReorder/*EnableReorder*/;
#ifdef QUEUE_STATISTICS
BOOLEAN reordered = FALSE;
#endif //QUEUE_STATISTICS
PHW_LU_EXTENSION LunExt = chan->lun[GET_LDEV(Srb) & 1];
AtaReq->Srb = Srb;
/*
#ifdef _DEBUG
if(!LunExt) {
PrintNtConsole("q: chan = %#x, dev %#x\n", chan, GET_LDEV(Srb));
int i;
for(i=0; i<1000; i++) {
AtapiStallExecution(5*1000);
}
return;
}
#endif //_DEBUG
*/
// check if queue is empty
if(LunExt->queue_depth) {
AtaReq->ttl = (UCHAR)(max(LunExt->queue_depth, MIN_REQ_TTL));
// init loop
BestAtaReq1 =
AtaReq2 = LunExt->last_req;
if(use_reorder &&
(Srb->SrbFlags & SRB_FLAGS_QUEUE_ACTION_ENABLE)) {
switch(Srb->QueueAction) {
case SRB_ORDERED_QUEUE_TAG_REQUEST:
use_reorder = FALSE;
#ifdef QUEUE_STATISTICS
chan->TryReorderTailCount++;
#endif //QUEUE_STATISTICS
break;
case SRB_HEAD_OF_QUEUE_TAG_REQUEST:
BestAtaReq1 = LunExt->first_req;
best_cost = -REORDER_COST_RESELECT;
#ifdef QUEUE_STATISTICS
chan->TryReorderHeadCount++;
#endif //QUEUE_STATISTICS
break;
case SRB_SIMPLE_TAG_REQUEST:
default:
best_cost = UniataGetCost(LunExt, BestAtaReq1, AtaReq);
use_reorder |= TRUE;
}
} else
if(use_reorder) {
best_cost = UniataGetCost(LunExt, BestAtaReq1, AtaReq);
}
if(use_reorder) {
#ifdef QUEUE_STATISTICS
chan->TryReorderCount++;
#endif //QUEUE_STATISTICS
// walk through command queue and find the best
// place for insertion of the command
while (AtaReq1 = AtaReq2->prev_req) {
new_cost1 = UniataGetCost(LunExt, AtaReq1, AtaReq);
new_cost2 = UniataGetCost(LunExt, AtaReq, AtaReq2);
if(new_cost1 == REORDER_COST_INTERSECT ||
new_cost2 == REORDER_COST_INTERSECT)
chan->IntersectCount++;
if(new_cost2 > REORDER_COST_RESELECT)
break;
// for now I see nothing bad in RESELECT here
//ASSERT(new_cost1 <= REORDER_COST_RESELECT);
new_cost = UniataGetCost(LunExt, AtaReq1, AtaReq2);
new_cost = new_cost1 + new_cost2 - new_cost;
// check for Stop Reordering
if(new_cost > REORDER_COST_RESELECT*3)
break;
if(new_cost < best_cost) {
best_cost = new_cost;
BestAtaReq1 = AtaReq1;
#ifdef QUEUE_STATISTICS
reordered = TRUE;
#endif //QUEUE_STATISTICS
}
AtaReq2 = AtaReq1;
}
#ifdef QUEUE_STATISTICS
if(reordered)
chan->ReorderCount++;
#endif //QUEUE_STATISTICS
}
// Insert Req between Req2 & Req1
AtaReq2 = BestAtaReq1->next_req;
if(AtaReq2) {
AtaReq2->prev_req = AtaReq;
AtaReq->next_req = AtaReq2;
} else {
AtaReq->next_req = NULL;
LunExt->last_req = AtaReq;
}
// LunExt->last_req->next_req = AtaReq;
BestAtaReq1->next_req = AtaReq;
// AtaReq->prev_req = LunExt->last_req;
AtaReq->prev_req = BestAtaReq1;
AtaReq1 = AtaReq;
while(AtaReq1 = AtaReq1->next_req) {
//ASSERT(AtaReq1->ttl);
AtaReq1->ttl--;
}
} else {
// empty queue
AtaReq->ttl = 0;
AtaReq->prev_req =
AtaReq->next_req = NULL;
LunExt->first_req =
LunExt->last_req = AtaReq;
}
LunExt->queue_depth++;
chan->queue_depth++;
chan->DeviceExtension->queue_depth++;
// check if this is the 1st request in queue
if(chan->queue_depth == 1) {
chan->cur_req = LunExt->first_req;
}
#ifdef QUEUE_STATISTICS
//ASSERT(LunExt->queue_depth);
chan->QueueStat[min(MAX_QUEUE_STAT, LunExt->queue_depth)-1]++;
#endif //QUEUE_STATISTICS
/*
ASSERT(chan->queue_depth ==
(chan->lun[0]->queue_depth + chan->lun[1]->queue_depth));
ASSERT(!chan->queue_depth || chan->cur_req);
*/
return;
} // end UniataQueueRequest()
/*
Remove request from queue and get next request
*/
VOID
UniataRemoveRequest(
IN PHW_CHANNEL chan,
IN PSCSI_REQUEST_BLOCK Srb
)
{
if(!Srb)
return;
if(!chan)
return;
PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
//PHW_DEVICE_EXTENSION deviceExtension = chan->DeviceExtension;
ULONG cdev = GET_LDEV(Srb) & 1;
PHW_LU_EXTENSION LunExt = chan->lun[cdev];
if(!LunExt)
return;
/*
ASSERT(chan->queue_depth ==
(chan->lun[0]->queue_depth + chan->lun[1]->queue_depth));
ASSERT(!chan->queue_depth || chan->cur_req);
*/
// check if queue for the device is empty
if(!LunExt->queue_depth)
return;
// check if request is under processing (busy)
if(!AtaReq->ReqState)
return;
// remove reqest from queue
if(AtaReq->prev_req) {
AtaReq->prev_req->next_req =
AtaReq->next_req;
} else {
LunExt->first_req = AtaReq->next_req;
}
if(AtaReq->next_req) {
AtaReq->next_req->prev_req =
AtaReq->prev_req;
} else {
LunExt->last_req = AtaReq->prev_req;
}
LunExt->queue_depth--;
chan->queue_depth--;
chan->DeviceExtension->queue_depth--;
// set LastWrite flag for Lun
LunExt->last_write = ((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_WRITE);
// get request from longest queue to balance load
if(chan->lun[0]->queue_depth * (chan->lun[0]->LunSelectWaitCount+1) >
chan->lun[1]->queue_depth * (chan->lun[1]->LunSelectWaitCount+1)) {
cdev = 0;
} else {
cdev = 1;
}
/* // prevent too long wait for actively used device
if(chan->lun[cdev ^ 1]->queue_depth &&
chan->lun[cdev ^ 1]->LunSelectWaitCount >= chan->lun[cdev]->queue_depth) {
cdev = cdev ^ 1;
}*/
// get next request for processing
chan->cur_req = chan->lun[cdev]->first_req;
chan->cur_cdev = cdev;
if(!chan->lun[cdev ^ 1]->queue_depth) {
chan->lun[cdev ^ 1]->LunSelectWaitCount=0;
} else {
chan->lun[cdev ^ 1]->LunSelectWaitCount++;
}
chan->lun[cdev]->LunSelectWaitCount=0;
// chan->first_req->prev_req = NULL;
AtaReq->ReqState = REQ_STATE_NONE;
/*
ASSERT(chan->queue_depth ==
(chan->lun[0]->queue_depth + chan->lun[1]->queue_depth));
ASSERT(!chan->queue_depth || chan->cur_req);
*/
return;
} // end UniataRemoveRequest()
/*
Get currently processed request
(from head of the queue)
*/
PSCSI_REQUEST_BLOCK
UniataGetCurRequest(
IN PHW_CHANNEL chan
)
{
// if(!chan->lun[]->queue_depth) {
if(!chan || !chan->cur_req) {
return NULL;
}
return chan->cur_req->Srb;
} // end UniataGetCurRequest()
/*
Get next channel to be serviced
(used in simplex mode only)
*/
PHW_CHANNEL
UniataGetNextChannel(
IN PHW_CHANNEL chan
)
{
ULONG c=0, _c;
PHW_DEVICE_EXTENSION deviceExtension;
ULONG best_c;
ULONG cost_c;
deviceExtension = chan->DeviceExtension;
if(!deviceExtension->simplexOnly) {
return chan;
}
KdPrint2((PRINT_PREFIX "UniataGetNextChannel:\n"));
best_c = -1;
cost_c = 0;
for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
chan = &deviceExtension->chan[c];
if(chan->queue_depth &&
chan->queue_depth * (chan->ChannelSelectWaitCount+1) >
cost_c) {
best_c = c;
cost_c = chan->queue_depth * (chan->ChannelSelectWaitCount+1);
}
}
if(best_c == -1) {
KdPrint2((PRINT_PREFIX " empty queues\n"));
return NULL;
}
deviceExtension->FirstChannelToCheck = c;
for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
chan = &deviceExtension->chan[_c];
if(_c == best_c) {
chan->ChannelSelectWaitCount = 0;
continue;
}
chan->ChannelSelectWaitCount++;
if(!chan->queue_depth) {
chan->ChannelSelectWaitCount = 0;
} else {
chan->ChannelSelectWaitCount++;
}
}
KdPrint2((PRINT_PREFIX " select chan %d\n", best_c));
return &deviceExtension->chan[best_c];
} // end UniataGetNextChannel()

View file

@ -0,0 +1,41 @@
#ifndef __UNIATA_COMMAND_QUEUE_SUPPORT__H__
#define __UNIATA_COMMAND_QUEUE_SUPPORT__H__
/*
Insert command to proper place of command queue
Perform reorder if necessary
*/
VOID
UniataQueueRequest(
IN PHW_CHANNEL chan,
IN PSCSI_REQUEST_BLOCK Srb
);
/*
Remove request from queue and get next request
*/
VOID
UniataRemoveRequest(
IN PHW_CHANNEL chan,
IN PSCSI_REQUEST_BLOCK Srb
);
/*
Get currently processed request
(from head of the queue)
*/
PSCSI_REQUEST_BLOCK
UniataGetCurRequest(
IN PHW_CHANNEL chan
);
/*
Get next channel to be serviced
(used in simplex mode only)
*/
PHW_CHANNEL
UniataGetNextChannel(
IN PHW_CHANNEL chan
);
#endif __UNIATA_COMMAND_QUEUE_SUPPORT__H__

View file

@ -0,0 +1,289 @@
#include "stdafx.h"
UCHAR
UniataSataConnect(
IN PVOID HwDeviceExtension,
IN ULONG lChannel // logical channel
)
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
ULONG Channel = deviceExtension->Channel + lChannel;
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
SATA_SSTATUS_REG SStatus;
ULONG i;
/*
UCHAR signatureLow,
signatureHigh;
*/
UCHAR Status;
KdPrint2((PRINT_PREFIX "UniataSataConnect:\n"));
if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
KdPrint2((PRINT_PREFIX " no I/O range\n"));
return IDE_STATUS_IDLE;
}
/* clear SATA error register, some controllers need this */
AtapiWritePort4(chan, IDX_SATA_SError,
AtapiReadPort4(chan, IDX_SATA_SError));
/* wait up to 1 second for "connect well" */
for(i=0; i<100; i++) {
SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
if(SStatus.SPD == SStatus_SPD_Gen1 ||
SStatus.SPD == SStatus_SPD_Gen2) {
deviceExtension->lun[lChannel*2].TransferMode = ATA_SA150 + (UCHAR)(SStatus.SPD - 1);
break;
}
AtapiStallExecution(10000);
}
if(i >= 100) {
KdPrint2((PRINT_PREFIX "UniataSataConnect: SStatus %8.8x\n", SStatus.Reg));
return 0xff;
}
/* clear SATA error register */
AtapiWritePort4(chan, IDX_SATA_SError,
AtapiReadPort4(chan, IDX_SATA_SError));
Status = WaitOnBaseBusyLong(chan);
if(Status & IDE_STATUS_BUSY) {
return Status;
}
/*
signatureLow = AtapiReadPort1(chan, &deviceExtension->BaseIoAddress1[lChannel].i.CylinderLow);
signatureHigh = AtapiReadPort1(chan, &deviceExtension->baseIoAddress1[lChannel].i.CylinderHigh);
if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
}
*/
KdPrint2((PRINT_PREFIX "UniataSataConnect: OK, ATA status %x\n", Status));
return IDE_STATUS_IDLE;
} // end UniataSataConnect()
UCHAR
UniataSataPhyEnable(
IN PVOID HwDeviceExtension,
IN ULONG lChannel // logical channel
)
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
SATA_SCONTROL_REG SControl;
int loop, retry;
KdPrint2((PRINT_PREFIX "UniataSataPhyEnable:\n"));
if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
KdPrint2((PRINT_PREFIX " no I/O range\n"));
return IDE_STATUS_IDLE;
}
SControl.Reg = AtapiReadPort4(chan, IDX_SATA_SControl);
KdPrint2((PRINT_PREFIX "SControl %x\n", SControl.Reg));
if(SControl.DET == SControl_DET_Idle) {
return UniataSataConnect(HwDeviceExtension, lChannel);
}
for (retry = 0; retry < 10; retry++) {
KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: retry init %d\n", retry));
for (loop = 0; loop < 10; loop++) {
SControl.Reg = 0;
SControl.DET = SControl_DET_Init;
AtapiWritePort4(chan, IDX_SATA_SControl, SControl.Reg);
AtapiStallExecution(100);
SControl.Reg = AtapiReadPort4(chan, IDX_SATA_SControl);
KdPrint2((PRINT_PREFIX " SControl %8.8%x\n", SControl.Reg));
if(SControl.DET == SControl_DET_Init) {
break;
}
}
AtapiStallExecution(5000);
KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: retry idle %d\n", retry));
for (loop = 0; loop < 10; loop++) {
SControl.Reg = 0;
SControl.DET = SControl_DET_DoNothing;
SControl.IPM = SControl_IPM_NoPartialSlumber;
AtapiWritePort4(chan, IDX_SATA_SControl, SControl.Reg);
AtapiStallExecution(100);
SControl.Reg = AtapiReadPort4(chan, IDX_SATA_SControl);
KdPrint2((PRINT_PREFIX " SControl %8.8%x\n", SControl.Reg));
if(SControl.DET == SControl_DET_Idle) {
return UniataSataConnect(HwDeviceExtension, lChannel);
}
}
}
KdPrint2((PRINT_PREFIX "UniataSataPhyEnable: failed\n"));
return 0xff;
} // end UniataSataPhyEnable()
BOOLEAN
UniataSataClearErr(
IN PVOID HwDeviceExtension,
IN ULONG lChannel, // logical channel
IN BOOLEAN do_connect
)
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
SATA_SSTATUS_REG SStatus;
SATA_SERROR_REG SError;
if(deviceExtension->BaseIoAddressSATA_0.Addr) {
//if(ChipFlags & UNIATA_SATA) {
SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError);
if(SStatus.Reg) {
KdPrint2((PRINT_PREFIX " SStatus %x\n", SStatus.Reg));
}
if(SError.Reg) {
KdPrint2((PRINT_PREFIX " SError %x\n", SError.Reg));
/* clear error bits/interrupt */
AtapiWritePort4(chan, IDX_SATA_SError, SError.Reg);
if(do_connect) {
/* if we have a connection event deal with it */
if(SError.DIAG.N) {
KdPrint2((PRINT_PREFIX " catch SATA connect/disconnect\n"));
if(SStatus.SPD >= SStatus_SPD_Gen1) {
UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH);
} else {
UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH);
}
return TRUE;
}
}
}
}
return FALSE;
} // end UniataSataClearErr()
BOOLEAN
UniataSataEvent(
IN PVOID HwDeviceExtension,
IN ULONG lChannel, // logical channel
IN ULONG Action
)
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
UCHAR Status;
ULONG ldev = lChannel*2;
if(!deviceExtension->BaseIoAddressSATA_0.Addr) {
return FALSE;
}
switch(Action) {
case UNIATA_SATA_EVENT_ATTACH:
KdPrint2((PRINT_PREFIX " CONNECTED\n"));
Status = UniataSataConnect(HwDeviceExtension, lChannel);
KdPrint2((PRINT_PREFIX " Status %x\n", Status));
if(Status != IDE_STATUS_IDLE) {
return FALSE;
}
CheckDevice(HwDeviceExtension, lChannel, 0 /*dev*/, FALSE);
return TRUE;
break;
case UNIATA_SATA_EVENT_DETACH:
KdPrint2((PRINT_PREFIX " DISCONNECTED\n"));
deviceExtension->lun[ldev].DeviceFlags = 0;
return TRUE;
break;
}
return FALSE;
} // end UniataSataEvent()
BOOLEAN
UniataAhciInit(
IN PVOID HwDeviceExtension
)
{
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
ULONG version;
ULONG c;
PHW_CHANNEL chan;
ULONG offs;
ULONG BaseMemAddress;
ULONG PI;
ULONG CAP;
BOOLEAN MemIo;
/* reset AHCI controller */
AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC) | AHCI_GHC_HR);
AtapiStallExecution(1000000);
if(AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC) & AHCI_GHC_HR) {
KdPrint2((PRINT_PREFIX " AHCI reset failed\n"));
return FALSE;
}
/* enable AHCI mode */
AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC) | AHCI_GHC_AE);
CAP = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_CAP);
/* get the number of HW channels */
deviceExtension->NumberChannels =
(CAP & AHCI_CAP_NOP_MASK)+1;
if(CAP & AHCI_CAP_S64A) {
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
deviceExtension->Host64 = TRUE;
}
/* clear interrupts */
AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_IS,
AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_IS));
/* enable AHCI interrupts */
AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC) | AHCI_GHC_IE);
version = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_VS);
PI = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_PI);
KdPrint2((PRINT_PREFIX " AHCI version %x%x.%x%x controller with %d ports (mask %x) detected\n",
(version >> 24) & 0xff, (version >> 16) & 0xff,
(version >> 8) & 0xff, version & 0xff, deviceExtension->NumberChannels, PI));
deviceExtension->HwFlags |= UNIATA_SATA;
deviceExtension->HwFlags |= UNIATA_AHCI;
BaseMemAddress = deviceExtension->BaseIoAHCI_0.Addr;
MemIo = deviceExtension->BaseIoAHCI_0.MemIo;
for(c=0; c<deviceExtension->NumberChannels; c++) {
chan = &deviceExtension->chan[c];
offs = sizeof(IDE_AHCI_REGISTERS) + c*sizeof(IDE_AHCI_PORT_REGISTERS);
chan->RegTranslation[IDX_IO1_i_Status ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD.STS);
chan->RegTranslation[IDX_IO1_i_Status ].MemIo = MemIo;
chan->RegTranslation[IDX_IO2_AltStatus] = chan->RegTranslation[IDX_IO1_i_Status];
chan->RegTranslation[IDX_IO1_i_Error ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD.ERR);
chan->RegTranslation[IDX_IO1_i_Error ].MemIo = MemIo;
chan->RegTranslation[IDX_IO1_i_CylinderLow ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG.LbaLow);
chan->RegTranslation[IDX_IO1_i_CylinderLow ].MemIo = MemIo;
chan->RegTranslation[IDX_IO1_i_CylinderHigh].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG.LbaHigh);
chan->RegTranslation[IDX_IO1_i_CylinderHigh].MemIo = MemIo;
chan->RegTranslation[IDX_IO1_i_BlockCount ].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG.SectorCount);
chan->RegTranslation[IDX_IO1_i_BlockCount ].MemIo = MemIo;
UniataInitSyncBaseIO(chan);
chan->RegTranslation[IDX_SATA_SStatus].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SSTS);
chan->RegTranslation[IDX_SATA_SStatus].MemIo = MemIo;
chan->RegTranslation[IDX_SATA_SError].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SERR);
chan->RegTranslation[IDX_SATA_SError].MemIo = MemIo;
chan->RegTranslation[IDX_SATA_SControl].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SCTL);
chan->RegTranslation[IDX_SATA_SControl].MemIo = MemIo;
chan->RegTranslation[IDX_SATA_SActive].Addr = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT);
chan->RegTranslation[IDX_SATA_SActive].MemIo = MemIo;
chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
}
return TRUE;
} // end UniataAhciInit()

View file

@ -0,0 +1,36 @@
#ifndef __UNIATA_SATA__H__
#define __UNIATA_SATA__H__
UCHAR
UniataSataConnect(
IN PVOID HwDeviceExtension,
IN ULONG lChannel // logical channel
);
UCHAR
UniataSataPhyEnable(
IN PVOID HwDeviceExtension,
IN ULONG lChannel // logical channel
);
#define UNIATA_SATA_DO_CONNECT TRUE
#define UNIATA_SATA_IGNORE_CONNECT FALSE
BOOLEAN
UniataSataClearErr(
IN PVOID HwDeviceExtension,
IN ULONG lChannel, // logical channel
IN BOOLEAN do_connect
);
#define UNIATA_SATA_EVENT_ATTACH 0x01
#define UNIATA_SATA_EVENT_DETACH 0x02
BOOLEAN
UniataSataEvent(
IN PVOID HwDeviceExtension,
IN ULONG lChannel, // logical channel
IN ULONG Action
);
#endif __UNIATA_SATA__H__

View file

@ -0,0 +1,8 @@
; IDEDMA.def
NAME IDEDMA.SYS
DESCRIPTION 'IDEDMA.SYS'
EXPORTS

View file

@ -0,0 +1,27 @@
#include <windows.h>
#include <ntverp.h>
#include "uniata_ver.h"
#undef VERSION
#define VERSION "0." UNIATA_VER_STR
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
#undef VER_COMPANYNAME_STR
#define VER_COMPANYNAME_STR "AlterWare"
#define VER_FILEDESCRIPTION_STR "Universal IDE BusMaster (DMA) Miniport Driver"
#define VER_INTERNALNAME_STR "uniata.sys\0"
#define VER_ORIGINALFILENAME_STR "uniata.sys"
#define VER_LEGALCOPYRIGHT_YEARS "1999-2004"
#define VER_LEGALCOPYRIGHT_STR "Copyright \251 AlterWare" VER_LEGALCOPYRIGHT_YEARS
#undef VER_PRODUCTNAME_STR
#define VER_PRODUCTNAME_STR "UniATA"
#undef VER_PRODUCTVERSION
#define VER_PRODUCTVERSION 0,31,2
#undef VER_PRODUCTVERSION_STR
#define VER_PRODUCTVERSION_STR VERSION
#undef VER_LEGALTRADEMARKS_STR
#define VER_LANGNEUTRAL
#include "common.ver"

View file

@ -0,0 +1,58 @@
#ifdef CROSSNT_DECL
#undef CROSSNT_DECL
#undef CROSSNT_DECL_EX
#endif //CROSSNT_DECL
/***************************/
#ifdef CROSSNT_DECL_API
#define CROSSNT_DECL(type, dspec, name, args, callargs) \
typedef type (dspec *ptr##name) args; \
extern "C" ptr##name CrNt##name; \
type dspec CrNt##name##_impl args;
#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
typedef type (dspec *ptr##name) args; \
extern "C" ptr##name CrNt##name; \
type dspec CrNt##name##_impl args;
#endif //CROSSNT_DECL_API
/***************************/
#ifdef CROSSNT_DECL_STUB
#define CROSSNT_DECL(type, dspec, name, args, callargs) \
extern "C" ptr##name CrNt##name = NULL; \
#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
extern "C" ptr##name CrNt##name = NULL; \
#endif //CROSSNT_DECL_STUB
/***************************/
#ifdef CROSSNT_INIT_STUB
#define CROSSNT_DECL(type, dspec, name, args, callargs) \
KdPrint(("Init " #name " cur %x\n", CrNt##name)); \
if(!CrNt##name) { \
CrNt##name = (ptr##name)CrNtGetProcAddress(g_hNtosKrnl, #name); \
KdPrint((" GetProcAddr(NTOSKRNL.EXE," #name ") = %x\n", CrNt##name)); \
if(!CrNt##name) { \
CrNt##name = CrNt##name##_impl; \
} \
KdPrint((" final %\n", CrNt##name)); \
}
#define CROSSNT_DECL_EX(mod, type, dspec, name, args, callargs) \
KdPrint(("Init " mod "," #name " cur %x\n", CrNt##name)); \
if(!CrNt##name) { \
CrNt##name = (ptr##name)CrNtGetProcAddress(CrNtGetModuleBase(mod), #name); \
KdPrint((" GetProcAddr(" mod "," #name ") = %x\n", CrNt##name)); \
if(!CrNt##name) { \
CrNt##name = CrNt##name##_impl; \
} \
KdPrint((" final %x\n", CrNt##name)); \
}
#endif //CROSSNT_INIT_STUB

View file

@ -0,0 +1,109 @@
CROSSNT_DECL(
HANDLE,__stdcall,
PsGetCurrentProcessId,(),())
CROSSNT_DECL(
HANDLE,__stdcall,
PsGetCurrentThreadId,(),())
CROSSNT_DECL(
BOOLEAN,
__fastcall,
KeTestSpinLock,(
IN PKSPIN_LOCK SpinLock
),
(
SpinLock
))
CROSSNT_DECL(
LONG,
__fastcall,
InterlockedIncrement,(
IN OUT PLONG Addend
),
(
IN OUT PLONG Addend
))
CROSSNT_DECL(
LONG,
__fastcall,
InterlockedDecrement,(
IN OUT PLONG Addend
),
(
IN OUT PLONG Addend
))
CROSSNT_DECL(
LONG,
__fastcall,
InterlockedExchangeAdd,(
IN OUT PLONG Addend,
IN LONG Increment
),
(
IN OUT PLONG Addend,
IN LONG Increment
))
CROSSNT_DECL(
PVOID,
__fastcall,
InterlockedCompareExchange,(
IN OUT PVOID *Destination,
IN PVOID ExChange,
IN PVOID Comperand
),
(
IN OUT PVOID *Destination,
IN PVOID ExChange,
IN PVOID Comperand
))
CROSSNT_DECL_EX("HAL.DLL",
KIRQL,__stdcall,
KeRaiseIrqlToDpcLevel,(),())
CROSSNT_DECL_EX("HAL.DLL",
KIRQL,__stdcall,
KeRaiseIrqlToSynchLevel,(),())
CROSSNT_DECL_EX("NDIS.SYS",
VOID,
__stdcall,
NdisInitializeReadWriteLock,(
IN PNDIS_RW_LOCK Lock
),
(
Lock
))
CROSSNT_DECL_EX("NDIS.SYS",
VOID,
__stdcall,
NdisAcquireReadWriteLock,(
IN PNDIS_RW_LOCK Lock,
IN BOOLEAN fWrite,
IN PLOCK_STATE LockState
),
(
Lock,
fWrite,
LockState
))
CROSSNT_DECL_EX("NDIS.SYS",
VOID,
__stdcall,
NdisReleaseReadWriteLock,(
IN PNDIS_RW_LOCK Lock,
IN PLOCK_STATE LockState
),
(
Lock,
LockState
))

View file

@ -0,0 +1,136 @@
#ifndef __CROSS_VERSION_LIB_NT__H__
#define __CROSS_VERSION_LIB_NT__H__
extern "C" {
#pragma pack(push, 8)
#if !defined(NT_INCLUDED)
#include <ntddk.h> // various NT definitions
#endif
#include <stddef.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "ntddk_ex.h"
#include "tools.h"
#include "rwlock.h"
#ifdef CROSS_NT_INTERNAL
#include "ilock.h"
#endif //CROSS_NT_INTERNAL
#include "misc.h"
#pragma pack(pop)
extern "C"
NTSTATUS
CrNtInit(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
extern "C"
PVOID
CrNtGetModuleBase(
IN PCHAR pModuleName
);
extern "C"
PVOID
CrNtFindModuleBaseByPtr(
IN PVOID ptrInSection,
IN PCHAR ptrExportedName
);
extern "C"
PVOID
CrNtGetProcAddress(
PVOID ModuleBase,
PCHAR pFunctionName
);
typedef BOOLEAN (__stdcall *ptrCrNtPsGetVersion)(
PULONG MajorVersion OPTIONAL,
PULONG MinorVersion OPTIONAL,
PULONG BuildNumber OPTIONAL,
PUNICODE_STRING CSDVersion OPTIONAL
);
extern "C"
ptrCrNtPsGetVersion CrNtPsGetVersion;
typedef NTSTATUS (__stdcall *ptrCrNtNtQuerySystemInformation)(
IN SYSTEM_INFORMATION_CLASS SystemInfoClass,
OUT PVOID SystemInfoBuffer,
IN ULONG SystemInfoBufferSize,
OUT PULONG BytesReturned OPTIONAL
);
extern "C"
ptrCrNtNtQuerySystemInformation CrNtNtQuerySystemInformation;
extern "C" {
extern ULONG MajorVersion;
extern ULONG MinorVersion;
extern ULONG BuildNumber;
extern ULONG SPVersion;
extern HANDLE g_hNtosKrnl;
extern HANDLE g_hHal;
};
#define WinVer_Is351 (MajorVersion==0x03)
#define WinVer_IsNT (MajorVersion==0x04)
#define WinVer_Is2k (MajorVersion==0x05 && MinorVersion==0x00)
#define WinVer_IsXP (MajorVersion==0x05 && MinorVersion==0x01)
#define WinVer_IsXPp (MajorVersion==0x05 && MinorVersion>=0x01)
#define WinVer_IsdNET (MajorVersion==0x05 && MinorVersion==0x02)
#define WinVer_IsdNETp ((MajorVersion==0x05 && MinorVersion>=0x02) || (MajorVersion>0x05))
#define WinVer_IsVista (MajorVersion==0x06 && MinorVersion==0x00)
#define WinVer_Id() ((MajorVersion << 8) | MinorVersion)
#define WinVer_351 (0x0351)
#define WinVer_NT (0x0400)
#define WinVer_ROS (0x0401)
#define WinVer_2k (0x0500)
#define WinVer_XP (0x0501)
#define WinVer_dNET (0x0502)
#define WinVer_Vista (0x0600)
#ifdef _DEBUG
// NT3.51 doesn't export strlen() and strcmp()
// The same time, Release build doesn't depend no these functions since they are inlined
size_t __cdecl CrNtstrlen (
const char * str
);
int __cdecl CrNtstrcmp (
const char * src,
const char * dst
);
#define strlen CrNtstrlen
#define strcmp CrNtstrcmp
#endif //_DEBUG
#define CROSSNT_DECL_API
#include "CrNtDecl.h"
#include "CrNtStubs.h"
#undef CROSSNT_DECL_API
}; // end extern "C"
#endif //__CROSS_VERSION_LIB_NT__H__

View file

@ -0,0 +1,46 @@
#ifndef __DBG_DUMP_TOOLS__H__
#define __DBG_DUMP_TOOLS__H__
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
BOOLEAN
_cdecl
DbgDump_Printf(
PCHAR Format,
...
);
BOOLEAN
__stdcall
DbgDump_Print(
PCHAR Msg
);
BOOLEAN
__stdcall
DbgDump_Printn(
PCHAR Msg,
ULONG Length
);
BOOLEAN
__stdcall
DbgDump_Reconnect();
VOID
__stdcall
DbgDump_Disconnect();
VOID
__stdcall
DbgDump_SetAutoReconnect(
BOOLEAN AutoReconnect
);
#ifdef __cplusplus
};
#endif //__cplusplus
#endif //__DBG_DUMP_TOOLS__H__

View file

@ -0,0 +1,144 @@
#ifndef __CROSSNT_MISC__H__
#define __CROSSNT_MISC__H__
typedef void
(__fastcall *ptrMOV_DD_SWP)(
void* a, // ECX
void* b // EDX
);
extern "C" ptrMOV_DD_SWP _MOV_DD_SWP;
extern "C"
void
__fastcall
_MOV_DD_SWP_i486(
void* a, // ECX
void* b // EDX
);
extern "C"
void
__fastcall
_MOV_DD_SWP_i386(
void* a, // ECX
void* b // EDX
);
#define MOV_DD_SWP(a,b) _MOV_DD_SWP(&(a),&(b))
/********************/
extern "C"
void
__fastcall
_MOV_DW_SWP(
void* a, // ECX
void* b // EDX
);
#define MOV_DW_SWP(a,b) _MOV_DW_SWP(&(a),&(b))
/********************/
typedef void
(__fastcall *ptrREVERSE_DD)(
void* a // ECX
);
extern "C" ptrREVERSE_DD _REVERSE_DD;
void
__fastcall
_REVERSE_DD_i486(
void* a // ECX
);
void
__fastcall
_REVERSE_DD_i386(
void* a // ECX
);
#define REVERSE_DD(a,b) _REVERSE_DD(&(a),&(b))
/********************/
extern "C"
void
__fastcall
_REVERSE_DW(
void* a // ECX
);
#define REVERSE_DW(a) _REVERSE_DW(&(a))
/********************/
extern "C"
void
__fastcall
_MOV_DW2DD_SWP(
void* a, // ECX
void* b // EDX
);
#define MOV_DW2DD_SWP(a,b) _MOV_DW2DD_SWP(&(a),&(b))
/********************/
extern "C"
void
__fastcall
_MOV_SWP_DW2DD(
void* a, // ECX
void* b // EDX
);
#define MOV_SWP_DW2DD(a,b) _MOV_SWP_DW2DD(&(a),&(b))
/********************/
extern "C"
void
__fastcall
_MOV_MSF(
void* a, // ECX
void* b // EDX
);
#define MOV_MSF(a,b) _MOV_MSF(&(a),&(b))
/********************/
typedef void
(__fastcall *ptrMOV_MSF_SWP)(
void* a, // ECX
void* b // EDX
);
extern "C" ptrMOV_MSF_SWP _MOV_MSF_SWP;
extern "C"
void
__fastcall
_MOV_MSF_SWP_i486(
void* a, // ECX
void* b // EDX
);
extern "C"
void
__fastcall
_MOV_MSF_SWP_i386(
void* a, // ECX
void* b // EDX
);
#define MOV_MSF_SWP(a,b) _MOV_MSF_SWP(&(a),&(b))
/********************/
extern "C"
void
__fastcall
_XCHG_DD(
void* a, // ECX
void* b // EDX
);
#define XCHG_DD(a,b) _XCHG_DD(&(a),&(b))
#endif // __CROSSNT_MISC__H__

View file

@ -0,0 +1,39 @@
#ifndef __CROSS_NT_RWLOCK__H__
#define __CROSS_NT_RWLOCK__H__
#ifndef MAXIMUM_PROCESSORS
#define MAXIMUM_PROCESSORS 32
#endif
typedef union _NDIS_RW_LOCK_REFCOUNT {
unsigned int RefCount;
UCHAR cacheLine[16]; // One refCount per cache line
} NDIS_RW_LOCK_REFCOUNT;
typedef struct _NDIS_RW_LOCK {
union {
struct {
KSPIN_LOCK SpinLock;
PVOID Context;
};
UCHAR Reserved[16];
};
NDIS_RW_LOCK_REFCOUNT RefCount[MAXIMUM_PROCESSORS];
} NDIS_RW_LOCK, *PNDIS_RW_LOCK;
typedef struct _LOCK_STATE {
USHORT LockState;
KIRQL OldIrql;
} LOCK_STATE, *PLOCK_STATE;
#define RWLOCK_STATE_FREE 0
#define RWLOCK_STATE_READ_ACQUIRED 1
#define RWLOCK_STATE_WRITE_ACQUIRED 2
#define RWLOCK_STATE_RECURSIVE 3
#define RWLOCK_STATE_RELEASED 0xffff
#define RWLOCK_FOR_WRITE TRUE
#define RWLOCK_FOR_READ FALSE
#endif __CROSS_NT_RWLOCK__H__

View file

@ -0,0 +1,571 @@
#ifndef __NTDDK_EX__H__
#define __NTDDK_EX__H__
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemNextEventIdInformation,
SystemEventIdsInformation,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
SystemPowerInformation,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation
} SYSTEM_INFORMATION_CLASS;
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInfoClass,
OUT PVOID SystemInfoBuffer,
IN ULONG SystemInfoBufferSize,
OUT PULONG BytesReturned OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInfoClass,
OUT PVOID SystemInfoBuffer,
IN ULONG SystemInfoBufferSize,
OUT PULONG BytesReturned OPTIONAL
);
typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
ULONG MinimumUserModeAddress;
ULONG MaximumUserModeAddress;
KAFFINITY ActiveProcessorsAffinityMask;
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
typedef struct _SYSTEM_MODULE_ENTRY
{
ULONG Unused;
ULONG Always0;
PVOID ModuleBaseAddress;
ULONG ModuleSize;
ULONG Unknown;
ULONG ModuleEntryIndex;
USHORT ModuleNameLength;
USHORT ModuleNameOffset;
CHAR ModuleName [256];
} SYSTEM_MODULE_ENTRY, * PSYSTEM_MODULE_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Count;
SYSTEM_MODULE_ENTRY Module [1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef unsigned short WORD;
typedef unsigned int BOOL;
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY LoadOrder;
LIST_ENTRY MemoryOrder;
LIST_ENTRY InitializationOrder;
PVOID ModuleBaseAddress;
PVOID EntryPoint;
ULONG ModuleSize;
UNICODE_STRING FullModuleName;
UNICODE_STRING ModuleName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY Hash;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
ULONG TimeStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
HANDLE SsHandle;
LIST_ENTRY LoadOrder;
LIST_ENTRY MemoryOrder;
LIST_ENTRY InitializationOrder;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _PEB_FREE_BLOCK {
struct _PEB_FREE_BLOCK *Next;
ULONG Size;
} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;
#define GDI_HANDLE_BUFFER_SIZE 34
#define TLS_MINIMUM_AVAILABLE 64 // winnt
typedef struct _PEB {
BOOLEAN InheritedAddressSpace; // These four fields cannot change unless the
BOOLEAN ReadImageFileExecOptions; //
BOOLEAN BeingDebugged; //
BOOLEAN SpareBool; //
HANDLE Mutant; // INITIAL_PEB structure is also updated.
PVOID ImageBaseAddress;
PPEB_LDR_DATA Ldr;
struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID KernelCallbackTable;
HANDLE EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[2]; // relates to TLS_MINIMUM_AVAILABLE
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID *ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
// Useful information for LdrpInitialize
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
// Passed up from MmCreatePeb from Session Manager registry key
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
// Where heap manager keeps track of all heaps created for a process
// Fields initialized by MmCreatePeb. ProcessHeaps is initialized
// to point to the first free byte after the PEB and MaximumNumberOfHeaps
// is computed from the page size used to hold the PEB, less the fixed
// size of this data structure.
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID *ProcessHeaps;
//
//
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
// Following fields filled in by MmCreatePeb from system values and/or
// image header.
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubsystem;
ULONG ImageSubsystemMajorVersion;
ULONG ImageSubsystemMinorVersion;
ULONG ImageProcessAffinityMask;
ULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];
} PEB, *PPEB;
//
// Gdi command batching
//
#define GDI_BATCH_BUFFER_SIZE 310
typedef struct _GDI_TEB_BATCH {
ULONG Offset;
ULONG HDC;
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
} GDI_TEB_BATCH,*PGDI_TEB_BATCH;
//
// TEB - The thread environment block
//
#define STATIC_UNICODE_BUFFER_LENGTH 261
#define WIN32_CLIENT_INFO_LENGTH 31
#define WIN32_CLIENT_INFO_SPIN_COUNT 1
typedef struct _TEB {
NT_TIB NtTib;
PVOID EnvironmentPointer;
CLIENT_ID ClientId;
PVOID ActiveRpcHandle;
PVOID ThreadLocalStoragePointer;
PPEB ProcessEnvironmentBlock;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
PVOID CsrClientThread;
PVOID Win32ThreadInfo; // PtiCurrent
ULONG Win32ClientInfo[WIN32_CLIENT_INFO_LENGTH]; // User32 Client Info
PVOID WOW32Reserved; // used by WOW
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID SystemReserved1[54]; // Used by FP emulator
PVOID Spare1; // unused
NTSTATUS ExceptionCode; // for RaiseUserException
UCHAR SpareBytes1[40];
PVOID SystemReserved2[10]; // Used by user/console for temp obja
GDI_TEB_BATCH GdiTebBatch; // Gdi batching
ULONG gdiRgn;
ULONG gdiPen;
ULONG gdiBrush;
CLIENT_ID RealClientId;
HANDLE GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
PVOID GdiThreadLocalInfo;
PVOID UserReserved[5]; // unused
PVOID glDispatchTable[280]; // OpenGL
ULONG glReserved1[26]; // OpenGL
PVOID glReserved2; // OpenGL
PVOID glSectionInfo; // OpenGL
PVOID glSection; // OpenGL
PVOID glTable; // OpenGL
PVOID glCurrentRC; // OpenGL
PVOID glContext; // OpenGL
ULONG LastStatusValue;
UNICODE_STRING StaticUnicodeString;
WCHAR StaticUnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
PVOID DeallocationStack;
PVOID TlsSlots[TLS_MINIMUM_AVAILABLE];
LIST_ENTRY TlsLinks;
PVOID Vdm;
PVOID ReservedForNtRpc;
PVOID DbgSsReserved[2];
ULONG HardErrorsAreDisabled;
PVOID Instrumentation[16];
PVOID WinSockData; // WinSock
ULONG GdiBatchCount;
ULONG Spare2;
ULONG Spare3;
ULONG Spare4;
PVOID ReservedForOle;
ULONG WaitingOnLoaderLock;
} TEB;
typedef TEB *PTEB;
typedef struct _KTHREAD_HDR {
//
// The dispatcher header and mutant listhead are faifly infrequently
// referenced, but pad the thread to a 32-byte boundary (assumption
// that pool allocation is in units of 32-bytes).
//
DISPATCHER_HEADER Header;
LIST_ENTRY MutantListHead;
//
// The following fields are referenced during trap, interrupts, or
// context switches.
//
// N.B. The Teb address and TlsArray are loaded as a quadword quantity
// on MIPS and therefore must to on a quadword boundary.
//
PVOID InitialStack;
PVOID StackLimit;
PVOID Teb;
PVOID TlsArray;
PVOID KernelStack;
BOOLEAN DebugActive;
UCHAR State;
BOOLEAN Alerted[MaximumMode];
UCHAR Iopl;
UCHAR NpxState;
BOOLEAN Saturation;
SCHAR Priority;
/* KAPC_STATE ApcState;
ULONG ContextSwitches;
//
// The following fields are referenced during wait operations.
//
NTSTATUS WaitStatus;
KIRQL WaitIrql;
KPROCESSOR_MODE WaitMode;
BOOLEAN WaitNext;
UCHAR WaitReason;
PRKWAIT_BLOCK WaitBlockList;
LIST_ENTRY WaitListEntry;
ULONG WaitTime;
SCHAR BasePriority;
UCHAR DecrementCount;
SCHAR PriorityDecrement;
SCHAR Quantum;
KWAIT_BLOCK WaitBlock[THREAD_WAIT_OBJECTS + 1];
PVOID LegoData;
ULONG KernelApcDisable;
KAFFINITY UserAffinity;
BOOLEAN SystemAffinityActive;
UCHAR Pad[3];
PVOID ServiceTable;
// struct _ECHANNEL *Channel;
// PVOID Section;
// PCHANNEL_MESSAGE SystemView;
// PCHANNEL_MESSAGE ThreadView;
//
// The following fields are referenced during queue operations.
//
PRKQUEUE Queue;
KSPIN_LOCK ApcQueueLock;
KTIMER Timer;
LIST_ENTRY QueueListEntry;
//
// The following fields are referenced during read and find ready
// thread.
//
KAFFINITY Affinity;
BOOLEAN Preempted;
BOOLEAN ProcessReadyQueue;
BOOLEAN KernelStackResident;
UCHAR NextProcessor;
//
// The following fields are referenced suring system calls.
//
PVOID CallbackStack;
PVOID Win32Thread;
PKTRAP_FRAME TrapFrame;
PKAPC_STATE ApcStatePointer[2];
UCHAR EnableStackSwap;
UCHAR LargeStack;
UCHAR ResourceIndex;
CCHAR PreviousMode;
//
// The following entries are reference during clock interrupts.
//
ULONG KernelTime;
ULONG UserTime;
//
// The following fileds are referenced during APC queuing and process
// attach/detach.
//
KAPC_STATE SavedApcState;
BOOLEAN Alertable;
UCHAR ApcStateIndex;
BOOLEAN ApcQueueable;
BOOLEAN AutoAlignment;
//
// The following fields are referenced when the thread is initialized
// and very infrequently thereafter.
//
PVOID StackBase;
KAPC SuspendApc;
KSEMAPHORE SuspendSemaphore;
LIST_ENTRY ThreadListEntry;
//
// N.B. The below four UCHARs share the same DWORD and are modified
// by other threads. Therefore, they must ALWAYS be modified
// under the dispatcher lock to prevent granularity problems
// on Alpha machines.
//
CCHAR FreezeCount;
CCHAR SuspendCount;
UCHAR IdealProcessor;
UCHAR DisableBoost;
*/
} KTHREAD_HDR, *PKTHREAD_HDR;
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
NTHALAPI
VOID
HalDisplayString (
PUCHAR String
);
NTHALAPI
VOID
HalQueryDisplayParameters (
OUT PULONG WidthInCharacters,
OUT PULONG HeightInLines,
OUT PULONG CursorColumn,
OUT PULONG CursorRow
);
NTHALAPI
VOID
HalSetDisplayParameters (
IN ULONG CursorColumn,
IN ULONG CursorRow
);
extern ULONG NtBuildNumber;
#endif //__NTDDK_EX__H__

View file

@ -0,0 +1,235 @@
/*++ BUILD Version: 0001 // Increment this if a change has global effects
Copyright (c) 1990-1993 Microsoft Corporation
Module Name:
ntddscsi.h
Abstract:
This is the include file that defines all constants and types for
accessing the SCSI port adapters.
Author:
Jeff Havens
Revision History:
--*/
#ifndef _NTDDSCSIH_
#define _NTDDSCSIH_
#pragma pack(push, 8)
//
// Device Name - this string is the name of the device. It is the name
// that should be passed to NtOpenFile when accessing the device.
//
// Note: For devices that support multiple units, it should be suffixed
// with the Ascii representation of the unit number.
//
#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
#define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort"
//
// NtDeviceIoControlFile IoControlCode values for this device.
//
// Warning: Remember that the low two bits of the code specify how the
// buffers are passed to the driver!
//
#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS)
//
// Define the SCSI pass through structure.
//
typedef struct _SCSI_PASS_THROUGH {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
ULONG DataBufferOffset;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
}SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
//
// Define the SCSI pass through direct structure.
//
typedef struct _SCSI_PASS_THROUGH_DIRECT {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
PVOID DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
//
// Define SCSI information.
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
//
typedef struct _SCSI_BUS_DATA {
UCHAR NumberOfLogicalUnits;
UCHAR InitiatorBusId;
ULONG InquiryDataOffset;
}SCSI_BUS_DATA, *PSCSI_BUS_DATA;
//
// Define SCSI adapter bus information structure..
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
//
typedef struct _SCSI_ADAPTER_BUS_INFO {
UCHAR NumberOfBuses;
SCSI_BUS_DATA BusData[1];
} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
//
// Define SCSI adapter bus information.
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
//
typedef struct _SCSI_INQUIRY_DATA {
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
BOOLEAN DeviceClaimed;
ULONG InquiryDataLength;
ULONG NextInquiryDataOffset;
UCHAR InquiryData[1];
}SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
//
// Define header for I/O control SRB.
//
typedef struct _SRB_IO_CONTROL {
ULONG HeaderLength;
UCHAR Signature[8];
ULONG Timeout;
ULONG ControlCode;
ULONG ReturnCode;
ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
//
// SCSI port driver capabilities structure.
//
typedef struct _IO_SCSI_CAPABILITIES {
//
// Length of this structure
//
ULONG Length;
//
// Maximum transfer size in single SRB
//
ULONG MaximumTransferLength;
//
// Maximum number of physical pages per data buffer
//
ULONG MaximumPhysicalPages;
//
// Async calls from port to class
//
ULONG SupportedAsynchronousEvents;
//
// Alignment mask for data transfers.
//
ULONG AlignmentMask;
//
// Supports tagged queuing
//
BOOLEAN TaggedQueuing;
//
// Host adapter scans down for bios devices.
//
BOOLEAN AdapterScansDown;
//
// The host adapter uses programmed I/O.
//
BOOLEAN AdapterUsesPio;
} IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES;
typedef struct _SCSI_ADDRESS {
ULONG Length;
UCHAR PortNumber;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
}SCSI_ADDRESS, *PSCSI_ADDRESS;
//
// Define structure for returning crash dump pointers.
//
struct _ADAPTER_OBJECT;
typedef struct _DUMP_POINTERS {
struct _ADAPTER_OBJECT *AdapterObject;
PVOID MappedRegisterBase;
PVOID PortConfiguration;
PVOID CommonBufferVa;
LARGE_INTEGER CommonBufferPa;
ULONG CommonBufferSize;
} DUMP_POINTERS, *PDUMP_POINTERS;
//
// Define values for pass-through DataIn field.
//
#define SCSI_IOCTL_DATA_OUT 0
#define SCSI_IOCTL_DATA_IN 1
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
#pragma pack(pop)
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,970 @@
/*
Module Name:
srb.h
Abstract:
This file defines the interface between SCSI mini-port drivers and the
SCSI port driver. It is also used by SCSI class drivers to talk to the
SCSI port driver.
w2k-related definitions are added by Alter from w2k/xp DDK
*/
#ifndef _NTSRB_
#define _NTSRB_
// Define SCSI maximum configuration parameters.
#define SCSI_MAXIMUM_LOGICAL_UNITS 8
#define SCSI_MAXIMUM_TARGETS_PER_BUS 128
#define SCSI_MAXIMUM_LUNS_PER_TARGET 255
#define SCSI_MAXIMUM_BUSES 8
#define SCSI_MINIMUM_PHYSICAL_BREAKS 16
#define SCSI_MAXIMUM_PHYSICAL_BREAKS 255
// This constant is for backward compatibility.
// This use to be the maximum number of targets supported.
#define SCSI_MAXIMUM_TARGETS 8
// begin_ntminitape
#define MAXIMUM_CDB_SIZE 12
// end_ntminitape
#ifndef USER_MODE
typedef PHYSICAL_ADDRESS SCSI_PHYSICAL_ADDRESS, *PSCSI_PHYSICAL_ADDRESS;
typedef struct _ACCESS_RANGE {
SCSI_PHYSICAL_ADDRESS RangeStart;
ULONG RangeLength;
BOOLEAN RangeInMemory;
}ACCESS_RANGE, *PACCESS_RANGE;
//
// Configuration information structure. Contains the information necessary
// to initialize the adapter. NOTE: This structure's must be a multiple of
// quadwords.
//
typedef struct _PORT_CONFIGURATION_INFORMATION {
ULONG Length; // Length of port configuation information strucuture.
ULONG SystemIoBusNumber; // IO bus number (0 for machines that have only 1 IO bus
INTERFACE_TYPE AdapterInterfaceType; // EISA, MCA or ISA
ULONG BusInterruptLevel; // Interrupt request level for device
// Bus interrupt vector used with hardware buses which use as vector as
// well as level, such as internal buses.
ULONG BusInterruptVector;
KINTERRUPT_MODE InterruptMode; // Interrupt mode (level-sensitive or edge-triggered)
ULONG MaximumTransferLength; // Max bytes that can be transferred in a single SRB
ULONG NumberOfPhysicalBreaks; // Number of contiguous blocks of physical memory
ULONG DmaChannel; // DMA channel for devices using system DMA
ULONG DmaPort;
DMA_WIDTH DmaWidth;
DMA_SPEED DmaSpeed;
ULONG AlignmentMask; // Alignment masked for the adapter for data transfers.
ULONG NumberOfAccessRanges; // Number of allocated access range elements.
ACCESS_RANGE (*AccessRanges)[]; // Pointer to array of access range elements.
PVOID Reserved;
UCHAR NumberOfBuses; // Number of SCSI buses attached to the adapter.
CCHAR InitiatorBusId[8]; // SCSI bus ID for adapter
BOOLEAN ScatterGather; // Indicates that the adapter does scatter/gather
BOOLEAN Master; // Indicates that the adapter is a bus master
BOOLEAN CachesData; // Host caches data or state.
BOOLEAN AdapterScansDown; // Host adapter scans down for bios devices.
BOOLEAN AtdiskPrimaryClaimed; // Primary at disk address (0x1F0) claimed.
BOOLEAN AtdiskSecondaryClaimed; // Secondary at disk address (0x170) claimed.
BOOLEAN Dma32BitAddresses; // The master uses 32-bit DMA addresses.
BOOLEAN DemandMode; // Use Demand Mode DMA rather than Single Request.
BOOLEAN MapBuffers; // Data buffers must be mapped into virtual address space.
BOOLEAN NeedPhysicalAddresses; // We need to tranlate virtual to physical addresses.
BOOLEAN TaggedQueuing; // Supports tagged queuing
BOOLEAN AutoRequestSense; // Supports auto request sense.
BOOLEAN MultipleRequestPerLu; // Supports multiple requests per logical unit.
BOOLEAN ReceiveEvent; // Support receive event function.
BOOLEAN RealModeInitialized; // Indicates the real-mode driver has initialized the card.
BOOLEAN BufferAccessScsiPortControlled; // Indicate that the miniport will not touch
// the data buffers directly.
UCHAR MaximumNumberOfTargets; // Indicator for wide scsi.
UCHAR ReservedUchars[2]; // Ensure quadword alignment.
ULONG SlotNumber; // Adapter slot number
ULONG BusInterruptLevel2; // Interrupt information for a second IRQ.
ULONG BusInterruptVector2;
KINTERRUPT_MODE InterruptMode2;
ULONG DmaChannel2; // DMA information for a second channel.
ULONG DmaPort2;
DMA_WIDTH DmaWidth2;
DMA_SPEED DmaSpeed2;
} PORT_CONFIGURATION_INFORMATION, *PPORT_CONFIGURATION_INFORMATION;
typedef struct _PORT_CONFIGURATION_INFORMATION_NT {
// Fields added to allow for the miniport
// to update these sizes based on requirements
// for large transfers ( > 64K);
ULONG DeviceExtensionSize;
ULONG SpecificLuExtensionSize;
ULONG SrbExtensionSize;
} PORT_CONFIGURATION_INFORMATION_NT, *PPORT_CONFIGURATION_INFORMATION_NT;
typedef struct _PORT_CONFIGURATION_INFORMATION_2K {
// Used to determine whether the system and/or the miniport support
// 64-bit physical addresses. See SCSI_DMA64_* flags below.
UCHAR Dma64BitAddresses;
// Indicates that the miniport can accept a SRB_FUNCTION_RESET_DEVICE
// to clear all requests to a particular LUN.
BOOLEAN ResetTargetSupported;
// Indicates that the miniport can support more than 8 logical units per
// target (maximum LUN number is one less than this field).
UCHAR MaximumNumberOfLogicalUnits;
// Supports WMI?
BOOLEAN WmiDataProvider;
} PORT_CONFIGURATION_INFORMATION_2K, *PPORT_CONFIGURATION_INFORMATION_2K;
typedef struct _PORT_CONFIGURATION_INFORMATION_COMMON {
PORT_CONFIGURATION_INFORMATION comm;
PORT_CONFIGURATION_INFORMATION_NT nt4;
PORT_CONFIGURATION_INFORMATION_2K w2k;
} PORT_CONFIGURATION_INFORMATION_COMMON, *PPORT_CONFIGURATION_INFORMATION_COMMON;
//
// Version control for ConfigInfo structure.
//
#define CONFIG_INFO_VERSION_2 sizeof(PORT_CONFIGURATION_INFORMATION)
//
// Flags for controlling 64-bit DMA use (PORT_CONFIGURATION_INFORMATION field
// Dma64BitAddresses)
//
//
// Set by scsiport on entering HwFindAdapter if the system can support 64-bit
// physical addresses. The miniport can use this information before calling
// ScsiPortGetUncachedExtension to modify the DeviceExtensionSize,
// SpecificLuExtensionSize & SrbExtensionSize fields to account for the extra
// size of the scatter gather list.
//
#define SCSI_DMA64_SYSTEM_SUPPORTED 0x80
//
// Set by the miniport before calling ScsiPortGetUncachedExtension to indicate
// that scsiport should provide it with 64-bit physical addresses. If the
// system does not support 64-bit PA's then this bit will be ignored.
//
#define SCSI_DMA64_MINIPORT_SUPPORTED 0x01
//
// Command type (and parameter) definition(s) for AdapterControl requests.
//
typedef enum _SCSI_ADAPTER_CONTROL_TYPE {
ScsiQuerySupportedControlTypes = 0,
ScsiStopAdapter,
ScsiRestartAdapter,
ScsiSetBootConfig,
ScsiSetRunningConfig,
ScsiAdapterControlMax,
MakeAdapterControlTypeSizeOfUlong = 0xffffffff
} SCSI_ADAPTER_CONTROL_TYPE, *PSCSI_ADAPTER_CONTROL_TYPE;
//
// Adapter control status values
//
typedef enum _SCSI_ADAPTER_CONTROL_STATUS {
ScsiAdapterControlSuccess = 0,
ScsiAdapterControlUnsuccessful
} SCSI_ADAPTER_CONTROL_STATUS, *PSCSI_ADAPTER_CONTROL_STATUS;
//
// Parameters for Adapter Control Functions:
//
//
// ScsiQuerySupportedControlTypes:
//
#pragma warning(disable:4200)
typedef struct _SCSI_SUPPORTED_CONTROL_TYPE_LIST {
//
// Specifies the number of entries in the adapter control type list.
//
IN ULONG MaxControlType;
//
// The miniport will set TRUE for each control type it supports.
// The number of entries in this array is defined by MaxAdapterControlType
// - the miniport must not attempt to set any AC types beyond the maximum
// value specified.
//
OUT BOOLEAN SupportedTypeList[0];
} SCSI_SUPPORTED_CONTROL_TYPE_LIST, *PSCSI_SUPPORTED_CONTROL_TYPE_LIST;
#pragma warning(default:4200)
//
// Uninitialized flag value.
//
#define SP_UNINITIALIZED_VALUE ((ULONG) ~0)
#define SP_UNTAGGED ((UCHAR) ~0)
//
// Set asynchronous events.
//
#define SRBEV_BUS_RESET 0x0001
#define SRBEV_SCSI_ASYNC_NOTIFICATION 0x0002
// begin_ntminitape
//
// SCSI I/O Request Block
//
typedef struct _SCSI_REQUEST_BLOCK {
USHORT Length; // offset 0
UCHAR Function; // offset 2
UCHAR SrbStatus; // offset 3
UCHAR ScsiStatus; // offset 4
UCHAR PathId; // offset 5
UCHAR TargetId; // offset 6
UCHAR Lun; // offset 7
UCHAR QueueTag; // offset 8
UCHAR QueueAction; // offset 9
UCHAR CdbLength; // offset a
UCHAR SenseInfoBufferLength; // offset b
ULONG SrbFlags; // offset c
ULONG DataTransferLength; // offset 10
ULONG TimeOutValue; // offset 14
PVOID DataBuffer; // offset 18
PVOID SenseInfoBuffer; // offset 1c
struct _SCSI_REQUEST_BLOCK *NextSrb; // offset 20
PVOID OriginalRequest; // offset 24
PVOID SrbExtension; // offset 28
union {
ULONG InternalStatus; // offset 2c
ULONG QueueSortKey; // offset 2c
};
#if defined(_WIN64)
// Force PVOID alignment of Cdb
ULONG Reserved;
#endif
UCHAR Cdb[16]; // offset 30
} SCSI_REQUEST_BLOCK, *PSCSI_REQUEST_BLOCK;
#define SCSI_REQUEST_BLOCK_SIZE sizeof(SCSI_REQUEST_BLOCK)
//
// SCSI I/O Request Block for WMI Requests
//
typedef struct _SCSI_WMI_REQUEST_BLOCK {
USHORT Length;
UCHAR Function; // SRB_FUNCTION_WMI
UCHAR SrbStatus;
UCHAR WMISubFunction;
UCHAR PathId; // If SRB_WMI_FLAGS_ADAPTER_REQUEST is set in
UCHAR TargetId; // WMIFlags then PathId, TargetId and Lun are
UCHAR Lun; // reserved fields.
UCHAR Reserved1;
UCHAR WMIFlags;
UCHAR Reserved2[2];
ULONG SrbFlags;
ULONG DataTransferLength;
ULONG TimeOutValue;
PVOID DataBuffer;
PVOID DataPath;
PVOID Reserved3;
PVOID OriginalRequest;
PVOID SrbExtension;
ULONG Reserved4;
UCHAR Reserved5[16];
} SCSI_WMI_REQUEST_BLOCK, *PSCSI_WMI_REQUEST_BLOCK;
//
// SRB Functions
//
#define SRB_FUNCTION_EXECUTE_SCSI 0x00
#define SRB_FUNCTION_CLAIM_DEVICE 0x01
#define SRB_FUNCTION_IO_CONTROL 0x02
#define SRB_FUNCTION_RECEIVE_EVENT 0x03
#define SRB_FUNCTION_RELEASE_QUEUE 0x04
#define SRB_FUNCTION_ATTACH_DEVICE 0x05
#define SRB_FUNCTION_RELEASE_DEVICE 0x06
#define SRB_FUNCTION_SHUTDOWN 0x07
#define SRB_FUNCTION_FLUSH 0x08
#define SRB_FUNCTION_ABORT_COMMAND 0x10
#define SRB_FUNCTION_RELEASE_RECOVERY 0x11
#define SRB_FUNCTION_RESET_BUS 0x12
#define SRB_FUNCTION_RESET_DEVICE 0x13
#define SRB_FUNCTION_TERMINATE_IO 0x14
#define SRB_FUNCTION_FLUSH_QUEUE 0x15
#define SRB_FUNCTION_REMOVE_DEVICE 0x16
#define SRB_FUNCTION_WMI 0x17
#define SRB_FUNCTION_LOCK_QUEUE 0x18
#define SRB_FUNCTION_UNLOCK_QUEUE 0x19
#define SRB_FUNCTION_RESET_LOGICAL_UNIT 0x20
//
// SRB Status
//
#define SRB_STATUS_PENDING 0x00
#define SRB_STATUS_SUCCESS 0x01
#define SRB_STATUS_ABORTED 0x02
#define SRB_STATUS_ABORT_FAILED 0x03
#define SRB_STATUS_ERROR 0x04
#define SRB_STATUS_BUSY 0x05
#define SRB_STATUS_INVALID_REQUEST 0x06
#define SRB_STATUS_INVALID_PATH_ID 0x07
#define SRB_STATUS_NO_DEVICE 0x08
#define SRB_STATUS_TIMEOUT 0x09
#define SRB_STATUS_SELECTION_TIMEOUT 0x0A
#define SRB_STATUS_COMMAND_TIMEOUT 0x0B
#define SRB_STATUS_MESSAGE_REJECTED 0x0D
#define SRB_STATUS_BUS_RESET 0x0E
#define SRB_STATUS_PARITY_ERROR 0x0F
#define SRB_STATUS_REQUEST_SENSE_FAILED 0x10
#define SRB_STATUS_NO_HBA 0x11
#define SRB_STATUS_DATA_OVERRUN 0x12
#define SRB_STATUS_UNEXPECTED_BUS_FREE 0x13
#define SRB_STATUS_PHASE_SEQUENCE_FAILURE 0x14
#define SRB_STATUS_BAD_SRB_BLOCK_LENGTH 0x15
#define SRB_STATUS_REQUEST_FLUSHED 0x16
#define SRB_STATUS_INVALID_LUN 0x20
#define SRB_STATUS_INVALID_TARGET_ID 0x21
#define SRB_STATUS_BAD_FUNCTION 0x22
#define SRB_STATUS_ERROR_RECOVERY 0x23
#define SRB_STATUS_NOT_POWERED 0x24
//
// This value is used by the port driver to indicate that a non-scsi-related
// error occured. Miniports must never return this status.
//
#define SRB_STATUS_INTERNAL_ERROR 0x30
//
// Srb status values 0x38 through 0x3f are reserved for internal port driver
// use.
//
//
// SRB Status Masks
//
#define SRB_STATUS_QUEUE_FROZEN 0x40
#define SRB_STATUS_AUTOSENSE_VALID 0x80
#define SRB_STATUS(Status) (Status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
//
// SRB Flag Bits
//
#define SRB_FLAGS_QUEUE_ACTION_ENABLE 0x00000002
#define SRB_FLAGS_DISABLE_DISCONNECT 0x00000004
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER 0x00000008
#define SRB_FLAGS_BYPASS_FROZEN_QUEUE 0x00000010
#define SRB_FLAGS_DISABLE_AUTOSENSE 0x00000020
#define SRB_FLAGS_DATA_IN 0x00000040
#define SRB_FLAGS_DATA_OUT 0x00000080
#define SRB_FLAGS_NO_DATA_TRANSFER 0x00000000
#define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)
#define SRB_FLAGS_NO_QUEUE_FREEZE 0x00000100
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE 0x00000200
#define SRB_FLAGS_FREE_SENSE_BUFFER 0x00000400
#define SRB_FLAGS_IS_ACTIVE 0x00010000
#define SRB_FLAGS_ALLOCATED_FROM_ZONE 0x00020000
#define SRB_FLAGS_SGLIST_FROM_POOL 0x00040000
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE 0x00080000
#define SRB_FLAGS_NO_KEEP_AWAKE 0x00100000
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE 0x00200000
#define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT 0x00400000
#define SRB_FLAGS_DONT_START_NEXT_PACKET 0x00800000
#define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000
#define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000
//
// Queue Action
//
#define SRB_SIMPLE_TAG_REQUEST 0x20
#define SRB_HEAD_OF_QUEUE_TAG_REQUEST 0x21
#define SRB_ORDERED_QUEUE_TAG_REQUEST 0x22
#define SRB_WMI_FLAGS_ADAPTER_REQUEST 0x01
// end_ntminitape
//
// SCSI Adapter Dependent Routines
//
typedef
BOOLEAN
(*PHW_INITIALIZE) (
IN PVOID DeviceExtension
);
typedef
BOOLEAN
(*PHW_STARTIO) (
IN PVOID DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
typedef
BOOLEAN
(*PHW_INTERRUPT) (
IN PVOID DeviceExtension
);
typedef
VOID
(*PHW_TIMER) (
IN PVOID DeviceExtension
);
typedef
VOID
(*PHW_DMA_STARTED) (
IN PVOID DeviceExtension
);
typedef
ULONG
(*PHW_FIND_ADAPTER) (
IN PVOID DeviceExtension,
IN PVOID HwContext,
IN PVOID BusInformation,
IN PCHAR ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
OUT PBOOLEAN Again
);
typedef
BOOLEAN
(*PHW_RESET_BUS) (
IN PVOID DeviceExtension,
IN ULONG PathId
);
typedef
BOOLEAN
(*PHW_ADAPTER_STATE) (
IN PVOID DeviceExtension,
IN PVOID Context,
IN BOOLEAN SaveState
);
typedef
SCSI_ADAPTER_CONTROL_STATUS
(*PHW_ADAPTER_CONTROL) (
IN PVOID DeviceExtension,
IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
IN PVOID Parameters
);
//
// Port driver error codes
//
#define SP_BUS_PARITY_ERROR 0x0001
#define SP_UNEXPECTED_DISCONNECT 0x0002
#define SP_INVALID_RESELECTION 0x0003
#define SP_BUS_TIME_OUT 0x0004
#define SP_PROTOCOL_ERROR 0x0005
#define SP_INTERNAL_ADAPTER_ERROR 0x0006
#define SP_REQUEST_TIMEOUT 0x0007
#define SP_IRQ_NOT_RESPONDING 0x0008
#define SP_BAD_FW_WARNING 0x0009
#define SP_BAD_FW_ERROR 0x000a
#define SP_LOST_WMI_MINIPORT_REQUEST 0x000b
//
// Return values for SCSI_HW_FIND_ADAPTER.
//
#define SP_RETURN_NOT_FOUND 0
#define SP_RETURN_FOUND 1
#define SP_RETURN_ERROR 2
#define SP_RETURN_BAD_CONFIG 3
//
// Notification Event Types
//
typedef enum _SCSI_NOTIFICATION_TYPE {
RequestComplete,
NextRequest,
NextLuRequest,
ResetDetected,
CallDisableInterrupts,
CallEnableInterrupts,
RequestTimerCall,
BusChangeDetected, /* New */
WMIEvent,
WMIReregister
} SCSI_NOTIFICATION_TYPE, *PSCSI_NOTIFICATION_TYPE;
//
// Structure passed between miniport initialization
// and SCSI port initialization
//
typedef struct _HW_INITIALIZATION_DATA {
ULONG HwInitializationDataSize;
// Adapter interface type:
//
// Internal
// Isa
// Eisa
// MicroChannel
// TurboChannel
// PCIBus
// VMEBus
// NuBus
// PCMCIABus
// CBus
// MPIBus
// MPSABus
INTERFACE_TYPE AdapterInterfaceType;
// Miniport driver routines
PHW_INITIALIZE HwInitialize;
PHW_STARTIO HwStartIo;
PHW_INTERRUPT HwInterrupt;
PHW_FIND_ADAPTER HwFindAdapter;
PHW_RESET_BUS HwResetBus;
PHW_DMA_STARTED HwDmaStarted;
PHW_ADAPTER_STATE HwAdapterState;
ULONG DeviceExtensionSize;
ULONG SpecificLuExtensionSize;
ULONG SrbExtensionSize;
ULONG NumberOfAccessRanges;
PVOID Reserved;
BOOLEAN MapBuffers; // Data buffers must be mapped into virtual address space.
BOOLEAN NeedPhysicalAddresses; // We need to tranlate virtual to physical addresses.
BOOLEAN TaggedQueuing; // Supports tagged queuing
BOOLEAN AutoRequestSense; // Supports auto request sense.
BOOLEAN MultipleRequestPerLu; // Supports multiple requests per logical unit.
BOOLEAN ReceiveEvent; // Support receive event function.
USHORT VendorIdLength; // Vendor identification length
PVOID VendorId; // Vendor identification
USHORT ReservedUshort; // Pad for alignment and future use.
USHORT DeviceIdLength; // Device identification length
PVOID DeviceId; // Device identification
} HW_INITIALIZATION_DATA, *PHW_INITIALIZATION_DATA;
typedef struct _HW_INITIALIZATION_DATA_2K {
// Stop adapter routine.
PHW_ADAPTER_CONTROL HwAdapterControl;
} HW_INITIALIZATION_DATA_2K, *PHW_INITIALIZATION_DATA_2K;
typedef struct _HW_INITIALIZATION_DATA_COMMON {
HW_INITIALIZATION_DATA comm;
HW_INITIALIZATION_DATA_2K w2k;
}HW_INITIALIZATION_DATA_COMMON, *PHW_INITIALIZATION_DATA_COMMON;
// begin_ntminitape
#ifndef _NTDDK_
#define SCSIPORT_API DECLSPEC_IMPORT
#else
#define SCSIPORT_API
#endif
// end_ntminitape
//
// Port driver routines called by miniport driver
//
SCSIPORT_API
ULONG
ScsiPortInitialize(
IN PVOID Argument1,
IN PVOID Argument2,
IN struct _HW_INITIALIZATION_DATA *HwInitializationData,
IN PVOID HwContext
);
SCSIPORT_API
VOID
ScsiPortFreeDeviceBase(
IN PVOID HwDeviceExtension,
IN PVOID MappedAddress
);
SCSIPORT_API
ULONG
ScsiPortGetBusData(
IN PVOID DeviceExtension,
IN ULONG BusDataType,
IN ULONG SystemIoBusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Length
);
SCSIPORT_API
ULONG
ScsiPortSetBusDataByOffset(
IN PVOID DeviceExtension,
IN ULONG BusDataType,
IN ULONG SystemIoBusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
);
SCSIPORT_API
PVOID
ScsiPortGetDeviceBase(
IN PVOID HwDeviceExtension,
IN INTERFACE_TYPE BusType,
IN ULONG SystemIoBusNumber,
IN SCSI_PHYSICAL_ADDRESS IoAddress,
IN ULONG NumberOfBytes,
IN BOOLEAN InIoSpace
);
SCSIPORT_API
PVOID
ScsiPortGetLogicalUnit(
IN PVOID HwDeviceExtension,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun
);
SCSIPORT_API
PSCSI_REQUEST_BLOCK
ScsiPortGetSrb(
IN PVOID DeviceExtension,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun,
IN LONG QueueTag
);
SCSIPORT_API
SCSI_PHYSICAL_ADDRESS
ScsiPortGetPhysicalAddress(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
IN PVOID VirtualAddress,
OUT ULONG *Length
);
SCSIPORT_API
PVOID
ScsiPortGetVirtualAddress(
IN PVOID HwDeviceExtension,
IN SCSI_PHYSICAL_ADDRESS PhysicalAddress
);
SCSIPORT_API
PVOID
ScsiPortGetUncachedExtension(
IN PVOID HwDeviceExtension,
IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
IN ULONG NumberOfBytes
);
SCSIPORT_API
VOID
ScsiPortFlushDma(
IN PVOID DeviceExtension
);
SCSIPORT_API
VOID
ScsiPortIoMapTransfer(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
IN PVOID LogicalAddress,
IN ULONG Length
);
SCSIPORT_API
VOID
ScsiPortNotification(
IN SCSI_NOTIFICATION_TYPE NotificationType,
IN PVOID HwDeviceExtension,
...
);
SCSIPORT_API
VOID
ScsiPortLogError(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun,
IN ULONG ErrorCode,
IN ULONG UniqueId
);
SCSIPORT_API
VOID
ScsiPortCompleteRequest(
IN PVOID HwDeviceExtension,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun,
IN UCHAR SrbStatus
);
SCSIPORT_API
VOID
ScsiPortMoveMemory(
IN PVOID WriteBuffer,
IN PVOID ReadBuffer,
IN ULONG Length
);
SCSIPORT_API
UCHAR
ScsiPortReadPortUchar(
IN PUCHAR Port
);
SCSIPORT_API
USHORT
ScsiPortReadPortUshort(
IN PUSHORT Port
);
SCSIPORT_API
ULONG
ScsiPortReadPortUlong(
IN PULONG Port
);
SCSIPORT_API
VOID
ScsiPortReadPortBufferUchar(
IN PUCHAR Port,
IN PUCHAR Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortReadPortBufferUshort(
IN PUSHORT Port,
IN PUSHORT Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortReadPortBufferUlong(
IN PULONG Port,
IN PULONG Buffer,
IN ULONG Count
);
SCSIPORT_API
UCHAR
ScsiPortReadRegisterUchar(
IN PUCHAR Register
);
SCSIPORT_API
USHORT
ScsiPortReadRegisterUshort(
IN PUSHORT Register
);
SCSIPORT_API
ULONG
ScsiPortReadRegisterUlong(
IN PULONG Register
);
SCSIPORT_API
VOID
ScsiPortReadRegisterBufferUchar(
IN PUCHAR Register,
IN PUCHAR Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortReadRegisterBufferUshort(
IN PUSHORT Register,
IN PUSHORT Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortReadRegisterBufferUlong(
IN PULONG Register,
IN PULONG Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortStallExecution(
IN ULONG Delay
);
SCSIPORT_API
VOID
ScsiPortWritePortUchar(
IN PUCHAR Port,
IN UCHAR Value
);
SCSIPORT_API
VOID
ScsiPortWritePortUshort(
IN PUSHORT Port,
IN USHORT Value
);
SCSIPORT_API
VOID
ScsiPortWritePortUlong(
IN PULONG Port,
IN ULONG Value
);
SCSIPORT_API
VOID
ScsiPortWritePortBufferUchar(
IN PUCHAR Port,
IN PUCHAR Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortWritePortBufferUshort(
IN PUSHORT Port,
IN PUSHORT Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortWritePortBufferUlong(
IN PULONG Port,
IN PULONG Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortWriteRegisterUchar(
IN PUCHAR Register,
IN UCHAR Value
);
SCSIPORT_API
VOID
ScsiPortWriteRegisterUshort(
IN PUSHORT Register,
IN USHORT Value
);
SCSIPORT_API
VOID
ScsiPortWriteRegisterUlong(
IN PULONG Register,
IN ULONG Value
);
SCSIPORT_API
VOID
ScsiPortWriteRegisterBufferUchar(
IN PUCHAR Register,
IN PUCHAR Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortWriteRegisterBufferUshort(
IN PUSHORT Register,
IN PUSHORT Buffer,
IN ULONG Count
);
SCSIPORT_API
VOID
ScsiPortWriteRegisterBufferUlong(
IN PULONG Register,
IN PULONG Buffer,
IN ULONG Count
);
SCSIPORT_API
SCSI_PHYSICAL_ADDRESS
ScsiPortConvertUlongToPhysicalAddress(
ULONG UlongAddress
);
SCSIPORT_API
ULONG
ScsiPortConvertPhysicalAddressToUlong(
SCSI_PHYSICAL_ADDRESS Address
);
#define ScsiPortConvertPhysicalAddressToUlong(Address) ((Address).LowPart)
SCSIPORT_API
BOOLEAN
ScsiPortValidateRange(
IN PVOID HwDeviceExtension,
IN INTERFACE_TYPE BusType,
IN ULONG SystemIoBusNumber,
IN SCSI_PHYSICAL_ADDRESS IoAddress,
IN ULONG NumberOfBytes,
IN BOOLEAN InIoSpace
);
// begin_ntminitape
SCSIPORT_API
VOID
ScsiDebugPrint(
ULONG DebugPrintLevel,
PCCHAR DebugMessage,
...
);
// end_ntminitape
#endif //USER_MODE
#endif //

View file

@ -0,0 +1 @@
#include "stdafx.h"

View file

@ -0,0 +1,25 @@
extern "C" {
#include <ntddk.h>
};
#include "stddef.h"
#include "stdarg.h"
#include "inc\CrossNt.h"
#include "atapi.h" // includes scsi.h
#include "ntdddisk.h"
#include "ntddscsi.h"
#include "bsmaster.h"
#include "uniata_ver.h"
#include "id_sata.h"
#ifndef UNIATA_CORE
#include "id_queue.h"
#endif //UNIATA_CORE
#include "badblock.h"

View file

@ -0,0 +1,375 @@
/*++
Copyright (c) 2002-2005 Alexandr A. Telyatnikov (Alter)
Module Name:
tools.h
Abstract:
This header contains some useful definitions for data manipulation.
Author:
Alexander A. Telyatnikov (Alter)
Environment:
kernel mode only
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:
--*/
#ifndef __TOOLS_H__
#define __TOOLS_H__
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
//----------------
#ifndef USER_MODE
#include <ntddk.h> // various NT definitions
#endif //USER_MODE
//----------------
#ifndef FOUR_BYTE_DEFINED
#define FOUR_BYTE_DEFINED
typedef struct _FOUR_BYTE {
UCHAR Byte0;
UCHAR Byte1;
UCHAR Byte2;
UCHAR Byte3;
} FOUR_BYTE, *PFOUR_BYTE;
#endif //FOUR_BYTE_DEFINED
#ifdef _DEBUG
#ifndef DBG
#define DBG
#endif // DBG
#else // _DEBUG
#ifdef DBG
#undef DBG
#endif // DBG
#endif // _DEBUG
// This macro has the effect of Bit = log2(Data)
#define WHICH_BIT(Data, Bit) { \
for (Bit = 0; Bit < 32; Bit++) { \
if ((Data >> Bit) == 1) { \
break; \
} \
} \
}
#define PAGE_MASK (PAGE_SIZE-1)
#define ntohs(x) ( (((USHORT)x[0])<<8) | x[1] )
#define PLAY_ACTIVE(DeviceExtension) (((PCDROM_DATA)(DeviceExtension + 1))->PlayActive)
#define MSF_TO_LBA(Minutes,Seconds,Frames) \
(ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))
#define LBA_TO_MSF(Lba,Minutes,Seconds,Frames) \
{ \
(Minutes) = (UCHAR)(Lba / (60 * 75)); \
(Seconds) = (UCHAR)((Lba % (60 * 75)) / 75); \
(Frames) = (UCHAR)((Lba % (60 * 75)) % 75); \
}
#define DEC_TO_BCD(x) (((x / 10) << 4) + (x % 10))
/*
#if defined _X86_ && !defined(__GNUC__)
#define MOV_DD_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm mov eax,[ebx] \
__asm bswap eax \
__asm mov ebx,_to_ \
__asm mov [ebx],eax \
}
#define MOV_DW_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm mov ax,[ebx] \
__asm rol ax,8 \
__asm mov ebx,_to_ \
__asm mov [ebx],ax \
}
#define REVERSE_DD(a) { \
PFOUR_BYTE _from_; \
_from_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm mov eax,[ebx] \
__asm bswap eax \
__asm mov [ebx],eax \
}
#define REVERSE_DW(a) { \
PFOUR_BYTE _from_; \
_from_ = ((PFOUR_BYTE)&(a)); \
__asm mov eax,_from_ \
__asm rol word ptr [eax],8 \
}
#define MOV_DW2DD_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm mov ax,[ebx] \
__asm rol ax,8 \
__asm mov ebx,_to_ \
__asm mov [ebx+2],ax \
__asm mov [ebx],0 \
}
#define MOV_SWP_DW2DD(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm xor eax,eax \
__asm mov ax,[ebx] \
__asm rol ax,8 \
__asm mov ebx,_to_ \
__asm mov [ebx],eax \
}
#define MOV_MSF(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm mov eax,[ebx] \
__asm mov ebx,_to_ \
__asm mov [ebx],ax \
__asm shr eax,16 \
__asm mov [ebx+2],al \
}
#define MOV_MSF_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
__asm mov ebx,_from_ \
__asm mov eax,[ebx] \
__asm mov ebx,_to_ \
__asm mov [ebx+2],al \
__asm bswap eax \
__asm shr eax,8 \
__asm mov [ebx],ax \
}
#define XCHG_DD(a,b) \
{ \
PULONG _from_, _to_; \
_from_ = ((PULONG)&(b)); \
_to_ = ((PULONG)&(a)); \
__asm mov ebx,_from_ \
__asm mov ecx,_to_ \
__asm mov eax,[ebx] \
__asm xchg eax,[ecx] \
__asm mov [ebx],eax \
}
#else // NO X86 optimization , use generic C/C++
#define MOV_DD_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
_to_->Byte0 = _from_->Byte3; \
_to_->Byte1 = _from_->Byte2; \
_to_->Byte2 = _from_->Byte1; \
_to_->Byte3 = _from_->Byte0; \
}
#define MOV_DW_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
_to_->Byte0 = _from_->Byte1; \
_to_->Byte1 = _from_->Byte0; \
}
#define REVERSE_DD(a) { \
ULONG _i_; \
MOV_DD_SWP(_i_,(a)); \
*((PULONG)&(a)) = _i_; \
}
#define REVERSE_DW(a) { \
USHORT _i_; \
MOV_DW_SWP(_i_,(a)); \
*((PUSHORT)&(a)) = _i_; \
}
#define MOV_DW2DD_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
*((PUSHORT)_to_) = 0; \
_to_->Byte2 = _from_->Byte1; \
_to_->Byte3 = _from_->Byte0; \
}
#define MOV_MSF(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
_to_->Byte0 = _from_->Byte0; \
_to_->Byte1 = _from_->Byte1; \
_to_->Byte2 = _from_->Byte2; \
}
#define MOV_MSF_SWP(a,b) \
{ \
PFOUR_BYTE _from_, _to_; \
_from_ = ((PFOUR_BYTE)&(b)); \
_to_ = ((PFOUR_BYTE)&(a)); \
_to_->Byte0 = _from_->Byte2; \
_to_->Byte1 = _from_->Byte1; \
_to_->Byte2 = _from_->Byte0; \
}
#define XCHG_DD(a,b) \
{ \
ULONG _temp_; \
PULONG _from_, _to_; \
_from_ = ((PULONG)&(b)); \
_to_ = ((PULONG)&(a)); \
_temp_ = *_from_; \
*_from_ = *_to_; \
*_to_ = _temp_; \
}
#endif // _X86_
#define MOV_3B_SWP(a,b) MOV_MSF_SWP(a,b)
*/
#ifdef DBG
#define KdDump(a,b) \
if((a)!=NULL) { \
ULONG i; \
for(i=0; i<(b); i++) { \
ULONG c; \
c = (ULONG)(*(((PUCHAR)(a))+i)); \
KdPrint(("%2.2x ",c)); \
if ((i & 0x0f) == 0x0f) KdPrint(("\n")); \
} \
KdPrint(("\n")); \
}
#define BrutePoint() {}
#define DbgAllocatePool(x,y) ExAllocatePool(x,y)
#define DbgFreePool(x) ExFreePool(x)
#define DbgAllocatePoolWithTag(a,b,c) ExAllocatePoolWithTag(a,b,c)
#else
#define KdDump(a,b) {}
#define DbgAllocatePool(x,y) ExAllocatePool(x,y)
#define DbgFreePool(x) ExFreePool(x)
#define DbgAllocatePoolWithTag(a,b,c) ExAllocatePoolWithTag(a,b,c)
#define BrutePoint() {}
#endif //DBG
#define WAIT_FOR_XXX_EMU_DELAY DEF_I64(5000000) // 0.5 s
// neat little hacks to count number of bits set efficiently
__inline ULONG CountOfSetBitsUChar(UCHAR _X)
{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
__inline ULONG CountOfSetBitsULong(ULONG _X)
{ ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif //max
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif //min
//#define abs(a) (((a) < 0) ? (-(a)) : (a))
/*
extern ULONG MajorVersion;
extern ULONG MinorVersion;
extern ULONG BuildNumber;
extern ULONG SPVersion;
*/
#ifdef __cplusplus
};
#endif //__cplusplus
#ifndef USER_MODE
extern UNICODE_STRING SavedSPString;
#endif //USER_MODE
/*
#define WinVer_Is351 (MajorVersion==0x03)
#define WinVer_IsNT (MajorVersion==0x04)
#define WinVer_Is2k (MajorVersion==0x05 && MinorVersion==0x00)
#define WinVer_IsXP (MajorVersion==0x05 && MinorVersion==0x01)
#define WinVer_IsdNET (MajorVersion==0x05 && MinorVersion==0x02)
#define WinVer_Id() ((MajorVersion << 8) | MinorVersion)
#define WinVer_351 (0x0351)
#define WinVer_NT (0x0400)
#define WinVer_2k (0x0500)
#define WinVer_XP (0x0501)
#define WinVer_dNET (0x0502)
*/
#define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
#ifndef offsetof
#define offsetof(type, field) (ULONG)&(((type *)0)->field)
#endif //offsetof
#endif // __TOOLS_H__

View file

@ -0,0 +1,229 @@
/*++
Copyright (c) 2004-2005 Alexandr A. Telyatnikov (Alter)
Module Name:
uata_ctl.h
Abstract:
This header contains definitions for private UniATA SRB_IOCTL.
Author:
Alexander A. Telyatnikov (Alter)
Environment:
kernel mode only
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:
--*/
#ifndef __UNIATA_IO_CONTROL_CODES__H__
#define __UNIATA_IO_CONTROL_CODES__H__
//#include "scsi.h"
#pragma pack(push, 8)
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
#define AHCI_MAX_PORT 32
#define IDE_MAX_CHAN 8
// Thanks to SATA Port Multipliers:
#define IDE_MAX_LUN_PER_CHAN 16
#define IDE_MAX_LUN (AHCI_MAX_PORT*IDE_MAX_LUN_PER_CHAN)
#define MAX_QUEUE_STAT 8
#ifndef UNIATA_CORE
#define IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES ((FILE_DEVICE_SCSI << 16) + 0x09a0)
#define IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE ((FILE_DEVICE_SCSI << 16) + 0x09a1)
#define IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE ((FILE_DEVICE_SCSI << 16) + 0x09a2)
#define IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE ((FILE_DEVICE_SCSI << 16) + 0x09a3)
#define IOCTL_SCSI_MINIPORT_UNIATA_ADAPTER_INFO ((FILE_DEVICE_SCSI << 16) + 0x09a4)
//#define IOCTL_SCSI_MINIPORT_UNIATA_LUN_IDENT ((FILE_DEVICE_SCSI << 16) + 0x09a5) -> IOCTL_SCSI_MINIPORT_IDENTIFY
#define IOCTL_SCSI_MINIPORT_UNIATA_RESETBB ((FILE_DEVICE_SCSI << 16) + 0x09a5)
#define IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE ((FILE_DEVICE_SCSI << 16) + 0x09a6)
#define IOCTL_SCSI_MINIPORT_UNIATA_REG_IO ((FILE_DEVICE_SCSI << 16) + 0x09a7)
typedef struct _ADDREMOVEDEV {
ULONG WaitForPhysicalLink; // us
} ADDREMOVEDEV, *PADDREMOVEDEV;
typedef struct _SETTRANSFERMODE {
ULONG MaxMode;
ULONG OrigMode;
BOOLEAN ApplyImmediately;
UCHAR Reserved[3];
} SETTRANSFERMODE, *PSETTRANSFERMODE;
typedef struct _GETTRANSFERMODE {
ULONG MaxMode;
ULONG OrigMode;
ULONG CurrentMode;
ULONG Reserved;
} GETTRANSFERMODE, *PGETTRANSFERMODE;
typedef struct _CHANINFO {
ULONG MaxTransferMode; // may differ from Controller's value due to 40-pin cable
ULONG ChannelCtrlFlags;
//#ifdef QUEUE_STATISTICS
LONGLONG QueueStat[MAX_QUEUE_STAT];
LONGLONG ReorderCount;
LONGLONG IntersectCount;
LONGLONG TryReorderCount;
LONGLONG TryReorderHeadCount;
LONGLONG TryReorderTailCount; /* in-order requests */
//#endif //QUEUE_STATISTICS
} CHANINFO, *PCHANINFO;
typedef struct _ADAPTERINFO {
// Device identification
ULONG HeaderLength;
ULONG DevID;
ULONG RevID;
ULONG slotNumber;
ULONG SystemIoBusNumber;
ULONG DevIndex;
ULONG Channel;
ULONG HbaCtrlFlags;
BOOLEAN simplexOnly;
BOOLEAN MemIo;
BOOLEAN UnknownDev;
BOOLEAN MasterDev;
ULONG MaxTransferMode;
ULONG HwFlags;
ULONG OrigAdapterInterfaceType;
CHAR DeviceName[64];
ULONG BusInterruptLevel; // Interrupt level
ULONG InterruptMode; // Interrupt Mode (Level or Edge)
ULONG BusInterruptVector;
// Number of channels being supported by one instantiation
// of the device extension. Normally (and correctly) one, but
// with so many broken PCI IDE controllers being sold, we have
// to support them.
ULONG NumberChannels;
BOOLEAN ChanInfoValid;
CHANINFO Chan[AHCI_MAX_PORT];
} ADAPTERINFO, *PADAPTERINFO;
#ifndef ATA_FLAGS_DRDY_REQUIRED
//The ATA_PASS_THROUGH_DIRECT structure is used in conjunction with an IOCTL_ATA_PASS_THROUGH_DIRECT request to instruct the port driver to send an embedded ATA command to the target device.
typedef struct _ATA_PASS_THROUGH_DIRECT {
USHORT Length;
USHORT AtaFlags;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR ReservedAsUchar;
ULONG DataTransferLength;
ULONG TimeOutValue;
ULONG ReservedAsUlong;
PVOID DataBuffer;
UCHAR PreviousTaskFile[8];
UCHAR CurrentTaskFile[8];
} ATA_PASS_THROUGH_DIRECT, *PATA_PASS_THROUGH_DIRECT;
#define ATA_FLAGS_DRDY_REQUIRED 0x01 // Wait for DRDY status from the device before sending the command to the device.
#define ATA_FLAGS_DATA_OUT 0x02 // Write data to the device.
#define ATA_FLAGS_DATA_IN 0x04 // Read data from the device.
#define ATA_FLAGS_48BIT_COMMAND 0x08 // The ATA command to be send uses the 48 bit LBA feature set.
// When this flag is set, the contents of the PreviousTaskFile member in the
// ATA_PASS_THROUGH_DIRECT structure should be valid.
#endif //ATA_FLAGS_DRDY_REQUIRED
#pragma pack(1)
typedef struct _IDEREGS_EX {
UCHAR bFeaturesReg; // Used for specifying SMART "commands".
UCHAR bSectorCountReg; // IDE sector count register
UCHAR bSectorNumberReg; // IDE sector number register
UCHAR bCylLowReg; // IDE low order cylinder value
UCHAR bCylHighReg; // IDE high order cylinder value
UCHAR bDriveHeadReg; // IDE drive/head register
UCHAR bCommandReg; // Actual IDE command.
UCHAR bOpFlags; // 00 - send
// 01 - read regs
// 08 - lba48
// 10 - treat timeout as msec
#define UNIATA_SPTI_EX_SND 0x00
#define UNIATA_SPTI_EX_RCV 0x01
#define UNIATA_SPTI_EX_LBA48 0x08
#define UNIATA_SPTI_EX_SPEC_TO 0x10
//#define UNIATA_SPTI_EX_FREEZE_TO 0x20 // do not reset device on timeout and keep interrupts disabled
UCHAR bFeaturesRegH; // feature (high part for LBA48 mode)
UCHAR bSectorCountRegH; // IDE sector count register (high part for LBA48 mode)
UCHAR bSectorNumberRegH; // IDE sector number register (high part for LBA48 mode)
UCHAR bCylLowRegH; // IDE low order cylinder value (high part for LBA48 mode)
UCHAR bCylHighRegH; // IDE high order cylinder value (high part for LBA48 mode)
UCHAR bReserved; // 0
} IDEREGS_EX, *PIDEREGS_EX, *LPIDEREGS_EX;
typedef struct _UNIATA_REG_IO {
USHORT RegIDX;
UCHAR RegSz:2; // 0=1, 1=2, 2=4, 3=2+2 (for lba48)
UCHAR InOut:1; // 0=in, 1=out
UCHAR Reserved:5;
UCHAR Reserved1;
ULONG Data;
} UNIATA_REG_IO, *PUNIATA_REG_IO;
typedef struct _UNIATA_REG_IO_HDR {
ULONG ItemCount;
UNIATA_REG_IO r[1];
} UNIATA_REG_IO_HDR, *PUNIATA_REG_IO_HDR;
#pragma pack()
typedef struct _UNIATA_CTL {
SRB_IO_CONTROL hdr;
SCSI_ADDRESS addr;
union {
UCHAR RawData[1];
ADDREMOVEDEV FindDelDev;
SETTRANSFERMODE SetMode;
GETTRANSFERMODE GetMode;
ADAPTERINFO AdapterInfo;
// IDENTIFY_DATA2 LunIdent;
// ATA_PASS_THROUGH_DIRECT AtaDirect;
UNIATA_REG_IO_HDR RegIo;
};
} UNIATA_CTL, *PUNIATA_CTL;
#endif //UNIATA_CORE
#ifdef __cplusplus
};
#endif //__cplusplus
#pragma pack(pop)
#endif //__UNIATA_IO_CONTROL_CODES__H__

View file

@ -0,0 +1,2 @@
#define UNIATA_VER_STR "38c2"