diff --git a/reactos/drivers/storage/ide/uniata/atapi.h b/reactos/drivers/storage/ide/uniata/atapi.h index bbb29c66939..2f9dce60029 100644 --- a/reactos/drivers/storage/ide/uniata/atapi.h +++ b/reactos/drivers/storage/ide/uniata/atapi.h @@ -86,19 +86,20 @@ ScsiDebugPrint( #define PRINT_PREFIX 0, +#define KdPrint3(_x_) ScsiDebugPrint _x_ {;} #define KdPrint2(_x_) {ScsiDebugPrint("%x: ", PsGetCurrentThread()) ; ScsiDebugPrint _x_ ; } -#define KdPrint(_x_) ScsiDebugPrint _x_ +#define KdPrint(_x_) ScsiDebugPrint _x_ {;} #else // SCSI_PORT_DBG_PRINT -#ifndef USE_DBGPRINT_LOGGER -ULONG -_cdecl -DbgPrint( - const CHAR * Format, - ... - ); -#endif // USE_DBGPRINT_LOGGER +//#ifndef USE_DBGPRINT_LOGGER +//ULONG +//_cdecl +//DbgPrint( +// PCH Format, +// ... +// ); +//#endif // USE_DBGPRINT_LOGGER #define PRINT_PREFIX @@ -107,6 +108,7 @@ DbgPrint( //#define LOG_ON_RAISED_IRQL_W2K TRUE //#define LOG_ON_RAISED_IRQL_W2K FALSE +#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }} #define KdPrint2(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }} #define KdPrint(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }} /* @@ -136,8 +138,12 @@ DbgPrint( #else // _DEBUG -#define KdPrint2(_x_) -#define KdPrint(_x_) +#define PRINT_PREFIX "UniATA: " + +//#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }} +#define KdPrint3(_x_) {;} +#define KdPrint2(_x_) {;} +#define KdPrint(_x_) {;} #define Connect_DbgPrint() {;} #define AtapiStallExecution(dt) ScsiPortStallExecution(dt) @@ -235,6 +241,9 @@ typedef struct _IDE_REGISTERS_2 { #define DFLAGS_RCACHE_ENABLED 0x1000 // Indicates that we use read cache #define DFLAGS_ORIG_GEOMETRY 0x2000 // #define DFLAGS_REINIT_DMA 0x4000 // +#define DFLAGS_HIDDEN 0x8000 // Hidden device, available only with special IOCTLs + // via communication virtual device +//#define DFLAGS_ 0x10000 // // // Used to disable 'advanced' features. // @@ -287,6 +296,7 @@ typedef struct _MODE_PARAMETER_HEADER_10 { #define IDE_COMMAND_ATAPI_RESET 0x08 #define IDE_COMMAND_RECALIBRATE 0x10 #define IDE_COMMAND_READ 0x20 +#define IDE_COMMAND_READ_NO_RETR 0x21 #define IDE_COMMAND_READ48 0x24 #define IDE_COMMAND_READ_DMA48 0x25 #define IDE_COMMAND_READ_DMA_Q48 0x26 @@ -296,6 +306,7 @@ typedef struct _MODE_PARAMETER_HEADER_10 { #define IDE_COMMAND_READ_STREAM48 0x2B #define IDE_COMMAND_READ_LOG48 0x2f #define IDE_COMMAND_WRITE 0x30 +#define IDE_COMMAND_WRITE_NO_RETR 0x31 #define IDE_COMMAND_WRITE48 0x34 #define IDE_COMMAND_WRITE_DMA48 0x35 #define IDE_COMMAND_WRITE_DMA_Q48 0x36 @@ -849,8 +860,10 @@ NATIVE_MODE_CONTROLLER_INFORMATION const NativeModeAdapters[] = { AtapiWritePort1(chan, IDX_IO1_o_Command, _Command); -#define SelectDrive(chan, unit) \ - AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (unit) ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); +#define SelectDrive(chan, unit) { \ + if(chan && chan->lun[unit] && chan->lun[unit]->DeviceFlags & DFLAGS_ATAPI_CHANGER) KdPrint3((" Select %d\n", unit)); \ + AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (unit) ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); \ +} #define ReadBuffer(chan, Buffer, Count, timing) \ @@ -1054,10 +1067,12 @@ CheckDevice( IN BOOLEAN ResetBus ); +#define UNIATA_FIND_DEV_UNHIDE 0x01 + BOOLEAN FindDevices( IN PVOID HwDeviceExtension, - IN BOOLEAN AtapiOnly, + IN ULONG Flags, IN ULONG Channel ); @@ -1154,8 +1169,10 @@ AtapiDisableInterrupts( IN ULONG c ); -#define CHAN_NOT_SPECIFIED (0xffffffffL) -#define DEVNUM_NOT_SPECIFIED (0xffffffffL) +#define CHAN_NOT_SPECIFIED (0xffffffffL) +#define CHAN_NOT_SPECIFIED_CHECK_CABLE (0xfffffffeL) +#define DEVNUM_NOT_SPECIFIED (0xffffffffL) +#define IOMODE_NOT_SPECIFIED (0xffffffffL) extern ULONG AtapiRegCheckDevValue( diff --git a/reactos/drivers/storage/ide/uniata/bm_devs.h b/reactos/drivers/storage/ide/uniata/bm_devs.h index b630d66bdbf..7e131e8ea54 100644 --- a/reactos/drivers/storage/ide/uniata/bm_devs.h +++ b/reactos/drivers/storage/ide/uniata/bm_devs.h @@ -78,7 +78,8 @@ Revision History: // define PIO timings in nanoseconds #define PIO0_TIMING 600 -#define UniataGetPioTiming(LunExt) ((LunExt->TransferMode <= ATA_PIO0) ? PIO0_TIMING : 0) +//#define UniataGetPioTiming(LunExt) ((LunExt->TransferMode <= ATA_PIO0) ? PIO0_TIMING : 0) +#define UniataGetPioTiming(LunExt) 0 //ktp #ifndef __IDE_BUSMASTER_DEVICES_H__ #define __IDE_BUSMASTER_DEVICES_H__ @@ -101,6 +102,7 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION { CHAR channel; // CHAR numOfChannes; CHAR MasterDev; + BOOLEAN Known; #ifndef USER_MODE CHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary BOOLEAN Isr2Enable; @@ -198,6 +200,9 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION { #define ATA_NATIONAL_ID 0x100b #define ATA_SC1100 0x0502100b +#define ATA_NETCELL_ID 0x169c +#define ATA_NETCELL_SR 0x0044169c + #define ATA_NVIDIA_ID 0x10de #define ATA_NFORCE1 0x01bc10de #define ATA_NFORCE2 0x006510de @@ -354,6 +359,7 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION { #define UNIATA_NO_DPC 0x08000000 #define UNIATA_NO_DPC_ATAPI 0x04000000 #define UNIATA_AHCI 0x02000000 +#define UNIATA_NO80CHK 0x01000000 #define ATPOLD 0x0100 @@ -440,11 +446,11 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION { 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( 0006, 1191, 0x00, ATA_UDMA4, "Acard ATP860A" , UNIATA_NO80CHK ), + PCI_DEV_HW_SPEC_BM( 0007, 1191, 0x00, ATA_UDMA4, "Acard ATP860R" , UNIATA_NO80CHK ), + PCI_DEV_HW_SPEC_BM( 0008, 1191, 0x00, ATA_UDMA6, "Acard ATP865A" , UNIATA_NO80CHK ), + PCI_DEV_HW_SPEC_BM( 0009, 1191, 0x00, ATA_UDMA6, "Acard ATP865R" , UNIATA_NO80CHK ), + 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 ), @@ -455,10 +461,11 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = { 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( 7401, 1022, 0x00, ATA_UDMA2, "AMD 755" , AMDNVIDIA | 0x00 ), + PCI_DEV_HW_SPEC_BM( 7409, 1022, 0x00, ATA_UDMA4, "AMD 756" , AMDNVIDIA | UNIATA_NO80CHK ), + PCI_DEV_HW_SPEC_BM( 7411, 1022, 0x00, ATA_UDMA5, "AMD 766" , AMDNVIDIA | AMDBUG ), + PCI_DEV_HW_SPEC_BM( 7441, 1022, 0x00, ATA_UDMA5, "AMD 768" , AMDNVIDIA ), + PCI_DEV_HW_SPEC_BM( 7469, 1022, 0x00, ATA_UDMA6, "AMD 8111" , AMDNVIDIA ), 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 ), @@ -520,6 +527,10 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = { 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( 2920, 8086, 0x00, ATA_SA300, "Intel ICH9" , UNIATA_SATA | UNIATA_AHCI ), + PCI_DEV_HW_SPEC_BM( 2926, 8086, 0x00, ATA_SA300, "Intel ICH9" , UNIATA_SATA | UNIATA_AHCI ), + PCI_DEV_HW_SPEC_BM( 2923, 8086, 0x00, ATA_SA300, "Intel ICH9" , UNIATA_SATA | UNIATA_AHCI ), + PCI_DEV_HW_SPEC_BM( 2922, 8086, 0x00, ATA_SA300, "Intel ICH9" , 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 ), @@ -690,6 +701,8 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = { 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( 0044, 169c, 0x00, ATA_UDMA2, "Netcell SR3000/5000", 0 ), + PCI_DEV_HW_SPEC_BM( 8013, 3388, 0x00, ATA_DMA, "HiNT VXII EIDE" , 0 ), // Terminator diff --git a/reactos/drivers/storage/ide/uniata/bsmaster.h b/reactos/drivers/storage/ide/uniata/bsmaster.h index fd5b6746fe4..781c0ed29f4 100644 --- a/reactos/drivers/storage/ide/uniata/bsmaster.h +++ b/reactos/drivers/storage/ide/uniata/bsmaster.h @@ -77,8 +77,6 @@ Revision History: #define PCI_ADDRESS_IOMASK 0xfffffff0 #define ATA_BM_OFFSET1 0x08 -#define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/ -#define ATA_DMA_EOT 0x80000000 #define ATA_IOSIZE 0x08 #define ATA_ALTOFFSET 0x206 /* alternate registers offset */ #define ATA_PCCARD_ALTOFFSET 0x0e /* do for PCCARD devices */ @@ -87,6 +85,9 @@ Revision History: #define ATA_PC98_BANKIOSIZE 0x01 #define ATA_MAX_LBA28 DEF_U64(0x0fffffff) +#define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/ +#define ATA_DMA_EOT 0x80000000 + #define DEV_BSIZE 512 #define ATAPI_MAGIC_LSB 0x14 @@ -348,6 +349,34 @@ typedef struct _IDE_SATA_REGISTERS { #define IDX_MAX_REG (IDX_SATA_IO+IDX_SATA_IO_SZ) +typedef union _AHCI_IS_REG { + struct { + ULONG DHRS:1;// Device to Host Register FIS Interrupt + ULONG PSS:1; // PIO Setup FIS Interrupt + ULONG DSS:1; // DMA Setup FIS Interrupt + ULONG SDBS:1;// Set Device Bits Interrupt + ULONG UFS:1; // Unknown FIS Interrupt + ULONG DPS:1; // Descriptor Processed + ULONG PCS:1; // Port Connect Change Status + ULONG DMPS:1;// Device Mechanical Presence Status + + ULONG Reserved_8_21:14; + ULONG PRCS:1;// PhyRdy Change Status + ULONG IPMS:1;// Incorrect Port Multiplier Status + + ULONG OFS:1; // Overflow Status + ULONG Reserved_25:1; + ULONG INFS:1;// Interface Non-fatal Error Status + ULONG IFS:1; // Interface Fatal Error Status + ULONG HBDS:1;// Host Bus Data Error Status + ULONG HBFS:1;// Host Bus Fatal Error Status + ULONG TFES:1;// Task File Error Status + ULONG CPDS:1;// Cold Port Detect Status + }; + ULONG Reg; +} AHCI_IS_REG, *PAHCI_IS_REG; + + typedef struct _IDE_AHCI_PORT_REGISTERS { union { struct { @@ -366,31 +395,9 @@ typedef struct _IDE_AHCI_PORT_REGISTERS { }; union { - ULONG Reg; // interrupt status - struct { - ULONG DHRS:1;// Device to Host Register FIS Interrupt - ULONG PSS:1; // PIO Setup FIS Interrupt - ULONG DSS:1; // DMA Setup FIS Interrupt - ULONG SDBS:1;// Set Device Bits Interrupt - ULONG UFS:1; // Unknown FIS Interrupt - ULONG DPS:1; // Descriptor Processed - ULONG PCS:1; // Port Connect Change Status - ULONG DMPS:1;// Device Mechanical Presence Status - - ULONG Reserved_8_21:14; - ULONG PRCS:1;// PhyRdy Change Status - ULONG IPMS:1;// Incorrect Port Multiplier Status - - ULONG OFS:1; // Overflow Status - ULONG Reserved_25:1; - ULONG INFS:1;// Interface Non-fatal Error Status - ULONG IFS:1; // Interface Fatal Error Status - ULONG HBDS:1;// Host Bus Data Error Status - ULONG HBFS:1;// Host Bus Fatal Error Status - ULONG TFES:1;// Task File Error Status - ULONG CPDS:1;// Cold Port Detect Status - }; - } IS; + ULONG IS_Reg; // interrupt status + AHCI_IS_REG IS; + }; union { ULONG Reg; // interrupt enable @@ -513,13 +520,19 @@ typedef struct _IDE_AHCI_PORT_REGISTERS { } IDE_AHCI_PORT_REGISTERS, *PIDE_AHCI_PORT_REGISTERS; +#define IDX_AHCI_P_IS (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS)) +#define IDX_AHCI_P_CI (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI)) + typedef struct _IDE_AHCI_PRD_ENTRY { union { ULONG base; ULONGLONG base64; struct { ULONG DBA; - ULONG DBAU; + union { + ULONG DBAU; + ULONG baseu; + }; }; }; ULONG Reserved1; @@ -530,6 +543,22 @@ typedef struct _IDE_AHCI_PRD_ENTRY { } IDE_AHCI_PRD_ENTRY, *PIDE_AHCI_PRD_ENTRY; +#define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */ + +typedef struct _IDE_AHCI_CMD { + UCHAR cfis[64]; + UCHAR acmd[32]; + UCHAR Reserved[32]; + IDE_AHCI_PRD_ENTRY prd_tab[ATA_AHCI_DMA_ENTRIES]; +} IDE_AHCI_CMD, *PIDE_AHCI_CMD; + +typedef struct _IDE_AHCI_CMD_LIST { + USHORT cmd_flags; + USHORT prd_length; /* PRD entries */ + ULONG bytecount; + ULONGLONG cmd_table_phys; /* 128byte aligned */ +} IDE_AHCI_CMD_LIST, *PIDE_AHCI_CMD_LIST; + #define IsBusMaster(pciData) \ ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \ (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) @@ -545,31 +574,52 @@ typedef struct _IDE_AHCI_PRD_ENTRY { //#define INT_Q_SIZE 32 #define MIN_REQ_TTL 4 -struct _ATA_REQ; +union _ATA_REQ; -typedef struct _ATA_REQ { +typedef union _ATA_REQ { // ULONG reqId; // serial - struct _ATA_REQ* next_req; - struct _ATA_REQ* prev_req; + struct { - PSCSI_REQUEST_BLOCK Srb; // Current request on controller. + union { - PUSHORT DataBuffer; // Data buffer pointer. - ULONG WordsLeft; // Data words left. - ULONG TransferLength; // Originally requested transfer length - LONGLONG lba; - ULONG bcount; + struct { + union _ATA_REQ* next_req; + union _ATA_REQ* prev_req; - UCHAR retry; - UCHAR ttl; -// UCHAR tag; - UCHAR Flags; - UCHAR ReqState; + PSCSI_REQUEST_BLOCK Srb; // Current request on controller. - PSCSI_REQUEST_BLOCK OriginalSrb; // Mechanism Status Srb Data + PUSHORT DataBuffer; // Data buffer pointer. + ULONG WordsLeft; // Data words left. + ULONG TransferLength; // Originally requested transfer length + LONGLONG lba; + ULONG WordsTransfered;// Data words already transfered. + ULONG bcount; - ULONG dma_base; - BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES]; + UCHAR retry; + UCHAR ttl; + // UCHAR tag; + UCHAR Flags; + UCHAR ReqState; + + PSCSI_REQUEST_BLOCK OriginalSrb; // Mechanism Status Srb Data + + ULONG dma_entries; + union { + ULONG dma_base; + ULONGLONG ahci_base64; // for AHCI + }; + }; + UCHAR padding_128b[128]; + }; + struct { + union { + BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES]; + IDE_AHCI_CMD ahci_cmd; // for AHCI + }; + }; + }; + + UCHAR padding_4kb[PAGE_SIZE]; } ATA_REQ, *PATA_REQ; @@ -588,6 +638,7 @@ typedef struct _ATA_REQ { #define REQ_STATE_QUEUED 0x10 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20 +#define REQ_STATE_PREPARE_TO_NEXT 0x21 #define REQ_STATE_READY_TO_TRANSFER 0x30 #define REQ_STATE_EXPECTING_INTR 0x40 @@ -724,7 +775,14 @@ typedef struct _HW_CHANNEL { PVOID DB_IO; ULONG DB_IO_PhAddr; - PUCHAR DmaBuffer; + PUCHAR DmaBuffer; + + // + PIDE_AHCI_CMD_LIST AHCI_CL; + ULONGLONG AHCI_CL_PhAddr; + PVOID AHCI_FIS; // is not actually used by UniATA now, but is required by AHCI controller + ULONGLONG AHCI_FIS_PhAddr; + // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure #ifdef QUEUE_STATISTICS LONGLONG QueueStat[MAX_QUEUE_STAT]; @@ -732,7 +790,7 @@ typedef struct _HW_CHANNEL { LONGLONG IntersectCount; LONGLONG TryReorderCount; LONGLONG TryReorderHeadCount; - LONGLONG TryReorderTailCount; // in-order requests + LONGLONG TryReorderTailCount; /* in-order requests */ #endif //QUEUE_STATISTICS //ULONG BaseMemAddress; @@ -800,13 +858,16 @@ typedef struct _HW_LU_EXTENSION { ULONG opt_PreferedTransferMode; BOOLEAN opt_ReadCacheEnable; BOOLEAN opt_WriteCacheEnable; + UCHAR opt_ReadOnly; // padding - BOOLEAN opt_reserved[2]; + BOOLEAN opt_reserved[1]; struct _SBadBlockListItem* bbListDescr; struct _SBadBlockRange* arrBadBlocks; ULONG nBadBlocks; + struct _HW_DEVICE_EXTENSION* DeviceExtension; + #ifdef IO_STATISTICS LONGLONG ModeErrorCount[MAX_RETRIES]; @@ -833,7 +894,7 @@ typedef struct _HW_DEVICE_EXTENSION { ULONG FirstChannelToCheck; #if 1 HW_LU_EXTENSION lun[IDE_MAX_LUN]; - HW_CHANNEL chan[AHCI_MAX_PORT]; // IDE_MAX_CHAN + HW_CHANNEL chan[AHCI_MAX_PORT/*IDE_MAX_CHAN*/]; #else PHW_LU_EXTENSION lun; PHW_CHANNEL chan; @@ -851,12 +912,12 @@ typedef struct _HW_DEVICE_EXTENSION { ULONG ActiveDpcChan; ULONG FirstDpcChan; - -// PHW_TIMER HwScsiTimer1; -// PHW_TIMER HwScsiTimer2; -// LONGLONG DpcTime1; -// LONGLONG DpcTime2; - +/* + PHW_TIMER HwScsiTimer1; + PHW_TIMER HwScsiTimer2; + LONGLONG DpcTime1; + LONGLONG DpcTime2; +*/ ULONG queue_depth; PDEVICE_OBJECT Isr2DevObj; @@ -891,6 +952,7 @@ typedef struct _HW_DEVICE_EXTENSION { ULONG MaxTransferMode; // max transfer mode supported by controller ULONG HwFlags; INTERFACE_TYPE OrigAdapterInterfaceType; + INTERFACE_TYPE AdapterInterfaceType; ULONG MaximumDmaTransferLength; ULONG AlignmentMask; @@ -908,6 +970,8 @@ typedef struct _HW_DEVICE_EXTENSION { BOOLEAN opt_AtapiDmaRawRead; // default TRUE BOOLEAN opt_AtapiDmaReadWrite; // default TRUE + PCHAR FullDevName; + } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION; typedef struct _ISR2_DEVICE_EXTENSION { @@ -921,6 +985,8 @@ typedef struct _ISR2_DEVICE_EXTENSION { extern UCHAR pciBuffer[256]; extern PBUSMASTER_CONTROLLER_INFORMATION BMList; extern ULONG BMListLen; +extern ULONG IsaCount; +extern ULONG MCACount; //extern const CHAR retry_Wdma[MAX_RETRIES+1]; //extern const CHAR retry_Udma[MAX_RETRIES+1]; @@ -931,6 +997,26 @@ UniataEnumBusMasterController( PVOID Argument2 ); +extern ULONG DDKAPI +UniataFindCompatBusMasterController1( + IN PVOID HwDeviceExtension, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ); + +extern ULONG DDKAPI +UniataFindCompatBusMasterController2( + IN PVOID HwDeviceExtension, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ); + extern ULONG DDKAPI UniataFindBusMasterController( IN PVOID HwDeviceExtension, @@ -941,6 +1027,16 @@ UniataFindBusMasterController( OUT PBOOLEAN Again ); +extern ULONG DDKAPI +UniataFindFakeBusMasterController( + IN PVOID HwDeviceExtension, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ); + extern NTSTATUS UniataConnectIntr2( IN PVOID HwDeviceExtension @@ -962,6 +1058,9 @@ ScsiPortGetBusDataByOffset( IN ULONG Length ); +#define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL) +#define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL) + extern ULONG AtapiFindListedDev( PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters, @@ -1021,8 +1120,6 @@ AtapiDmaStart( IN PSCSI_REQUEST_BLOCK Srb ); -//#define DEVNUM_NOT_SPECIFIED (0xffffffffL) - extern UCHAR AtapiDmaDone( IN PVOID HwDeviceExtension, @@ -1327,6 +1424,8 @@ AtapiReadBuffer2( chan->lun[1] = &(deviceExtension->lun[c*2+1]); \ chan->AltRegMap = deviceExtension->AltRegMap; \ chan->NextDpcChan = -1; \ + chan->lun[0]->DeviceExtension = deviceExtension; \ + chan->lun[1]->DeviceExtension = deviceExtension; \ } BOOLEAN @@ -1336,6 +1435,11 @@ AtapiReadChipConfig( IN ULONG channel // physical channel ); +VOID +UniataForgetDevice( + PHW_LU_EXTENSION LunExt + ); + extern ULONG SkipRaids; extern ULONG ForceSimplex; @@ -1343,4 +1447,6 @@ extern BOOLEAN InDriverEntry; extern BOOLEAN g_opt_Verbose; +extern BOOLEAN WinVer_WDM_Model; + #endif //__IDE_BUSMASTER_H__ diff --git a/reactos/drivers/storage/ide/uniata/config.h b/reactos/drivers/storage/ide/uniata/config.h index 13f72ee146a..17768e42a20 100644 --- a/reactos/drivers/storage/ide/uniata/config.h +++ b/reactos/drivers/storage/ide/uniata/config.h @@ -58,6 +58,12 @@ #define IO_STATISTICS +/***************************************/ +// Misc +/***************************************/ + +//#define NAVO_TEST + /***************************************************/ /* Validate Options */ /***************************************************/ diff --git a/reactos/drivers/storage/ide/uniata/id_ata.cpp b/reactos/drivers/storage/ide/uniata/id_ata.cpp index 02c1e700f05..e0f58e28421 100644 --- a/reactos/drivers/storage/ide/uniata/id_ata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_ata.cpp @@ -61,6 +61,8 @@ Revision History: static const CHAR ver_string[] = "\n\nATAPI IDE MiniPort Driver (UniATA) v 0." UNIATA_VER_STR "\n"; +static const CHAR uniata_comm_name[] = UNIATA_COMM_PORT_VENDOR_STR " \n"; + UNICODE_STRING SavedRegPath; WCHAR SavedRegPathBuffer[256]; @@ -85,6 +87,7 @@ BOOLEAN InDriverEntry = TRUE; BOOLEAN g_opt_Verbose = 0; +BOOLEAN WinVer_WDM_Model = FALSE; //UCHAR EnableDma = FALSE; //UCHAR EnableReorder = FALSE; @@ -211,6 +214,10 @@ UniataNanoSleep( LONGLONG t; LARGE_INTEGER t0; +#ifdef NAVO_TEST + return; +#endif //NAVO_TEST + if(!nano || !g_Perf || !g_PerfDt) return; t = (g_Perf * nano) / g_PerfDt / 1000; @@ -351,7 +358,7 @@ AtapiReadPortExN_template(ULONG, Ulong, 4); //AtapiReadPortExN_template(USHORT, Ushort, 2); AtapiReadPortExN_template(UCHAR, Uchar, 1); -#define AtapiReadPortBufferN_template(type, Type, sz) \ +#define AtapiReadPortBufferN_template(_type, _Type, sz) \ VOID \ DDKFASTAPI \ AtapiReadBuffer##sz( \ @@ -362,17 +369,41 @@ AtapiReadBuffer##sz( \ IN ULONG Timing \ ) \ { \ - ULONG i=0; \ + PIORES res; \ + \ + if(Timing) { \ + while(Count) { \ + (*((_type*)Buffer)) = AtapiReadPort##sz(chan, _port); \ + Count--; \ + Buffer = ((_type*)Buffer)+1; \ + UniataNanoSleep(Timing); \ + } \ + return; \ + } \ + \ + if(_port >= IDX_MAX_REG) { \ + res = (PIORES)(_port); \ + } else \ + if(chan) { \ + res = &chan->RegTranslation[_port]; \ + } else { \ + KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \ + return; \ + } \ + if(!res->MemIo) { \ + /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \ + ScsiPortReadPortBuffer##_Type((_type*)(res->Addr), (_type*)Buffer, Count); \ + return; \ + } \ while(Count) { \ - ((type*)Buffer)[i] = AtapiReadPort##sz(chan, _port); \ - i++; \ + (*((_type*)Buffer)) = ScsiPortReadRegister##_Type((_type*)(res->Addr)); \ Count--; \ - UniataNanoSleep(Timing); \ + Buffer = ((_type*)Buffer)+1; \ } \ return; \ } -#define AtapiWritePortBufferN_template(type, Type, sz) \ +#define AtapiWritePortBufferN_template(_type, _Type, sz) \ VOID \ DDKFASTAPI \ AtapiWriteBuffer##sz( \ @@ -383,12 +414,36 @@ AtapiWriteBuffer##sz( \ IN ULONG Timing \ ) \ { \ - ULONG i=0; \ + PIORES res; \ + \ + if(Timing) { \ + while(Count) { \ + AtapiWritePort##sz(chan, _port, *((_type*)Buffer)); \ + Buffer = ((_type*)Buffer)+1; \ + Count--; \ + UniataNanoSleep(Timing); \ + } \ + return; \ + } \ + \ + if(_port >= IDX_MAX_REG) { \ + res = (PIORES)(_port); \ + } else \ + if(chan) { \ + res = &chan->RegTranslation[_port]; \ + } else { \ + KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \ + return; \ + } \ + if(!res->MemIo) { \ + /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \ + ScsiPortWritePortBuffer##_Type((_type*)(res->Addr), (_type*)Buffer, Count); \ + return; \ + } \ while(Count) { \ - AtapiWritePort##sz(chan, _port, ((type*)Buffer)[i]); \ - i++; \ + ScsiPortWriteRegister##_Type((_type*)(res->Addr), *((_type*)Buffer)); \ Count--; \ - UniataNanoSleep(Timing); \ + Buffer = ((_type*)Buffer)+1; \ } \ return; \ } @@ -530,7 +585,7 @@ UniataIsIdle( return Status; } // if(deviceExtension->HwFlags & UNIATA_SATA) { - if(deviceExtension->BaseIoAddressSATA_0.Addr) { + if(UniataIsSATARangeAvailable(deviceExtension, 0)) { if(Status & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) { return Status; } @@ -701,7 +756,7 @@ AtaCommand48( //>>>>>> NV: 2006/08/03 if((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) && CheckIfBadBlock(&(deviceExtension->lun[ldev]), lba, count)) { - KdPrint2((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count)); + KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count)); return IDE_STATUS_ERROR; //return SRB_STATUS_ERROR; } @@ -723,10 +778,10 @@ AtaCommand48( chan->ChannelCtrlFlags |= CTRFLAGS_LBA48; plba = (PUCHAR)&lba; - AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)(feature>>8) & 0xff); + AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)(feature>>8)); AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)feature); - AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)(count>>8) & 0xff); - AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)count & 0xff); + AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)(count>>8)); + AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)count); AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[3])); AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[0])); AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[4])); @@ -738,22 +793,23 @@ AtaCommand48( AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) ); } else { + plba = (PUCHAR)&lba; //ktp chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48; - + //if(feature || // (deviceExtension->lun[ldev].DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))) { AtapiWritePort1(chan, IDX_IO1_o_Feature, (UCHAR)feature); //} AtapiWritePort1(chan, IDX_IO1_o_BlockCount, (UCHAR)count); - AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)lba & 0xff); - AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(lba>>8) & 0xff); - AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(lba>>16) & 0xff); + AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)plba[0]); + AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)plba[1]); + AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)plba[2]); if(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_LBA_ENABLED) { //KdPrint2((PRINT_PREFIX "AtaCommand28: ldev %#x USE_LBA\n", ldev )); - AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)((lba>>24) & 0xf) | IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) ); + AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)(plba[3] & 0xf) | IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) ); } else { //KdPrint2((PRINT_PREFIX "AtaCommand28: ldev %#x USE_CHS\n", ldev )); - AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)((lba>>24) & 0xf) | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) ); + AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, (UCHAR)(plba[3] & 0xf) | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) ); } } @@ -797,7 +853,7 @@ AtaCommand48( break; } else { //if(deviceExtension->HwFlags & UNIATA_SATA) { - if(deviceExtension->BaseIoAddressSATA_0.Addr) { + if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { break; } AtapiStallExecution(100); @@ -947,7 +1003,7 @@ AtapiTimerDpc( KdPrint2((PRINT_PREFIX "AtapiTimerDpc:\n")); lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan; - if(lChannel == (ULONG)-1) { + if(lChannel == CHAN_NOT_SPECIFIED) { KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no items\n")); return; } @@ -959,19 +1015,19 @@ AtapiTimerDpc( chan->HwScsiTimer = NULL; deviceExtension->FirstDpcChan = chan->NextDpcChan; - if(deviceExtension->FirstDpcChan != (ULONG)-1) { + if(deviceExtension->FirstDpcChan != CHAN_NOT_SPECIFIED) { recall = TRUE; } HwScsiTimer(HwDeviceExtension); - chan->NextDpcChan = -1; + chan->NextDpcChan = CHAN_NOT_SPECIFIED; lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan; - if(lChannel == (ULONG)-1) { + if(lChannel == CHAN_NOT_SPECIFIED) { KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no more items\n")); deviceExtension->FirstDpcChan = - deviceExtension->ActiveDpcChan = -1; + deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED; return; } @@ -989,7 +1045,7 @@ AtapiTimerDpc( } if(recall) { - deviceExtension->ActiveDpcChan = -1; + deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED; MiniportTimerValue = (ULONG)(time.QuadPart - chan->DpcTime)/10; if(!MiniportTimerValue) MiniportTimerValue = 1; @@ -1037,7 +1093,7 @@ AtapiQueueTimerDpc( i = deviceExtension->FirstDpcChan; chan = prev_chan = NULL; - while(i != (ULONG)-1) { + while(i != CHAN_NOT_SPECIFIED) { prev_chan = chan; chan = &deviceExtension->chan[i]; if(chan->DpcTime > time.QuadPart) { @@ -1143,6 +1199,10 @@ IssueIdentify( KdPrint2((PRINT_PREFIX "IssueIdentify: NO SLAVE\n")); return FALSE; } + if(LunExt->DeviceFlags & DFLAGS_HIDDEN) { + KdPrint2((PRINT_PREFIX "IssueIdentify: HIDDEN\n")); + return FALSE; + } SelectDrive(chan, DeviceNumber); AtapiStallExecution(10); @@ -1164,7 +1224,7 @@ IssueIdentify( KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte != IDE_STATUS_IDLE\n")); //if(!(deviceExtension->HwFlags & UNIATA_SATA)) { - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { SelectDrive(chan, DeviceNumber); WaitOnBusyLong(chan); @@ -1215,7 +1275,7 @@ IssueIdentify( } else { KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI. Status (%#x)\n", statusByte)); //if(!(deviceExtension->HwFlags & UNIATA_SATA)) { - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { statusByte = WaitForIdleLong(chan); KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI (2). Status (%#x)\n", statusByte)); } @@ -1223,7 +1283,7 @@ IssueIdentify( } // if(deviceExtension->HwFlags & UNIATA_SATA) { - if(deviceExtension->BaseIoAddressSATA_0.Addr) { + if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { j = 4; } else { j = 0; @@ -1750,6 +1810,14 @@ SetDriveParameters( } // end SetDriveParameters() +VOID +UniataForgetDevice( + PHW_LU_EXTENSION LunExt + ) +{ + LunExt->DeviceFlags &= DFLAGS_HIDDEN; +} // end UniataForgetDevice() + /*++ @@ -1804,11 +1872,11 @@ AtapiResetController__( KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber)); - if(!deviceExtension->simplexOnly) { + if(!deviceExtension->simplexOnly && (PathId != CHAN_NOT_SPECIFIED)) { // we shall reset both channels on SimplexOnly devices, // It's not worth doing so on normal controllers j = PathId; - numberChannels = j+1; + numberChannels = min(j+1, deviceExtension->NumberChannels); } else { j=0; numberChannels = deviceExtension->NumberChannels; @@ -1873,6 +1941,7 @@ AtapiResetController__( // Clear request tracking fields. AtaReq->WordsLeft = 0; AtaReq->DataBuffer = NULL; + AtaReq->TransferLength = 0; ScsiPortNotification(RequestComplete, deviceExtension, @@ -1910,7 +1979,7 @@ AtapiResetController__( ULONG timeout; if(!(ChipFlags & UNIATA_SATA)) goto default_reset; - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, j)) { goto default_reset; } @@ -1981,6 +2050,7 @@ default_reset: // Disable interrupts KdPrint2((PRINT_PREFIX " disable intr\n")); AtapiDisableInterrupts(deviceExtension, j); + AtapiStallExecution(100); KdPrint2((PRINT_PREFIX " re-enable intr\n")); AtapiEnableInterrupts(deviceExtension, j); KdPrint2((PRINT_PREFIX " wait a little (2)\n")); @@ -1991,7 +2061,7 @@ default_reset: } //if(!(ChipFlags & UNIATA_SATA)) { - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, j)) { // Reset DMA engine if active KdPrint2((PRINT_PREFIX " check DMA engine\n")); dma_status = GetDmaStatus(chan->DeviceExtension, chan->lChannel); @@ -2010,6 +2080,9 @@ default_reset: // Check if device present. if (!(deviceExtension->lun[i + (j * 2)].DeviceFlags & DFLAGS_DEVICE_PRESENT)) { +#ifdef NAVO_TEST + continue; +#else //NAVO_TEST //if(!CheckDevice(HwDeviceExtension, i, j, FALSE)) if(!UniataAnybodyHome(HwDeviceExtension, j, i)) { continue; @@ -2020,8 +2093,9 @@ default_reset: } else { if(!UniataAnybodyHome(HwDeviceExtension, j, i)) { KdPrint2((PRINT_PREFIX " device have gone\n")); - deviceExtension->lun[i + (j * 2)].DeviceFlags &= ~DFLAGS_DEVICE_PRESENT; + UniataForgetDevice(&(deviceExtension->lun[i + (j * 2)])); } +#endif //NAVO_TEST } SelectDrive(chan, i); @@ -2032,7 +2106,7 @@ default_reset: KdPrint2((PRINT_PREFIX "no drive, status %#x\n", statusByte)); - deviceExtension->lun[i + (j * 2)].DeviceFlags = 0; + UniataForgetDevice(&(deviceExtension->lun[i + (j * 2)])); } else // Check for ATAPI disk. if (deviceExtension->lun[i + (j * 2)].DeviceFlags & DFLAGS_ATAPI_DEVICE) { @@ -2508,6 +2582,10 @@ AtapiHwInitialize( KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base)\n")); + if(WinVer_WDM_Model) { + AtapiResetController__(HwDeviceExtension, CHAN_NOT_SPECIFIED, RESET_COMPLETE_ALL); + } + /* do extra chipset specific setups */ AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED); /* @@ -2537,11 +2615,11 @@ AtapiHwInitialize__( ULONG PreferedMode = 0xffffffff; AtapiChipInit(deviceExtension, DEVNUM_NOT_SPECIFIED, lChannel); - FindDevices(deviceExtension, FALSE, lChannel); + FindDevices(deviceExtension, 0, lChannel); for (i = lChannel*2; i < (lChannel+1)*2; i++) { - KdPrint2((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x\n", lChannel)); + KdPrint3((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x, dev %x\n", lChannel, i)); LunExt = &(deviceExtension->lun[i]); // skip empty slots @@ -2559,32 +2637,41 @@ AtapiHwInitialize__( IdeMediaStatus(TRUE,deviceExtension,(UCHAR)i); // If supported, setup Multi-block transfers. - if (LunExt->MaximumBlockXfer) { + statusByte = AtaCommand(deviceExtension, i & 1, lChannel, + IDE_COMMAND_SET_MULTIPLE, 0, 0, 0, + LunExt->MaximumBlockXfer, 0, ATA_WAIT_BASE_READY); + + // Check for errors. Reset the value to 0 (disable MultiBlock) if the + // command was aborted. + if (statusByte & IDE_STATUS_ERROR) { + + // Read the error register. + errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error); + + KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n", + statusByte, + errorByte)); statusByte = AtaCommand(deviceExtension, i & 1, lChannel, IDE_COMMAND_SET_MULTIPLE, 0, 0, 0, LunExt->MaximumBlockXfer, 0, ATA_WAIT_BASE_READY); - // Check for errors. Reset the value to 0 (disable MultiBlock) if the - // command was aborted. if (statusByte & IDE_STATUS_ERROR) { - // Read the error register. errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error); - KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n", + KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n", statusByte, errorByte)); - - // Adjust the devExt. value, if necessary. - LunExt->MaximumBlockXfer = 0; - - } else { - KdPrint2((PRINT_PREFIX - "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n", - i, - LunExt->MaximumBlockXfer)); } + // Adjust the devExt. value, if necessary. + LunExt->MaximumBlockXfer = 0; + + } else { + KdPrint2((PRINT_PREFIX + "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n", + i, + LunExt->MaximumBlockXfer)); } if(LunExt->IdentifyData.MajorRevision) { @@ -3125,7 +3212,7 @@ AtapiInterrupt( if(checked[c]) continue; - // check non-empty and execting interrupt channels first + // check non-empty and expecting interrupt channels first if(!pass && !deviceExtension->chan[c].ExpectingInterrupt) continue; @@ -3228,6 +3315,7 @@ AtapiInterrupt2( ULONG c_count = 0; ULONG i_res; + // we should never get here for ISA/MCA if(!BMList[deviceExtension->DevIndex].Isr2Enable) { KdPrint2((PRINT_PREFIX "AtapiInterrupt2: NOT ACTIVE cntrlr %#x chan %#x\n",deviceExtension->DevIndex, deviceExtension->Channel)); return FALSE; @@ -3438,6 +3526,7 @@ AtapiCheckInterrupt__( { PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; PHW_CHANNEL chan = &(deviceExtension->chan[c]); + PHW_LU_EXTENSION LunExt; ULONG VendorID = deviceExtension->DevID & 0xffff; ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK; @@ -3446,7 +3535,7 @@ AtapiCheckInterrupt__( ULONG pr_status = 0; UCHAR dma_status = 0; UCHAR reg8 = 0; - UCHAR reg32 = 0; + ULONG reg32 = 0; UCHAR statusByte; ULONG slotNumber = deviceExtension->slotNumber; ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber; @@ -3455,7 +3544,7 @@ AtapiCheckInterrupt__( UCHAR lChannel; BOOLEAN DmaTransfer = FALSE; BOOLEAN OurInterrupt = FALSE; - ULONG k; +// ULONG k; UCHAR interruptReason; BOOLEAN EarlyIntr = FALSE; @@ -3481,6 +3570,12 @@ AtapiCheckInterrupt__( goto check_unknown; } + if((ChipFlags & UNIATA_AHCI) && + UniataIsSATARangeAvailable(deviceExtension, lChannel)) { + OurInterrupt = UniataAhciStatus(HwDeviceExtension, lChannel); + return OurInterrupt; + } + // Attention ! // We can catch (BM_STATUS_ACTIVE + BM_STATUS_INTR) when operation is actually completed // Such behavior was observed with Intel ICH-xxx chips @@ -3581,9 +3676,9 @@ AtapiCheckInterrupt__( if(ChipType == SIIMIO) { - reg32 = AtapiReadPort1(chan, IDX_BM_DeviceSpecific0); + reg32 = AtapiReadPort4(chan, IDX_BM_DeviceSpecific0); KdPrint2((PRINT_PREFIX " Sii DS0 %x\n", reg32)); - if(reg32 == (UCHAR)-1) { + if(reg32 == 0xffffffff) { KdPrint2((PRINT_PREFIX " Sii mio unexpected\n")); return FALSE; } @@ -3645,10 +3740,14 @@ AtapiCheckInterrupt__( AtapiReadPort1(chan, IDX_BM_Command) & ~BM_COMMAND_START_STOP); goto skip_dma_stat_check; default: - if(deviceExtension->BaseIoAddressSATA_0.Addr && - (ChipFlags & UNIATA_SATA)) { - if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT)) { - OurInterrupt = 2; + if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { + if(ChipFlags & UNIATA_AHCI) { + // Do nothing here + } else + if(ChipFlags & UNIATA_SATA) { + if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT)) { + OurInterrupt = 2; + } } } } @@ -3686,53 +3785,57 @@ skip_dma_stat_check: AtapiStallExecution(1); } + LunExt = &(deviceExtension->lun[c*2 + chan->cur_cdev]); /* if drive is busy it didn't interrupt */ - /* the exception is DCS + BSY state of ATAPI dvices */ + /* the exception is DCS + BSY state of ATAPI devices */ KdPrint2((PRINT_PREFIX " getting status...\n")); GetStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX " status %#x\n", statusByte)); + if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) { + KdPrint3((PRINT_PREFIX " ATAPI status %#x\n", statusByte)); + } else { + KdPrint2((PRINT_PREFIX " IDE status %#x\n", statusByte)); + } if (statusByte == 0xff) { // interrupt from empty controller ? - } else + } else if (statusByte & IDE_STATUS_BUSY) { if(!chan->ExpectingInterrupt) { - KdPrint2((PRINT_PREFIX " unexpected intr + BUSY\n")); + KdPrint3((PRINT_PREFIX " unexpected intr + BUSY\n")); return OurInterrupt; } - if(deviceExtension->lun[c*2 + chan->cur_cdev].DeviceFlags & DFLAGS_ATAPI_DEVICE) { + if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) { KdPrint2((PRINT_PREFIX " ATAPI additional check\n")); } else { KdPrint2((PRINT_PREFIX " expecting intr + BUSY (3), non ATAPI\n")); return FALSE; } - if(statusByte != (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) { - KdPrint2((PRINT_PREFIX " unexpected status, seems it is not our\n")); + if((statusByte & ~IDE_STATUS_DRQ) != (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) { + KdPrint3((PRINT_PREFIX " unexpected status, seems it is not our\n")); + return FALSE; + } + if(!(LunExt->DeviceFlags & DFLAGS_INT_DRQ) && (statusByte & IDE_STATUS_DRQ)) { + KdPrint3((PRINT_PREFIX " unexpected DRQ, seems it is not our\n")); return FALSE; } EarlyIntr = TRUE; if(dma_status & BM_STATUS_INTR) { - KdPrint2((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n")); + KdPrint3((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n")); /* clear interrupt and get status */ GetBaseStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX " base status %#x\n", statusByte)); + KdPrint3((PRINT_PREFIX " base status %#x (+BM_STATUS_INTR)\n", statusByte)); return TRUE; } if(g_WaitBusyInISR) { - for(k=20; k; k--) { - GetStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte)); - KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", - AtapiReadPort1(chan, IDX_IO1_i_Error))); - if (!(statusByte & IDE_STATUS_BUSY)) { - KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n")); - break; - } - break; - //AtapiStallExecution(25); + GetStatus(chan, statusByte); + KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte)); + reg8 = AtapiReadPort1(chan, IDX_IO1_i_Error); + KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", reg8)); + if (!(statusByte & IDE_STATUS_BUSY)) { + KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n")); } if (statusByte & IDE_STATUS_BUSY) { KdPrint2((PRINT_PREFIX " still BUSY, seems it is not our\n")); @@ -3775,14 +3878,14 @@ skip_dma_stat_check: KdPrint2((PRINT_PREFIX " Unexpected interrupt.\n")); - if(deviceExtension->lun[c*2 + chan->cur_cdev * 2].DeviceFlags & DFLAGS_ATAPI_DEVICE) { + if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) { KdPrint2((PRINT_PREFIX " ATAPI additional check\n")); } else { KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt)); return OurInterrupt; } interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & 0x3); - KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason)); + KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason)); return OurInterrupt; } //ASSERT(!chan->queue_depth || chan->cur_req); @@ -3905,6 +4008,7 @@ AtapiInterrupt__( switch(OldReqState) { case REQ_STATE_ATAPI_EXPECTING_CMD_INTR: + KdPrint3((PRINT_PREFIX " EXPECTING_CMD_INTR\n")); case REQ_STATE_ATAPI_EXPECTING_DATA_INTR: case REQ_STATE_DPC_WAIT_BUSY0: case REQ_STATE_DPC_WAIT_BUSY1: @@ -4008,7 +4112,7 @@ ServiceInterrupt: #else ServiceInterrupt: #endif //UNIATA_CORE - +/* // make additional delay for old devices (if we are not in DPC) if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4)) && @@ -4019,10 +4123,14 @@ ServiceInterrupt: KdPrint2((PRINT_PREFIX " additional delay 10us for old devices\n")); AtapiStallExecution(10); } - +*/ /* clear interrupt and get status */ GetBaseStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte)); + if(atapiDev) { + KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte)); + } else { + KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte)); + } if(!UseDpc) { KdPrint2((PRINT_PREFIX " operate like in DPC\n")); @@ -4086,18 +4194,18 @@ try_dpc_wait: } if (statusByte & IDE_STATUS_BUSY) { //if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) { - KdPrint2((PRINT_PREFIX " BUSY on ATAPI device, waiting\n")); + KdPrint3((PRINT_PREFIX " BUSY on ATAPI device, waiting\n")); for(k=20; k; k--) { GetStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte)); - KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", + KdPrint3((PRINT_PREFIX " status re-check %#x\n", statusByte)); + KdPrint3((PRINT_PREFIX " Error reg (%#x)\n", AtapiReadPort1(chan, IDX_IO1_i_Error))); if (!(statusByte & IDE_STATUS_BUSY)) { KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n")); break; } if(k <= 18) { - KdPrint2((PRINT_PREFIX " too long wait -> DPC\n")); + KdPrint3((PRINT_PREFIX " too long wait -> DPC\n")); if(!InDpc) { KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC\n")); TimerValue = 100; @@ -4117,7 +4225,7 @@ try_dpc_wait: AtapiStallExecution(10); } if (statusByte & IDE_STATUS_BUSY) { - KdPrint2((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n")); + KdPrint3((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n")); goto try_dpc_wait; } } @@ -4156,16 +4264,17 @@ try_dpc_wait: KdPrint2((PRINT_PREFIX " Bad Lba unknown\n")); } - KdPrint2((PRINT_PREFIX " wait ready after error\n")); if(!atapiDev) { + KdPrint2((PRINT_PREFIX " wait 100 ready after IDE error\n")); AtapiStallExecution(100); } else { + KdPrint2((PRINT_PREFIX " wait 10 ready after ATAPI error\n")); AtapiStallExecution(10); } continue_err: - KdPrint2((PRINT_PREFIX " Intr on DRQ %x\n", + KdPrint3((PRINT_PREFIX " Intr on DRQ %x\n", LunExt->DeviceFlags & DFLAGS_INT_DRQ)); for (k = atapiDev ? 0 : 200; k; k--) { @@ -4204,10 +4313,27 @@ continue_err: } } else { interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & 0x3); - KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason)); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason)); + + if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) && + ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) { + if(AtaReq->retry < MAX_RETRIES) { +//fallback_pio: + AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION; + AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE; +// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE; + AtaReq->ReqState = REQ_STATE_QUEUED; + goto reenqueue_req; + } + } else { + if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) { + AtaReq->retry++; + } + KdPrint3((PRINT_PREFIX "Errors in PIO mode\n")); + } } - KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error\n")); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n")); if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) { // Fail this request. status = SRB_STATUS_ERROR; @@ -4215,7 +4341,6 @@ continue_err: } else { KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n")); } -#ifdef IO_STATISTICS } else if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) { KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n")); @@ -4223,12 +4348,18 @@ continue_err: } else if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) { KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n")); +#ifdef IO_STATISTICS chan->lun[DeviceNumber]->RecoverCount[AtaReq->retry]++; - if(chan->lun[DeviceNumber]->RecoverCount[AtaReq->retry] >= chan->lun[DeviceNumber]->IoCount/3) { + if(chan->lun[DeviceNumber]->RecoverCount[AtaReq->retry] >= chan->lun[DeviceNumber]->IoCount/3 || + (deviceExtension->HwFlags & UNIATA_NO80CHK) + ) { +#else + if(deviceExtension->HwFlags & UNIATA_NO80CHK) { +#endif //IO_STATISTICS + KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", deviceExtension->lun[DeviceNumber].TransferMode)); deviceExtension->lun[DeviceNumber].LimitedTransferMode = deviceExtension->lun[DeviceNumber].TransferMode; } -#endif //IO_STATISTICS } #ifdef IO_STATISTICS chan->lun[DeviceNumber]->IoCount++; @@ -4243,11 +4374,11 @@ continue_PIO: // ATAPI branch interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & 0x3); - KdPrint2((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason)); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason)); if(DmaTransfer) { wordsThisInterrupt = DEV_BSIZE/2*512; } else { - wordsThisInterrupt = DEV_BSIZE; + wordsThisInterrupt = DEV_BSIZE/2; } } else { @@ -4334,7 +4465,7 @@ IntrPrepareResetController: KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte)); if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) { // Write the packet. - KdPrint2((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n")); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n")); // Send CDB to device. WriteBuffer(chan, (PUSHORT)srb->Cdb, 6, 0); AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; @@ -4453,7 +4584,7 @@ IntrPrepareResetController: (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8); // Covert bytes to words. - wordCount >>= 1; + wordCount /= 2; KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R wordCount %#x\n", wordCount)); if (wordCount != AtaReq->WordsLeft) { @@ -4509,6 +4640,9 @@ IntrPrepareResetController: UniataGetPioTiming(LunExt)); KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) )); //KdDump(AtaReq->DataBuffer, wordCount*2); + if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) { + KdDump(AtaReq->DataBuffer, wordCount*2); + } GetStatus(chan, statusByte); KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte)); @@ -4529,7 +4663,7 @@ IntrPrepareResetController: } } else { - KdPrint2((PRINT_PREFIX + KdPrint3((PRINT_PREFIX "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n", interruptReason, srb)); @@ -4663,7 +4797,7 @@ CompleteRequest: KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n")); if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) { - KdPrint2((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status)); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status)); if (status == SRB_STATUS_SUCCESS) { // Bingo!! AtapiHwInitializeChanger (HwDeviceExtension, @@ -4690,7 +4824,7 @@ CompleteRequest: */ srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL); - KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt)); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt)); if (srbStatus == SRB_STATUS_PENDING) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (1)\n")); @@ -4708,7 +4842,7 @@ CompleteRequest: PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer; - KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status)); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status)); if (status == SRB_STATUS_DATA_OVERRUN) { // Check to see if we at least get mininum number of bytes if ((srb->DataTransferLength - AtaReq->WordsLeft) > @@ -4749,7 +4883,7 @@ CompleteRequest: */ srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL); - KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt)); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt)); if (srbStatus == SRB_STATUS_PENDING) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (2)\n")); @@ -4768,7 +4902,7 @@ CompleteRequest: // If we get here, it means AtapiSendCommand() has failed // Can't recover. Pretend the original srb has failed and complete it. - KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n")); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n")); if (AtaReq->OriginalSrb) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiHwInitializeChanger()\n")); @@ -4791,7 +4925,7 @@ CompleteRequest: } else if (status == SRB_STATUS_ERROR) { // Map error to specific SRB status and handle request sense. - KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n")); + KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n")); status = MapError(deviceExtension, srb); @@ -4800,6 +4934,7 @@ CompleteRequest: } else if(!DmaTransfer) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion\n")); + // Command complete. PIO_wait_busy: KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion, wait BUSY\n")); // Wait for busy to drop. @@ -4916,12 +5051,26 @@ PIO_wait_DRQ: // setmark hit , end of data, end of media... if (!(LunExt->DeviceFlags & DFLAGS_TAPE_DEVICE)) { if (status == SRB_STATUS_DATA_OVERRUN) { - srb->DataTransferLength -= AtaReq->WordsLeft; + srb->DataTransferLength -= AtaReq->WordsLeft*2; } else { srb->DataTransferLength = 0; } } else { - srb->DataTransferLength -= AtaReq->WordsLeft; + srb->DataTransferLength -= AtaReq->WordsLeft*2; + } + } + if(status == SRB_STATUS_SUCCESS) { + AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2; + if(!atapiDev && + AtaReq->WordsTransfered*2 < AtaReq->TransferLength) { + KdPrint2((PRINT_PREFIX "AtapiInterrupt: more I/O required (%x of %x bytes) -> reenqueue\n", + AtaReq->WordsTransfered*2, AtaReq->TransferLength)); + AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION; + AtaReq->ReqState = REQ_STATE_PREPARE_TO_NEXT; + goto reenqueue_req; + } else { + KdPrint2((PRINT_PREFIX " Transfered %x, full size %x\n", + AtaReq->WordsTransfered*2, AtaReq->TransferLength)); } } @@ -5249,7 +5398,8 @@ IdeSendSmartCommand( ULONGLONG UniAtaCalculateLBARegs( PHW_LU_EXTENSION LunExt, - ULONG startingSector + ULONG startingSector, + PULONG max_bcount ) { UCHAR drvSelect,sectorNumber; @@ -5257,6 +5407,11 @@ UniAtaCalculateLBARegs( ULONG tmp; if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) { + if(LunExt->LimitedTransferMode >= ATA_DMA) { + if(LunExt->DeviceExtension) { + (*max_bcount) = LunExt->DeviceExtension->MaximumDmaTransferLength / DEV_BSIZE; + } + } return startingSector; } tmp = LunExt->IdentifyData.SectorsPerTrack * @@ -5266,11 +5421,16 @@ UniAtaCalculateLBARegs( cylinder = 0; drvSelect = 0; sectorNumber = 1; + (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack; } else { cylinder = (USHORT)(startingSector / tmp); drvSelect = (UCHAR)((startingSector % tmp) / LunExt->IdentifyData.SectorsPerTrack); sectorNumber = (UCHAR)(startingSector % LunExt->IdentifyData.SectorsPerTrack) + 1; + (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack - sectorNumber + 1; + KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n", + cylinder, drvSelect, sectorNumber, (*max_bcount))); } + (*max_bcount) = 0; return (ULONG)(sectorNumber&0xff) | (((ULONG)cylinder&0xffff)<<8) | (((ULONG)drvSelect&0xf)<<24); } // end UniAtaCalculateLBARegs() @@ -5334,6 +5494,7 @@ IdeReadWrite( ULONG ldev = GET_LDEV(Srb); UCHAR DeviceNumber = (UCHAR)(ldev & 1); ULONG startingSector; + ULONG max_bcount; ULONG wordCount = 0; UCHAR statusByte,statusByte2; UCHAR cmd; @@ -5346,23 +5507,53 @@ IdeReadWrite( if((CmdAction & CMD_ACTION_PREPARE) && (AtaReq->ReqState != REQ_STATE_READY_TO_TRANSFER)) { + if(LunExt->opt_ReadOnly && + (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)) { + if(LunExt->opt_ReadOnly == 1) { + KdPrint2((PRINT_PREFIX "Abort WRITE (Soft R/O)\n")); + return SRB_STATUS_ERROR; + } else { + KdPrint2((PRINT_PREFIX "Ignore WRITE (Soft R/O)\n")); + return SRB_STATUS_SUCCESS; + } + } + // Set data buffer pointer and words left. - AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer; + AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION; - MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks); - //ASSERT(Srb->DataTransferLength == AtaReq->bcount * DEV_BSIZE); - AtaReq->WordsLeft = min(Srb->DataTransferLength, + if(AtaReq->WordsTransfered) { + AtaReq->DataBuffer = ((PUSHORT)(Srb->DataBuffer)) + AtaReq->WordsTransfered; + startingSector = (ULONG)(UniAtaCalculateLBARegsBack(LunExt, AtaReq->lba)) /* latest lba */ + AtaReq->bcount /* previous bcount */; + AtaReq->bcount = (AtaReq->TransferLength - AtaReq->WordsTransfered*2 + DEV_BSIZE-1) / DEV_BSIZE; + KdPrint2((PRINT_PREFIX "IdeReadWrite (Chained REQ): Starting sector %#x, OrigWordsRequested %#x, WordsTransfered %#x, DevSize %#x\n", + startingSector, + AtaReq->TransferLength/2, + AtaReq->WordsTransfered, + AtaReq->bcount)); + } else { + AtaReq->DataBuffer = (PUSHORT)(Srb->DataBuffer); + AtaReq->TransferLength = Srb->DataTransferLength; + // Set up 1st block. + MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA); + MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks); + KdPrint2((PRINT_PREFIX "IdeReadWrite (Orig REQ): Starting sector %#x, OrigWordsRequested %#x, DevSize %#x\n", + startingSector, + AtaReq->TransferLength/2, + AtaReq->bcount)); + } + lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount); + + if(max_bcount) { + AtaReq->bcount = min(AtaReq->bcount, max_bcount); + } + AtaReq->WordsLeft = min(AtaReq->TransferLength - AtaReq->WordsTransfered*2, AtaReq->bcount * DEV_BSIZE) / 2; - // Set up 1st block. - MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA); - KdPrint2((PRINT_PREFIX "IdeReadWrite (REQ): Starting sector is %#x, Number of WORDS %#x, DevSize %#x\n", startingSector, AtaReq->WordsLeft, AtaReq->bcount)); - lba = UniAtaCalculateLBARegs(LunExt, startingSector); AtaReq->lba = lba; // assume best case here @@ -5372,7 +5563,7 @@ IdeReadWrite( // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb, (PUCHAR)(AtaReq->DataBuffer), - ((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1)))) { + AtaReq->bcount * DEV_BSIZE)) { use_dma = FALSE; } } @@ -5416,7 +5607,7 @@ IdeReadWrite( // Prepare write command. if (use_dma) { - wordCount = Srb->DataTransferLength/2; + wordCount = AtaReq->bcount*DEV_BSIZE/2; cmd = IDE_COMMAND_WRITE_DMA; } else if (LunExt->MaximumBlockXfer) { @@ -5448,7 +5639,7 @@ IdeReadWrite( use_dma) { statusByte2 = AtaCommand48(deviceExtension, DeviceNumber, lChannel, cmd, lba, - (UCHAR)((Srb->DataTransferLength + DEV_BSIZE-1) / DEV_BSIZE), + (USHORT)(AtaReq->bcount), // (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE), 0, ATA_IMMEDIATE); GetStatus(chan, statusByte2); @@ -5465,7 +5656,7 @@ IdeReadWrite( statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel, cmd, lba, - (UCHAR)((Srb->DataTransferLength + DEV_BSIZE-1) / DEV_BSIZE), + (USHORT)(AtaReq->bcount), // (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE), 0, ATA_WAIT_INTR); @@ -5551,6 +5742,7 @@ IdeVerify( ULONG ldev = GET_LDEV(Srb); UCHAR statusByte; ULONG startingSector; + ULONG max_bcount; ULONG sectors; ULONG endSector; USHORT sectorCount; @@ -5608,7 +5800,7 @@ IdeVerify( InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE); - lba = UniAtaCalculateLBARegs(LunExt, startingSector); + lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount); statusByte = AtaCommand48(deviceExtension, ldev & 0x01, GET_CHANNEL(Srb), IDE_COMMAND_VERIFY, lba, @@ -5654,8 +5846,9 @@ AtapiSendCommand( UCHAR statusByte,byteCountLow,byteCountHigh; BOOLEAN use_dma = FALSE; BOOLEAN dma_reinited = FALSE; + BOOLEAN retried = FALSE; - KdPrint2((PRINT_PREFIX "AtapiSendCommand: req state %#x\n", AtaReq->ReqState)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: req state %#x, Action %x\n", AtaReq->ReqState, CmdAction)); if(AtaReq->ReqState < REQ_STATE_PREPARE_TO_TRANSFER) AtaReq->ReqState = REQ_STATE_PREPARE_TO_TRANSFER; @@ -5863,7 +6056,7 @@ call_dma_setup: KdPrint2((PRINT_PREFIX "AtapiSendCommand: !CMD_ACTION_EXEC => SRB_STATUS_PENDING\n")); return SRB_STATUS_PENDING; } - KdPrint2((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma)); if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) { KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n")); } @@ -5913,7 +6106,7 @@ call_dma_setup: ULONG srbStatus; - KdPrint2((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n")); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n")); // Set this flag now. If the device hangs on the mech. status // command, we will not have the chance to set it. deviceExtension->lun[ldev].DeviceFlags |= DFLAGS_CHANGER_INITED; @@ -5924,7 +6117,7 @@ call_dma_setup: HwDeviceExtension, Srb); - KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n")); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n")); srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL); if (srbStatus == SRB_STATUS_PENDING) { KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n")); @@ -5940,9 +6133,9 @@ call_dma_setup: } #endif //UNIATA_CORE - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Command %#x to TargetId %d lun %d\n", + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Command %#x to TargetId %d lun %d\n", Srb->Cdb[0], Srb->TargetId, Srb->Lun)); - + // Make sure command is to ATAPI device. flags = deviceExtension->lun[ldev].DeviceFlags; if (flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) { @@ -5961,13 +6154,13 @@ call_dma_setup: AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; return SRB_STATUS_SELECTION_TIMEOUT; } - +retry: // Select device 0 or 1. SelectDrive(chan, ldev & 0x1); // Verify that controller is ready for next command. GetStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte)); if (statusByte == 0xff) { KdPrint2((PRINT_PREFIX "AtapiSendCommand: bad status 0xff on entry\n")); @@ -5976,15 +6169,17 @@ call_dma_setup: if (statusByte & IDE_STATUS_BUSY) { if(statusByte & IDE_STATUS_DSC) { KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC on entry (%#x), try exec\n", statusByte)); + } else { + KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x) -> reset\n", statusByte)); + // We have to make reset here, since we are expecting device to be available + //return SRB_STATUS_BUSY; // this cause queue freeze + goto make_reset; } - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x)\n", statusByte)); - AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; - return SRB_STATUS_BUSY; } if (statusByte & IDE_STATUS_ERROR) { if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) { - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte)); // Read the error reg. to clear it and fail this request. AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; return MapError(deviceExtension, Srb); @@ -6011,7 +6206,7 @@ call_dma_setup: } if (statusByte & IDE_STATUS_DRQ) { - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n", + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n", statusByte)); // Try to drain the data that one preliminary device thinks that it has // to transfer. Hopefully this random assertion of DRQ will not be present @@ -6027,7 +6222,7 @@ call_dma_setup: if (i == 0x10000) { make_reset: - KdPrint2((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted.Status (%#x)\n", statusByte)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted.Status (%#x)\n", statusByte)); AtapiDisableInterrupts(deviceExtension, lChannel); @@ -6035,8 +6230,11 @@ make_reset: KdPrint2((PRINT_PREFIX "AtapiSendCommand: Issued soft reset to Atapi device. \n")); // Re-initialize Atapi device. + CheckDevice(HwDeviceExtension, GET_CHANNEL(Srb), ldev & 1, TRUE); +/* IssueIdentify(HwDeviceExtension, ldev & 1, GET_CHANNEL(Srb), IDE_COMMAND_ATAPI_IDENTIFY, FALSE); +*/ // Inform the port driver that the bus has been reset. ScsiPortNotification(ResetDetected, HwDeviceExtension, 0); // Clean up device extension fields that AtapiStartIo won't. @@ -6046,10 +6244,18 @@ make_reset: CHECK_INTR_IDLE); AtapiEnableInterrupts(deviceExtension, lChannel); - +/* AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; return SRB_STATUS_BUS_RESET; - +*/ + if(!retried) { + KdPrint3((PRINT_PREFIX "AtapiSendCommand: retry after reset.\n")); + retried = TRUE; + goto retry; + } + KdPrint3((PRINT_PREFIX "AtapiSendCommand: selection timeout.\n")); + AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; + return SRB_STATUS_SELECTION_TIMEOUT; } } @@ -6071,7 +6277,7 @@ make_reset: } statusByte = WaitOnBusy(chan); - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n", + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n", statusByte)); AtapiWritePort1(chan, IDX_IO1_o_Feature, @@ -6092,7 +6298,7 @@ make_reset: // This device interrupts when ready to receive the packet. - KdPrint2((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n", + KdPrint3((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n", statusByte)); chan->ExpectingInterrupt = TRUE; @@ -6103,7 +6309,7 @@ make_reset: // Write ATAPI packet command. AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_PACKET); - KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING\n")); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (DRQ)\n")); return SRB_STATUS_PENDING; } else { @@ -6133,14 +6339,14 @@ make_reset: if (!(statusByte & IDE_STATUS_DRQ)) { AtapiEnableInterrupts(deviceExtension, lChannel); - KdPrint2((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte)); AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE; return SRB_STATUS_ERROR; } } GetStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte)); // Send CDB to device. statusByte = WaitOnBaseBusy(chan); @@ -6164,7 +6370,7 @@ make_reset: AtapiDmaStart(HwDeviceExtension, ldev & 1, lChannel, Srb); } - KdPrint2((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt)); + KdPrint3((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt)); KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (3)\n")); return SRB_STATUS_PENDING; @@ -6259,7 +6465,9 @@ IdeSendCommand( if(CmdAction == CMD_ACTION_PREPARE) { switch (Srb->Cdb[0]) { - //case SCSIOP_INQUIRY: // now it requires device access +#ifdef NAVO_TEST + case SCSIOP_INQUIRY: // now it requires device access +#endif //NAVO_TEST case SCSIOP_READ_CAPACITY: case SCSIOP_READ: case SCSIOP_WRITE: @@ -6308,6 +6516,7 @@ IdeSendCommand( KdPrint2((PRINT_PREFIX "IdeSendCommand: SCSIOP_INQUIRY rejected (2)\n")); // Indicate no device found at this address. +#ifndef NAVO_TEST status = SRB_STATUS_SELECTION_TIMEOUT; break; } @@ -6316,7 +6525,8 @@ IdeSendCommand( KdPrint2((PRINT_PREFIX "IdeSendCommand: SCSIOP_INQUIRY device have gone\n")); // Indicate no device found at this address. - deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_DEVICE_PRESENT; + UniataForgetDevice(&(deviceExtension->lun[ldev])); +#endif //NAVO_TEST status = SRB_STATUS_SELECTION_TIMEOUT; break; } @@ -6507,7 +6717,8 @@ IdeSendCommand( case SCSIOP_WRITE: KdPrint2((PRINT_PREFIX - "IdeSendCommand: SCSIOP_READ/SCSIOP_WRITE PATH:LUN:TID = %#x:%#x:%#x\n", + "IdeSendCommand: SCSIOP_%s PATH:LUN:TID = %#x:%#x:%#x\n", + (Srb->Cdb[0] == SCSIOP_WRITE) ? "WRITE" : "READ", Srb->PathId, Srb->Lun, Srb->TargetId)); AtaReq->Flags &= ~REQ_FLAG_RW_MASK; AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE) ? REQ_FLAG_WRITE : REQ_FLAG_READ; @@ -6593,7 +6804,7 @@ IdeSendCommand( regs->bDriveHeadReg &= 0x0f; regs->bDriveHeadReg |= (UCHAR) (((Srb->TargetId & 0x1) << 4) | 0xA0); - if((regs->bReserved & 1) == 0) { // execute ATA command + if((regs->bOpFlags & 1) == 0) { // execute ATA command KdPrint2((PRINT_PREFIX "IdeSendCommand: SCSIOP_START_STOP_UNIT PATH:LUN:TID = %#x:%#x:%#x\n", @@ -6602,7 +6813,7 @@ IdeSendCommand( AtapiDisableInterrupts(deviceExtension, lChannel); - if(AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) { + if((AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) || (regs->bOpFlags & UNIATA_SPTI_EX_USE_DMA)) { if((chan->lun[Srb->TargetId & 0x1]->LimitedTransferMode >= ATA_DMA)) { use_dma = TRUE; // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success @@ -6617,7 +6828,7 @@ IdeSendCommand( AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, regs->bDriveHeadReg); AtapiStallExecution(10); - if((regs->bReserved & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command + if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg); AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountReg); AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberReg); @@ -6647,7 +6858,7 @@ IdeSendCommand( ScsiPortStallExecution(1); // wait for busy to be set - if(regs->bReserved & UNIATA_SPTI_EX_SPEC_TO) { + if(regs->bOpFlags & UNIATA_SPTI_EX_SPEC_TO) { to_lim = Srb->TimeOutValue; } else { if(Srb->TimeOutValue <= 2) { @@ -6667,7 +6878,7 @@ IdeSendCommand( } } if(i >= to_lim) { - //if(regs->bReserved & UNIATA_SPTI_EX_FREEZE_TO) { + //if(regs->bOpFlags & UNIATA_SPTI_EX_FREEZE_TO) { //} AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_NONE); goto passthrough_err; @@ -6725,7 +6936,7 @@ passthrough_err: regs->bDriveHeadReg = AtapiReadPort1(chan, IDX_IO1_i_DriveSelect); - if((regs->bReserved & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command + if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command regs->bFeaturesReg = AtapiReadPort1(chan, IDX_IO1_i_Error); regs->bSectorCountReg = AtapiReadPort1(chan, IDX_IO1_i_BlockCount); regs->bSectorNumberReg = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); @@ -6925,6 +7136,8 @@ UniataUserDeviceReset( } else { KdPrint2((PRINT_PREFIX "UniataUserDeviceReset: Reset IDE -> reset entire channel\n")); AtapiResetController__(deviceExtension, PathId, RESET_COMPLETE_NONE); + deviceExtension->chan[PathId].lun[0]->DeviceFlags |= DFLAGS_REINIT_DMA; + deviceExtension->chan[PathId].lun[1]->DeviceFlags |= DFLAGS_REINIT_DMA; } LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit AtapiEnableInterrupts(deviceExtension, PathId); @@ -6940,6 +7153,7 @@ UniataNeedQueueing( { BOOLEAN PostReq = FALSE; if(TopLevel) { + KdPrint3((PRINT_PREFIX "UniataNeedQueueing: TopLevel, qd=%x\n", chan->queue_depth)); if(chan->queue_depth > 0) { #if 0 if(atapiDev && @@ -6959,6 +7173,8 @@ UniataNeedQueueing( if(deviceExtension->simplexOnly && deviceExtension->queue_depth > 0) { PostReq = TRUE; } + } else { + KdPrint3((PRINT_PREFIX "UniataNeedQueueing: qd=%x\n", chan->queue_depth)); } return PostReq; } // end UniataNeedQueueing() @@ -7009,7 +7225,9 @@ AtapiStartIo__( PSCSI_REQUEST_BLOCK tmpSrb; BOOLEAN PostReq = FALSE; BOOLEAN atapiDev; + BOOLEAN commPort = FALSE; + // deviceExtension->Isr2DevObj must always be NULL for non-PCI if(deviceExtension->Isr2DevObj && !BMList[deviceExtension->DevIndex].Isr2Enable) { KdPrint2((PRINT_PREFIX "Isr2Enable -> 1\n")); BMList[deviceExtension->DevIndex].Isr2Enable = TRUE; @@ -7040,6 +7258,33 @@ AtapiStartIo__( Srb->Function, Srb->PathId, Srb->Lun, Srb->TargetId)); KdPrint2((PRINT_PREFIX " VendorID+DeviceID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID)); + if(lChannel == deviceExtension->NumberChannels && + !Srb->Lun && !Srb->TargetId && + ((Srb->Function == SRB_FUNCTION_IO_CONTROL) || + (Srb->Function == SRB_FUNCTION_EXECUTE_SCSI && Srb->Cdb[0] == SCSIOP_INQUIRY)) + ) { + KdPrint2((PRINT_PREFIX + "AtapiStartIo: Communication port\n")); + if(Srb->Function == SRB_FUNCTION_EXECUTE_SCSI) { + + PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer); + + KdPrint2((PRINT_PREFIX + " INQUIRY\n")); + // Zero INQUIRY data structure. + RtlZeroMemory((PCHAR)(Srb->DataBuffer), Srb->DataTransferLength); + + inquiryData->DeviceType = COMMUNICATION_DEVICE; + + // Fill in vendor identification fields. + RtlCopyMemory(&inquiryData->VendorId, &uniata_comm_name, 28); + + status = SRB_STATUS_SUCCESS; + goto complete_req; + } + commPort = TRUE; + /* Pass IOCTL request down */ + } else if(GET_CDEV(Srb) >= 2 || ldev >= deviceExtension->NumberChannels*2 || lChannel >= deviceExtension->NumberChannels || @@ -7063,7 +7308,8 @@ reject_srb: atapiDev = (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE; #ifdef _DEBUG - if(!(chan->lun[ldev & 1])) { + if(!commPort && !(chan->lun[ldev & 1])) { +#if 0 PrintNtConsole("de = %#x, chan = %#x , dev %#x, nchan %#x\n", deviceExtension, chan, ldev & 1, @@ -7072,6 +7318,7 @@ reject_srb: lChannel, ldev, GET_CDEV(Srb), deviceExtension->chan[0].lun[0]); PrintNtConsole("Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n", Srb->Function, Srb->PathId, Srb->Lun, Srb->TargetId); +#endif //0 /* int i; for(i=0; i<1000; i++) { @@ -7081,7 +7328,6 @@ reject_srb: goto reject_srb; } #endif //_DEBUG - //ASSERT(chan->lun[ldev & 1]); // Determine which function. switch (Srb->Function) { @@ -7114,10 +7360,10 @@ reject_srb: g_foo += a; } } __except(EXCEPTION_EXECUTE_HANDLER) { - KdPrint2((PRINT_PREFIX + KdPrint3((PRINT_PREFIX "AtapiStartIo: Bad data buffer -> EXECUTE_SCSI rejected\n")); // Indicate no device found at this address. - KdPrint2((PRINT_PREFIX "SRB_STATUS_ERROR\n")); + KdPrint3((PRINT_PREFIX "SRB_STATUS_ERROR\n")); status = SRB_STATUS_ERROR; KdPrint2((PRINT_PREFIX " *** Exception...\n")); ASSERT(FALSE); @@ -7128,10 +7374,10 @@ reject_srb: if(PostReq) { - KdPrint2((PRINT_PREFIX "Non-empty queue\n")); + KdPrint3((PRINT_PREFIX "Non-empty queue\n")); if (atapiDev && (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) { - KdPrint2((PRINT_PREFIX "Try ATAPI prepare\n")); + KdPrint3((PRINT_PREFIX "Try ATAPI prepare\n")); status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE); } else { @@ -7168,6 +7414,7 @@ reject_srb: //ASSERT(!AtaReq->Flags); } +#ifndef NAVO_TEST if(!(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT)) { if(Srb->Cdb[0] == SCSIOP_INQUIRY) { if(UniataAnybodyHome(deviceExtension, chan->lChannel, ldev & 1)) { @@ -7185,10 +7432,11 @@ reject_srb: goto reject_srb; } } +#endif //NAVO_TEST if(atapiDev && (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) { - KdPrint2((PRINT_PREFIX "Try ATAPI send\n")); + KdPrint3((PRINT_PREFIX "Try ATAPI send\n")); status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL); } else { KdPrint2((PRINT_PREFIX "Try IDE send\n")); @@ -7238,7 +7486,7 @@ reject_srb: if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_CURRENT)) { KdPrint2((PRINT_PREFIX "AtapiStartIo: Abort command failed\n")); // Log reset failure. - KdPrint2((PRINT_PREFIX + KdPrint3((PRINT_PREFIX "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n", HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8 )); @@ -7293,7 +7541,7 @@ reject_srb: break; case SRB_FUNCTION_RESET_BUS: - +do_bus_reset: // Reset Atapi and SCSI bus. // Note: reset is immediate command, it cannot be queued since it is usually used to @@ -7302,7 +7550,7 @@ reject_srb: if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_ALL)) { KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus failed\n")); // Log reset failure. - KdPrint2((PRINT_PREFIX + KdPrint3((PRINT_PREFIX "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d) - (2)\n", HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8 )); @@ -7435,6 +7683,15 @@ reject_srb: deviceNumber = versionParameters->bIDEDeviceMap; + if(commPort) { + KdPrint2((PRINT_PREFIX + "AtapiStartIo: SCSIDISK IOCTL for commPort -> EXECUTE_SCSI rejected (2)\n")); + // Indicate no device found at this address. + KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n")); + status = SRB_STATUS_SELECTION_TIMEOUT; + break; + } + if (!(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT) || atapiDev) { @@ -7539,6 +7796,15 @@ reject_srb: case IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES: case IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS: + if(commPort) { + KdPrint2((PRINT_PREFIX + "AtapiStartIo: SCSIDISK Smart IOCTL for commPort -> EXECUTE_SCSI rejected (3)\n")); + // Indicate no device found at this address. + KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n")); + status = SRB_STATUS_SELECTION_TIMEOUT; + break; + } + PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel); if(PostReq || TopLevel) { @@ -7571,14 +7837,14 @@ reject_srb: PUNIATA_CTL AtaCtl = (PUNIATA_CTL)(Srb->DataBuffer); ULONG ldev = GET_LDEV2(AtaCtl->addr.PathId, AtaCtl->addr.TargetId, 0); - PHW_LU_EXTENSION LunExt = &(deviceExtension->lun[ldev]); + PHW_LU_EXTENSION LunExt; BOOLEAN bad_ldev; ULONG i; //chan = &(deviceExtension->chan[lChannel]); if(AtaCtl->addr.Lun || ldev >= deviceExtension->NumberChannels*2 || - AtaCtl->addr.PathId > deviceExtension->NumberChannels) { + AtaCtl->addr.PathId >= deviceExtension->NumberChannels) { bad_ldev = TRUE; LunExt = NULL; @@ -7586,6 +7852,8 @@ reject_srb: } else { bad_ldev = FALSE; LunExt = &(deviceExtension->lun[ldev]); + lChannel = AtaCtl->addr.PathId; + chan = &(deviceExtension->chan[lChannel]); } KdPrint2((PRINT_PREFIX "AtapiStartIo: -UNIATA- %#x, ldev %#x\n", AtaCtl->hdr.ControlCode, ldev)); @@ -7593,13 +7861,32 @@ reject_srb: /* check for valid LUN */ switch (AtaCtl->hdr.ControlCode) { case IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES: + case IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE: + if(bad_ldev && + (AtaCtl->addr.PathId >= deviceExtension->NumberChannels || + AtaCtl->addr.TargetId != 0xff || + AtaCtl->addr.Lun != 0 + )) { + if(AtaCtl->hdr.ControlCode == IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES && + ldev < deviceExtension->NumberChannels*2) { // AtaCtl->addr.TargetId != 0xff + LunExt = &(deviceExtension->lun[ldev]); + // OK + } else { + goto handle_bad_ldev; + } + } + // this would be BUS reset + lChannel = AtaCtl->addr.PathId; + chan = &(deviceExtension->chan[lChannel]); + break; case IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE: case IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE: case IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE: case IOCTL_SCSI_MINIPORT_UNIATA_RESETBB: - case IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE: +// case IOCTL_SCSI_MINIPORT_UNIATA_REG_IO: if(bad_ldev) { - KdPrint2((PRINT_PREFIX +handle_bad_ldev: + KdPrint2((PRINT_PREFIX "AtapiStartIo: bad_ldev -> IOCTL SRB rejected\n")); // Indicate no device found at this address. goto reject_srb; @@ -7635,8 +7922,8 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth)); goto complete_req; - } - } + } + } // end switch (AtaCtl->hdr.ControlCode) /* process request */ switch (AtaCtl->hdr.ControlCode) { @@ -7644,11 +7931,22 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: rescan bus\n")); + if(AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: unhide from further detection\n")); + if(AtaCtl->addr.TargetId != 0xff) { + deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_HIDDEN; + } else { + } + } + for(i=0; iFindDelDev.WaitForPhysicalLink && i<30; i++) { AtapiStallExecution(1000 * 1000); } - FindDevices(HwDeviceExtension, FALSE, AtaCtl->addr.PathId); + FindDevices(HwDeviceExtension, + ((AtaCtl->addr.TargetId == 0xff) && (AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE)) + ? UNIATA_FIND_DEV_UNHIDE : 0, + AtaCtl->addr.PathId); status = SRB_STATUS_SUCCESS; break; @@ -7658,6 +7956,10 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: remove %#x:%#x\n", AtaCtl->addr.PathId, AtaCtl->addr.TargetId)); deviceExtension->lun[ldev].DeviceFlags = 0; + if(AtaCtl->FindDelDev.Flags & UNIATA_REMOVE_FLAGS_HIDE) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: hide from further detection\n")); + deviceExtension->lun[ldev].DeviceFlags |= DFLAGS_HIDDEN; + } for(i=0; iFindDelDev.WaitForPhysicalLink && i<30; i++) { AtapiStallExecution(1000 * 1000); @@ -7670,19 +7972,19 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Set transfer mode\n")); - if(AtaCtl->SetMode.OrigMode != (ULONG)-1) { + if(AtaCtl->SetMode.OrigMode != IOMODE_NOT_SPECIFIED) { LunExt->OrigTransferMode = (UCHAR)(AtaCtl->SetMode.OrigMode); } - if(AtaCtl->SetMode.MaxMode != (ULONG)-1) { + if(AtaCtl->SetMode.MaxMode != IOMODE_NOT_SPECIFIED) { LunExt->LimitedTransferMode = (UCHAR)(AtaCtl->SetMode.MaxMode); - if(LunExt->LimitedTransferMode > + if(LunExt->LimitedTransferMode > LunExt->OrigTransferMode) { // check for incorrect value LunExt->LimitedTransferMode = LunExt->OrigTransferMode; } } - LunExt->TransferMode = LunExt->OrigTransferMode; + LunExt->TransferMode = min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode); LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit if(AtaCtl->SetMode.ApplyImmediately) { @@ -7735,7 +8037,10 @@ uata_ctl_queue: AtaCtl->AdapterInfo.InterruptMode = deviceExtension->InterruptMode; AtaCtl->AdapterInfo.BusInterruptVector = deviceExtension->BusInterruptVector; AtaCtl->AdapterInfo.NumberChannels = deviceExtension->NumberChannels; - + AtaCtl->AdapterInfo.AdapterInterfaceType = deviceExtension->AdapterInterfaceType; + if(deviceExtension->FullDevName) { + strncpy(AtaCtl->AdapterInfo.DeviceName, deviceExtension->FullDevName, 64); + } AtaCtl->AdapterInfo.ChanInfoValid = FALSE; RtlZeroMemory(&AtaCtl->AdapterInfo.Chan, sizeof(AtaCtl->AdapterInfo.Chan)); @@ -7756,7 +8061,11 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device\n")); - UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId, ldev); + if(bad_ldev) { + goto do_bus_reset; + } else { + UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId, ldev); + } status = SRB_STATUS_SUCCESS; break; @@ -7934,7 +8243,7 @@ UniataInitAtaCommands() command = IDE_COMMAND_WRITE_DMA_Q48; break; case IDE_COMMAND_FLUSH_CACHE: command = IDE_COMMAND_FLUSH_CACHE48; break; - case IDE_COMMAND_READ_NATIVE_SIZE: + // case IDE_COMMAND_READ_NATIVE_SIZE: // command = IDE_COMMAND_READ_NATIVE_SIZE48; break; case IDE_COMMAND_SET_NATIVE_SIZE: command = IDE_COMMAND_SET_NATIVE_SIZE48; break; @@ -8013,6 +8322,7 @@ DriverEntry( KdPrint(("Performance calibration: dt=%d, counter=%I64d\n", g_PerfDt, g_Perf )); } else { + KdPrint(("UniATA Init: ReEnter\n")); ReEnter = TRUE; } @@ -8031,6 +8341,17 @@ DriverEntry( SavedRegPath.Buffer[SavedRegPath.Length/sizeof(WCHAR)] = 0; } + if(WinVer_Id() >= WinVer_2k) { + if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"1", 0)) { + KdPrint(("UniATA: Behave as WDM, mlia (1)\n")); + WinVer_WDM_Model = TRUE; + } + if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"5", 0)) { + KdPrint(("UniATA: Behave as WDM, mlia (5)\n")); + WinVer_WDM_Model = TRUE; + } + } + SkipRaids = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"SkipRaids", 1); ForceSimplex = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", 0); #ifdef _DEBUG @@ -8047,6 +8368,7 @@ DriverEntry( sizeof(hwInitializationData.comm) + // sizeof(hwInitializationData.nt4) + ((WinVer_Id() <= WinVer_NT) ? 0 : sizeof(hwInitializationData.w2k)); + KdPrint(("HwInitializationDataSize = %x\n", hwInitializationData.comm.HwInitializationDataSize)); // Set entry points. hwInitializationData.comm.HwInitialize = (PHW_INITIALIZE)AtapiHwInitialize; @@ -8063,7 +8385,9 @@ DriverEntry( hwInitializationData.comm.MapBuffers = TRUE; // Set PnP-specific API if(WinVer_Id() > WinVer_NT) { + KdPrint(("set NeedPhysicalAddresses = TRUE\n")); hwInitializationData.comm.NeedPhysicalAddresses = TRUE; + KdPrint(("set AtapiAdapterControl() ptr\n")); hwInitializationData.w2k.HwAdapterControl = (PHW_ADAPTER_CONTROL)AtapiAdapterControl; } @@ -8104,7 +8428,7 @@ DriverEntry( if(g_opt_Verbose) { _PrintNtConsole("Init standard Dual-channel PCI ATA controller:"); } - for(alt = 0; alt < 2; alt++) { + for(alt = 0; alt < (ULONG)(WinVer_WDM_Model ? 1 : 2) ; alt++) { for(c=0; c<2; c++) { @@ -8124,7 +8448,7 @@ DriverEntry( } } - if((WinVer_Id() <= WinVer_NT)) { + if((WinVer_Id() < WinVer_2k)) { // do not even try if already claimed if(c==0) { GlobalConfig->AtDiskPrimaryAddressClaimed = FALSE; @@ -8133,11 +8457,19 @@ DriverEntry( GlobalConfig->AtDiskSecondaryAddressClaimed = FALSE; } } - hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController; + if(!WinVer_WDM_Model) { + hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController; + } else { + // in WDM model things are different.... + hwInitializationData.comm.HwFindAdapter = (c == 0) ? + UniataFindCompatBusMasterController1 : UniataFindCompatBusMasterController2; + } hwInitializationData.comm.NumberOfAccessRanges = 6; hwInitializationData.comm.AdapterInterfaceType = Isa; - BMList[i].channel = (UCHAR)c; + if(!WinVer_WDM_Model) { + BMList[i].channel = (UCHAR)c; + } KdPrint2((PRINT_PREFIX "Try init channel %d, method %d\n", c, alt)); newStatus = ScsiPortInitialize(DriverObject, @@ -8158,7 +8490,7 @@ DriverEntry( */ } } - if(WinVer_Id() > WinVer_NT) { + if(WinVer_Id() >= WinVer_2k) { // the following doesn't work under higher OSes KdPrint2((PRINT_PREFIX "make still one attempt\n")); continue; @@ -8171,7 +8503,30 @@ DriverEntry( } // if (WinVer_Id() == WinVer_NT) and some error occured // try alternative init method + } // for(alt...) +#if 0 + if(WinVer_WDM_Model) { + hwInitializationData.comm.HwFindAdapter = UniataFindFakeBusMasterController; + hwInitializationData.comm.NumberOfAccessRanges = 5; + hwInitializationData.comm.AdapterInterfaceType = PCIBus; + + hwInitializationData.comm.VendorId = BMList[i].VendorId; + hwInitializationData.comm.VendorIdLength = (USHORT) BMList[i].VendorIdLength; + hwInitializationData.comm.DeviceId = BMList[i].DeviceId; + hwInitializationData.comm.DeviceIdLength = (USHORT) BMList[i].DeviceIdLength; + + //BMList[i].channel = 0/*(UCHAR)c*/; + + KdPrint2((PRINT_PREFIX "Try init fake: %4.4s %4.4s \n", + hwInitializationData.comm.VendorId, + hwInitializationData.comm.DeviceId)); + newStatus = ScsiPortInitialize(DriverObject, + Argument2, + &hwInitializationData.comm, + (PVOID)i); + KdPrint2((PRINT_PREFIX "Status %#x\n", newStatus)); } +#endif //0 if(g_opt_Verbose) { if(BMList[i].ChanInitOk & 0x03) { _PrintNtConsole(" OK\n"); @@ -8484,21 +8839,56 @@ AtapiRegCheckDevValue( HwDeviceExtension, L"Parameters", chan, dev, Name, val); if(deviceExtension) { - swprintf(namev, L"\\Ven_%4.4x", VendorID); - swprintf(named, L"\\Dev_%4.4x", DeviceID); - swprintf(names, L"\\Slot_%8.8x", SlotNumber); + if(deviceExtension->AdapterInterfaceType == PCIBus) { + // PCI + swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex); + swprintf(namex, L"Parameters%s", namev); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); - swprintf(namex, L"Parameters%s", namev); - val = AtapiRegCheckDevLunValue( - HwDeviceExtension, namex, chan, dev, Name, val); - swprintf(namex, L"Parameters%s%s", namev, named); - val = AtapiRegCheckDevLunValue( - HwDeviceExtension, namex, chan, dev, Name, val); + swprintf(namev, L"\\Ven_%4.4x", VendorID); + swprintf(named, L"\\Dev_%4.4x", DeviceID); + swprintf(names, L"\\Slot_%8.8x", SlotNumber); - swprintf(namex, L"Parameters%s%s%s", namev, named, names); - val = AtapiRegCheckDevLunValue( - HwDeviceExtension, namex, chan, dev, Name, val); + swprintf(namex, L"Parameters%s", namev); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + + swprintf(namex, L"Parameters%s%s", namev, named); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + + swprintf(namex, L"Parameters%s%s%s", namev, named, names); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + } else + if(deviceExtension->AdapterInterfaceType == Isa) { + // Isa + swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen); + swprintf(namex, L"Parameters%s", namev); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + + swprintf(namev, L"\\ISA_%d", deviceExtension->DevIndex); + swprintf(namex, L"Parameters%s", namev); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + + } else + if(deviceExtension->AdapterInterfaceType == MicroChannel) { + // MicroChannel + swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen+IsaCount); + swprintf(namex, L"Parameters%s", namev); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + + swprintf(namev, L"\\MCA_%d", deviceExtension->DevIndex); + swprintf(namex, L"Parameters%s", namev); + val = AtapiRegCheckDevLunValue( + HwDeviceExtension, namex, chan, dev, Name, val); + + } } KdPrint(( " Parameter %ws = %#x\n", Name, val)); @@ -8554,8 +8944,7 @@ AtapiRegCheckParameterValue( // KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer)); paramPath.Length = 0; - paramPath.MaximumLength = RegistryPath->Length + - (wcslen(PathSuffix)+2)*sizeof(WCHAR); + paramPath.MaximumLength = RegistryPath->Length + (wcslen(PathSuffix)+2)*sizeof(WCHAR); paramPath.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, paramPath.MaximumLength); if(!paramPath.Buffer) { KdPrint(("AtapiCheckRegValue: couldn't allocate paramPath\n")); @@ -8579,7 +8968,7 @@ AtapiRegCheckParameterValue( status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/, paramPath.Buffer, parameters, NULL, NULL); - KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun)); + //KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun)); ExFreePool(paramPath.Buffer); @@ -8645,8 +9034,11 @@ AtapiAdapterControl( AtapiResetController(deviceExtension, c); AtapiDisableInterrupts(deviceExtension, c); } - status = UniataDisconnectIntr2(HwDeviceExtension); - BMList[deviceExtension->DevIndex].Isr2Enable = FALSE; + if(deviceExtension->AdapterInterfaceType == PCIBus) { + // we must never get here for non-PCI + status = UniataDisconnectIntr2(HwDeviceExtension); + BMList[deviceExtension->DevIndex].Isr2Enable = FALSE; + } break; } case ScsiRestartAdapter: { @@ -8664,6 +9056,7 @@ AtapiAdapterControl( AtapiHwInitialize__(deviceExtension, c); } if(deviceExtension->Isr2DevObj) { + // we must never get here for non-PCI BMList[deviceExtension->DevIndex].Isr2Enable = TRUE; } @@ -8713,3 +9106,4 @@ _PrintNtConsole( } // end PrintNtConsole() + diff --git a/reactos/drivers/storage/ide/uniata/id_dma.cpp b/reactos/drivers/storage/ide/uniata/id_dma.cpp index 7f650a5a999..ae40fcd4918 100644 --- a/reactos/drivers/storage/ide/uniata/id_dma.cpp +++ b/reactos/drivers/storage/ide/uniata/id_dma.cpp @@ -176,7 +176,24 @@ err_1: } } #endif //USE_OWN_DMA - +/* + if(deviceExtension->HwFlags & UNIATA_AHCI) { + chan->AHCI_CLP = MmAllocateContiguousMemory(sizeof(((PATA_REQ)NULL)->dma_tab), ph4gb); + if(chan->AHCI_CLP) { + chan->DB_PRD_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->DB_PRD), &i, &ph_addru); + if(!chan->DB_PRD_PhAddr || !i || ((LONG)(chan->DB_PRD_PhAddr) == -1)) { + KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD BASE\n" )); + chan->DB_PRD = NULL; + chan->DB_PRD_PhAddr = 0; + return; + } + if(ph_addru) { + KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD below 4Gb\n" )); + goto err_1; + } + } + } +*/ return; } // end AtapiDmaAlloc() @@ -196,36 +213,45 @@ AtapiDmaSetup( PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension); BOOLEAN use_DB_IO = FALSE; + BOOLEAN use_AHCI = FALSE; ULONG orig_count = count; + ULONG max_entries = (deviceExtension->HwFlags & UNIATA_AHCI) ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES; AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION; - KdPrint2((PRINT_PREFIX "AtapiDmaSetup: mode %#x\n", deviceExtension->lun[lChannel*2+DeviceNumber].TransferMode )); + KdPrint2((PRINT_PREFIX "AtapiDmaSetup: mode %#x, data %x, count %x, lCh %x, dev %x\n", + deviceExtension->lun[lChannel*2+DeviceNumber].TransferMode, + data, count, lChannel, DeviceNumber )); if(deviceExtension->lun[lChannel*2+DeviceNumber].TransferMode < ATA_DMA) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: Not DMA mode, assume this is just preparation\n" )); //return FALSE; } + //KdPrint2((PRINT_PREFIX " checkpoint 1\n" )); if(!count) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: count=0\n" )); return FALSE; } + //KdPrint2((PRINT_PREFIX " checkpoint 2\n" )); if(count > deviceExtension->MaximumDmaTransferLength) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: deviceExtension->MaximumDmaTransferLength > count\n" )); return FALSE; } + //KdPrint2((PRINT_PREFIX " checkpoint 3\n" )); if((ULONG)data & deviceExtension->AlignmentMask) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: unaligned data: %#x (%#x)\n", data, deviceExtension->AlignmentMask)); return FALSE; } - // NOTE: This code is intended for 32-bit capable controllers only. - // 64-bit capable controllers shall be handled separately. + //KdPrint2((PRINT_PREFIX " checkpoint 4\n" )); + KdPrint2((PRINT_PREFIX " get Phys(PRD=%x)\n", &(AtaReq->dma_tab) )); dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)&(AtaReq->dma_tab) /*chan->dma_tab*/, &i, &dma_baseu); if(dma_baseu) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: SRB built-in PRD above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); - dma_base = chan->DB_PRD_PhAddr; - AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD; - i = 1; + if(!deviceExtension->Host64) { + dma_base = chan->DB_PRD_PhAddr; + AtaReq->Flags |= REQ_FLAG_DMA_DBUF_PRD; + i = 1; + } } else if(!dma_base || !i || ((LONG)(dma_base) == -1)) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No BASE\n" )); @@ -233,17 +259,23 @@ AtapiDmaSetup( } AtaReq->dma_base = dma_base; + KdPrint2((PRINT_PREFIX " get Phys(data=%x)\n", data )); dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu); if(dma_baseu) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: 1st block of buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); + if(!deviceExtension->Host64) { retry_DB_IO: - use_DB_IO = TRUE; - dma_base = chan->DB_IO_PhAddr; - data = (PUCHAR)(chan->DB_IO); + use_DB_IO = TRUE; + dma_base = chan->DB_IO_PhAddr; + data = (PUCHAR)(chan->DB_IO); + } else { + AtaReq->ahci_base64 = (ULONGLONG)dma_base | ((ULONGLONG)dma_baseu << 32); + } } else if(!dma_count || ((LONG)(dma_base) == -1)) { - AtaReq->dma_base = 0; KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No 1st block\n" )); + //AtaReq->dma_base = NULL; + AtaReq->ahci_base64 = NULL; return FALSE; } @@ -253,26 +285,37 @@ retry_DB_IO: i = 0; while (count) { - AtaReq->dma_tab[i].base = dma_base; - AtaReq->dma_tab[i].count = (dma_count & 0xffff); - i++; - if (i >= ATA_DMA_ENTRIES) { - AtaReq->dma_base = 0; + if(deviceExtension->HwFlags & UNIATA_AHCI) { + AtaReq->ahci_cmd.prd_tab[i].base = dma_base; + AtaReq->ahci_cmd.prd_tab[i].baseu = dma_baseu; + AtaReq->ahci_cmd.prd_tab[i].DBC = ((dma_count-1) & 0x3fffff); + } else { + AtaReq->dma_tab[i].base = dma_base; + AtaReq->dma_tab[i].count = (dma_count & 0xffff); + } + i++; + if (i >= max_entries) { KdPrint2((PRINT_PREFIX "too many segments in DMA table\n" )); + //AtaReq->dma_base = NULL; + AtaReq->ahci_base64 = NULL; return FALSE; } + KdPrint2((PRINT_PREFIX " get Phys(data[n]=%x)\n", data )); dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu); if(dma_baseu) { KdPrint2((PRINT_PREFIX "AtapiDmaSetup: block of buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); - if(use_DB_IO) { - KdPrint2((PRINT_PREFIX "AtapiDmaSetup: *ERROR* special buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); - return FALSE; + if(!deviceExtension->Host64) { + if(use_DB_IO) { + KdPrint2((PRINT_PREFIX "AtapiDmaSetup: *ERROR* special buffer above 4Gb: %8.8x%8.8x\n", dma_baseu, dma_base)); + return FALSE; + } + count = orig_count; + goto retry_DB_IO; } - count = orig_count; - goto retry_DB_IO; } else if(!dma_count || !dma_base || ((LONG)(dma_base) == -1)) { - AtaReq->dma_base = 0; + //AtaReq->dma_base = NULL; + AtaReq->ahci_base64 = NULL; KdPrint2((PRINT_PREFIX "AtapiDmaSetup: No NEXT block\n" )); return FALSE; } @@ -281,8 +324,16 @@ retry_DB_IO: data += min(count, PAGE_SIZE); count -= min(count, PAGE_SIZE); } - AtaReq->dma_tab[i].base = dma_base; - AtaReq->dma_tab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; + KdPrint2((PRINT_PREFIX " set TERM\n" )); + if(deviceExtension->HwFlags & UNIATA_AHCI) { + AtaReq->ahci_cmd.prd_tab[i].base = dma_base; + AtaReq->ahci_cmd.prd_tab[i].baseu = dma_baseu; + AtaReq->ahci_cmd.prd_tab[i].DBC = ((dma_count-1) & 0x3fffff); + } else { + AtaReq->dma_tab[i].base = dma_base; + AtaReq->dma_tab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; + } + AtaReq->dma_entries = i; if(use_DB_IO) { AtaReq->Flags |= REQ_FLAG_DMA_DBUF; @@ -405,7 +456,11 @@ AtapiDmaStart( if(AtaReq->Flags & REQ_FLAG_DMA_DBUF_PRD) { KdPrint2((PRINT_PREFIX " DBUF_PRD\n")); ASSERT(FALSE); - RtlCopyMemory(chan->DB_PRD, &(AtaReq->dma_tab), sizeof(AtaReq->dma_tab)); + if(deviceExtension->HwFlags & UNIATA_AHCI) { + RtlCopyMemory(chan->DB_PRD, &(AtaReq->ahci_cmd), sizeof(AtaReq->ahci_cmd)); + } else { + RtlCopyMemory(chan->DB_PRD, &(AtaReq->dma_tab), sizeof(AtaReq->dma_tab)); + } } if(!(Srb->SrbFlags & SRB_FLAGS_DATA_IN) && (AtaReq->Flags & REQ_FLAG_DMA_DBUF)) { @@ -567,16 +622,25 @@ limit_lba48: LunExt->DeviceFlags |= REQ_FLAG_FORCE_DOWNRATE_LBA48; limit_pio: // do not make extra work if we already use PIO - KdPrint2((PRINT_PREFIX - "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x)\n", ldev & 1, LunExt->TransferMode, ATA_PIO0+apiomode)); if(/*LunExt->TransferMode >= ATA_DMA*/ - LunExt->TransferMode != ATA_PIO0+apiomode + (LunExt->TransferMode > ATA_PIO5) && (LunExt->TransferMode != ATA_PIO0+apiomode) ) { + KdPrint2((PRINT_PREFIX + "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x)\n", ldev & 1, LunExt->TransferMode, ATA_PIO0+apiomode)); AtapiDmaInit(deviceExtension, ldev & 1, ldev >> 1, apiomode, -1, -1 ); + } else + if(LunExt->LimitedTransferMode < LunExt->TransferMode) { + KdPrint2((PRINT_PREFIX + "AtapiDmaReinit: set PIO mode on Device %d (%x -> %x) (2)\n", ldev & 1, LunExt->TransferMode, LunExt->LimitedTransferMode)); + AtapiDmaInit(deviceExtension, ldev & 1, ldev >> 1, + LunExt->LimitedTransferMode-ATA_PIO0, + -1, + -1 ); } + } else { KdPrint2((PRINT_PREFIX "AtapiDmaReinit: set MAX mode on Device %d\n", ldev & 1)); @@ -653,23 +717,23 @@ AtaSetTransferMode( IDE_COMMAND_SET_FEATURES, 0, 0, 0, (UCHAR)((mode > ATA_UDMA6) ? ATA_UDMA6 : mode), ATA_C_F_SETXFER, ATA_WAIT_BASE_READY); if(statusByte & IDE_STATUS_ERROR) { - KdPrint2((PRINT_PREFIX " wait ready after error\n")); + KdPrint3((PRINT_PREFIX " wait ready after error\n")); if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) { AtapiStallExecution(10); } else { AtapiStallExecution(100); } apiomode = (CHAR)AtaPioMode(&(LunExt->IdentifyData)); - if( apiomode > 0 && - (CHAR)AtaWmode(&(LunExt->IdentifyData)) > 0 && - (CHAR)AtaUmode(&(LunExt->IdentifyData)) > 0 + if( (apiomode > 0) && + ((CHAR)AtaWmode(&(LunExt->IdentifyData)) > 0) && + ((CHAR)AtaUmode(&(LunExt->IdentifyData)) > 0) ) { return FALSE; } if(mode > ATA_PIO2) { return FALSE; } - KdPrint2((PRINT_PREFIX " assume that drive doesn't support mode swithingm using PIO%d\n", apiomode)); + KdPrint3((PRINT_PREFIX " assume that drive doesn't support mode swithing using PIO%d\n", apiomode)); mode = ATA_PIO0 + apiomode; } //if(mode <= ATA_UDMA6) { @@ -780,7 +844,7 @@ AtapiDmaInit( goto try_generic_dma; } - if(deviceExtension->BaseIoAddressSATA_0.Addr) { + if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { //if(ChipFlags & UNIATA_SATA) { /****************/ /* SATA Generic */ @@ -1060,6 +1124,17 @@ set_new_acard: } /* Use GENERIC PIO */ break; + case ATA_NETCELL_ID: + /***********/ + /* NetCell */ + /***********/ + if (wdmamode >= 2 && apiomode >= 4) { + if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) { + return; + } + } + /* Use GENERIC PIO */ + break; case ATA_HIGHPOINT_ID: { /********************/ /* High Point (HPT) */ @@ -1184,6 +1259,7 @@ set_new_acard: if(ChipFlags & ICH4_FIX) { return; } + break; } } } @@ -1978,3 +2054,4 @@ via82c_timing( SetPciConfig1(0x4b-dev, (FIT(active - 1, 0, 0xf) << 4) | FIT(recover - 1, 0, 0xf) ); } // end via82c_timing() + diff --git a/reactos/drivers/storage/ide/uniata/id_init.cpp b/reactos/drivers/storage/ide/uniata/id_init.cpp index 11708307352..ce49d9a59e3 100644 --- a/reactos/drivers/storage/ide/uniata/id_init.cpp +++ b/reactos/drivers/storage/ide/uniata/id_init.cpp @@ -213,7 +213,7 @@ UniataChipDetect( case 0x06401095: /* CMD 640 known bad, no DMA */ case 0x06011039: - *simplexOnly = TRUE; + *simplexOnly = TRUE; /* FALLTHROUGH */ @@ -244,7 +244,7 @@ UniataChipDetect( i = Ata_is_dev_listed(DevTypeInfo, VendorID, DeviceID, RevID, -1); for_ugly_chips: KdPrint2((PRINT_PREFIX "i: %#x\n", i)); - if(i == 0xFFFFFFFF) { + if(i == BMLIST_TERMINATOR) { return FALSE; } deviceExtension->MaxTransferMode = DevTypeInfo[i].MaxTransferMode; @@ -556,7 +556,7 @@ for_ugly_chips: tmp32 == ATA_SIS5517) { i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION*)&SiSSouthAdapters[0], -1, HwDeviceExtension, SystemIoBusNumber, -1, NULL); - if(i != 0xFFFFFFFF) { + if(i != BMLIST_TERMINATOR) { deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD; //deviceExtension->MaxTransferMode = ATA_UDMA6; deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode; diff --git a/reactos/drivers/storage/ide/uniata/id_probe.cpp b/reactos/drivers/storage/ide/uniata/id_probe.cpp index 5b90d3593b4..9fd2e6fcfca 100644 --- a/reactos/drivers/storage/ide/uniata/id_probe.cpp +++ b/reactos/drivers/storage/ide/uniata/id_probe.cpp @@ -49,6 +49,8 @@ Revision History: PBUSMASTER_CONTROLLER_INFORMATION BMList = NULL; ULONG BMListLen = 0; +ULONG IsaCount = 0; +ULONG MCACount = 0; BOOLEAN FirstMasterOk = FALSE; @@ -59,7 +61,7 @@ ULONG maxPciBus = 16; PDRIVER_OBJECT SavedDriverObject = NULL; -// local routines +// local routines ULONG UniataEnumBusMasterController__( @@ -171,6 +173,40 @@ UniataEnumBusMasterController( } // end UniataEnumBusMasterController() +BOOLEAN +UniataCheckPCISubclass( + BOOLEAN known, + ULONG RaidFlags, + UCHAR SubClass + ) +{ + if(known) { + if((RaidFlags & UNIATA_RAID_CONTROLLER) && + SkipRaids) { + KdPrint2((PRINT_PREFIX "Skip RAID\n")); + return FALSE; + } + return TRUE; + } + KdPrint2((PRINT_PREFIX "unknown\n")); + + switch(SubClass) { + case PCI_DEV_SUBCLASS_RAID: + if(SkipRaids) { + KdPrint2((PRINT_PREFIX "Skip RAID (2)\n")); + return FALSE; + } + break; + case PCI_DEV_SUBCLASS_IDE: + case PCI_DEV_SUBCLASS_ATA: + case PCI_DEV_SUBCLASS_SATA: + break; + default: + KdPrint2((PRINT_PREFIX "Subclass not supported\n")); + return FALSE; + } + return TRUE; +} // end UniataCheckPCISubclass() /* Device initializaton callback @@ -274,6 +310,7 @@ UniataEnumBusMasterController__( deviceExtension->SystemIoBusNumber = busNumber; deviceExtension->DevID = dev_id; deviceExtension->RevID = pciData.RevisionID; + deviceExtension->AdapterInterfaceType = PCIBus; } found = (BOOLEAN)AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Include", 0); @@ -289,26 +326,16 @@ UniataEnumBusMasterController__( //known = UniataChipDetect(HwDeviceExtension, NULL, -1, ConfigInfo, &SimplexOnly); i = Ata_is_dev_listed((PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[0], VendorID, DeviceID, 0, NUM_BUSMASTER_ADAPTERS); - known = (i != 0xFFFFFFFF); + known = (i != BMLIST_TERMINATOR); if(known) { + deviceExtension->FullDevName = BusMasterAdapters[i].FullDevName; RaidFlags = BusMasterAdapters[i].RaidFlags; - if((RaidFlags & UNIATA_RAID_CONTROLLER) && - SkipRaids) { - KdPrint2((PRINT_PREFIX "Skip RAID\n")); - continue; - } - found = TRUE; } else { + deviceExtension->FullDevName = "Unknown Storage"; RaidFlags = 0; } - - switch(SubClass) { - case PCI_DEV_SUBCLASS_IDE: - case PCI_DEV_SUBCLASS_RAID: - case PCI_DEV_SUBCLASS_ATA: - case PCI_DEV_SUBCLASS_SATA: - break; - default: + found = UniataCheckPCISubclass(known, RaidFlags, SubClass); + if(!found) { KdPrint2((PRINT_PREFIX "Subclass not supported\n")); continue; } @@ -388,8 +415,9 @@ UniataEnumBusMasterController__( PBUSMASTER_CONTROLLER_INFORMATION newBMListPtr = BMList+BMListLen; if(pass == 1) { - if(!IsMasterDev(&pciData)) + if(!IsMasterDev(&pciData)) { continue; + } if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NativePCIMode", 0)) { KdPrint2((PRINT_PREFIX "try switch to native mode\n")); @@ -495,6 +523,8 @@ UniataEnumBusMasterController__( newBMListPtr->MasterDev = IsMasterDev(&pciData) ? 1 : 0; newBMListPtr->busNumber = busNumber; + newBMListPtr->Known = known; + KdPrint2((PRINT_PREFIX "Add to BMList\n")); } else { KdPrint2((PRINT_PREFIX "count: BMListLen++\n")); @@ -519,6 +549,7 @@ UniataEnumBusMasterController__( BMListLen=0; } } + KdPrint2((PRINT_PREFIX " BMListLen=%x\n", BMListLen)); if(deviceExtension) { ExFreePool(deviceExtension); } @@ -591,7 +622,7 @@ AtapiFindListedDev( ULONG i; // set start/end bus - if(BusNumber == 0xFFFFFFFF) { + if(BusNumber == PCIBUSNUM_NOT_SPECIFIED) { busNumber = 0; busNumber2 = maxPciBus; } else { @@ -599,7 +630,7 @@ AtapiFindListedDev( busNumber2 = BusNumber+1; } // set start/end slot - if(SlotNumber == 0xFFFFFFFF) { + if(SlotNumber == PCISLOTNUM_NOT_SPECIFIED) { slotNumber = 0; slotNumber2 = PCI_MAX_DEVICES; } else { @@ -631,7 +662,7 @@ AtapiFindListedDev( continue; i = Ata_is_dev_listed(BusMasterAdapters, pciData.VendorID, pciData.DeviceID, pciData.RevisionID, lim); - if(i != 0xFFFFFFFF) { + if(i != BMLIST_TERMINATOR) { if(_slotData) *_slotData = slotData; return i; @@ -696,6 +727,47 @@ AtapiFindDev( #endif //UNIATA_CORE + +ULONG +UniataFindCompatBusMasterController1( + IN PVOID HwDeviceExtension, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ) +{ + return UniataFindBusMasterController( + HwDeviceExtension, + (PVOID)0x00000000, + BusInformation, + ArgumentString, + ConfigInfo, + Again + ); +} // end UniataFindCompatBusMasterController1() + +ULONG +UniataFindCompatBusMasterController2( + IN PVOID HwDeviceExtension, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ) +{ + return UniataFindBusMasterController( + HwDeviceExtension, + (PVOID)0x80000000, + BusInformation, + ArgumentString, + ConfigInfo, + Again + ); +} // end UniataFindCompatBusMasterController2() + /*++ Routine Description: @@ -764,7 +836,7 @@ UniataFindBusMasterController( BOOLEAN found = FALSE; BOOLEAN MasterDev; BOOLEAN simplexOnly = FALSE; - //BOOLEAN skip_find_dev = FALSE; + BOOLEAN skip_find_dev = FALSE; BOOLEAN AltInit = FALSE; SCSI_PHYSICAL_ADDRESS IoBasePort1; @@ -781,21 +853,31 @@ UniataFindBusMasterController( PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo = (PPORT_CONFIGURATION_INFORMATION_COMMON)ConfigInfo; - *Again = FALSE; + if(!WinVer_WDM_Model) { + *Again = FALSE; + } else { + *Again = TRUE; + } + + KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context, BMListLen)); if(ForceSimplex) { KdPrint2((PRINT_PREFIX "ForceSimplex (1)\n")); simplexOnly = TRUE; } + if(ConfigInfo->AdapterInterfaceType == Isa) { + KdPrint2((PRINT_PREFIX "AdapterInterfaceType: Isa\n")); + } if(InDriverEntry) { i = (ULONG)Context; if(i & 0x80000000) { AltInit = TRUE; } i &= ~0x80000000; - channel = BMList[i].channel; + channel = BMList[i].channel; } else { + channel = 0; for(i=0; iSlotNumber && BMList[i].busNumber == ConfigInfo->SystemIoBusNumber) { @@ -803,15 +885,23 @@ UniataFindBusMasterController( } } if(i >= BMListLen) { - KdPrint2((PRINT_PREFIX "unexpected device arrival => SP_RETURN_NOT_FOUND\n")); - return(SP_RETURN_NOT_FOUND); + KdPrint2((PRINT_PREFIX "unexpected device arrival\n")); + i = (ULONG)Context; + if(FirstMasterOk) { + channel = 1; + } + i &= ~0x80000000; + if(i >= BMListLen) { + KdPrint2((PRINT_PREFIX " => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } } - channel = 0; + BMList[i].channel = (UCHAR)channel; } bm_offset = channel ? ATA_BM_OFFSET1 : 0; - KdPrint2((PRINT_PREFIX "UniataFindBusMasterController\n")); + KdPrint2((PRINT_PREFIX "bm_offset %x, channel %x \n", bm_offset, channel)); if (!deviceExtension) { KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n")); @@ -867,6 +957,7 @@ UniataFindBusMasterController( deviceExtension->DevID = dev_id; deviceExtension->RevID = RevID; deviceExtension->NumberChannels = 2; // default + deviceExtension->DevIndex = i; _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature), "UATA%8.8x/%1.1x@%8.8x", dev_id, channel, slotNumber); @@ -885,20 +976,8 @@ UniataFindBusMasterController( return(SP_RETURN_NOT_FOUND); } - if((BMList[i].RaidFlags & UNIATA_RAID_CONTROLLER) && - SkipRaids) { - KdPrint2((PRINT_PREFIX "RAID support disabled\n")); - return(SP_RETURN_NOT_FOUND); - } - - switch(SubClass) { - case PCI_DEV_SUBCLASS_IDE: - case PCI_DEV_SUBCLASS_RAID: - case PCI_DEV_SUBCLASS_ATA: - case PCI_DEV_SUBCLASS_SATA: - // ok - break; - default: + found = UniataCheckPCISubclass(BMList[i].Known, BMList[i].RaidFlags, SubClass); + if(!found) { KdPrint2((PRINT_PREFIX "Subclass not supported\n")); return(SP_RETURN_NOT_FOUND); } @@ -959,7 +1038,7 @@ UniataFindBusMasterController( MasterDev = IsMasterDev(&pciData); if(MasterDev) { - KdPrint2((PRINT_PREFIX "MasterDev\n")); + KdPrint2((PRINT_PREFIX "MasterDev (1)\n")); deviceExtension->MasterDev = TRUE; deviceExtension->NumberChannels = 1; } @@ -987,6 +1066,53 @@ UniataFindBusMasterController( } } else { deviceExtension->BusMaster = FALSE; + + if(WinVer_WDM_Model && !deviceExtension->UnknownDev) { + ULONG i; + // Enable Busmastering, IO-space and Mem-space + KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n")); + KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData.Command)); + for(i=0; i<3; i++) { + switch(i) { + case 0: + KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n")); + pciData.Command |= PCI_ENABLE_IO_SPACE; + break; + case 1: + KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n")); + pciData.Command |= PCI_ENABLE_MEMORY_SPACE; + break; + case 2: + KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n")); + pciData.Command |= PCI_ENABLE_BUS_MASTER; + break; + } + HalSetBusDataByOffset( PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG, + &(pciData.Command), + offsetof(PCI_COMMON_CONFIG, Command), + sizeof(pciData.Command)); + KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine)); + + // reread config space + busDataRead = HalGetBusData(PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG, + &pciData, PCI_COMMON_HDR_LENGTH); + KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData.Command)); + } + KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData.Command)); + } + // validate Mem/Io ranges + //no_ranges = TRUE; + { + ULONG i; + for(i=0; isimplexOnly; deviceExtension->simplexOnly |= simplexOnly; @@ -1062,6 +1188,7 @@ UniataFindBusMasterController( if(simplexOnly || !MasterDev /*|| (WinVer_Id() > WinVer_NT)*/) { if(deviceExtension->NumberChannels < 2) { + KdPrint2((PRINT_PREFIX "set NumberChannels = 2\n")); deviceExtension->NumberChannels = 2; if(BaseIoAddressBM_0) { UniataInitMapBM(deviceExtension, @@ -1086,7 +1213,7 @@ UniataFindBusMasterController( ConfigInfo->MaximumNumberOfTargets = (UCHAR)(/*deviceExtension->NumberChannels **/ 2); if (MasterDev) { - KdPrint2((PRINT_PREFIX "MasterDev\n")); + KdPrint2((PRINT_PREFIX "MasterDev (2)\n")); /* if((WinVer_Id() > WinVer_NT) || (deviceExtension->NumberChannels > 1)) { @@ -1167,6 +1294,7 @@ UniataFindBusMasterController( deviceExtension->OrigAdapterInterfaceType = ConfigInfo->AdapterInterfaceType; deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask; + deviceExtension->AdapterInterfaceType = PCIBus; found = FALSE; @@ -1216,6 +1344,8 @@ UniataFindBusMasterController( // in order to add support for multichannel controllers we must rewrite // io-range claiming algorithm + KdPrint2((PRINT_PREFIX "BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList[i].channel, deviceExtension->NumberChannels, channel)); + for (; channel < (BMList[i].channel + deviceExtension->NumberChannels); channel++, c++) { KdPrint2((PRINT_PREFIX "de %#x, Channel %#x\n",deviceExtension, channel)); @@ -1481,6 +1611,18 @@ exit_findbm: KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n", MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj)); + if(WinVer_WDM_Model && MasterDev) { + KdPrint2((PRINT_PREFIX "do not tell system, that we know about this:\n")); + if(BaseIoAddressBM_0) { + ScsiPortFreeDeviceBase(HwDeviceExtension, + BaseIoAddressBM_0); + } + (*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); + (*ConfigInfo->AccessRanges)[4].RangeLength = 0; + (*ConfigInfo->AccessRanges)[5].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0); + (*ConfigInfo->AccessRanges)[5].RangeLength = 0; + } + if(!NT_SUCCESS(status)) { KdPrint2((PRINT_PREFIX "failed\n")); found = FALSE; @@ -1497,11 +1639,330 @@ exit_findbm: FirstMasterOk = TRUE; } + ConfigInfo->NumberOfBuses++; // add virtual channel for communication port return SP_RETURN_FOUND; } // end UniataFindBusMasterController() #ifndef UNIATA_CORE + +/* + This is for claiming PCI Busmaster in compatible mode under WDM OSes +*/ +ULONG +UniataFindFakeBusMasterController( + IN PVOID HwDeviceExtension, + IN PVOID Context, + IN PVOID BusInformation, + IN PCHAR ArgumentString, + IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, + OUT PBOOLEAN Again + ) +{ + PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; + PHW_CHANNEL chan = NULL; + // this buffer must be global for UNIATA_CORE build + PCI_COMMON_CONFIG pciData; + + ULONG slotNumber; + ULONG busDataRead; + ULONG SystemIoBusNumber; + + UCHAR vendorString[5]; + UCHAR deviceString[5]; + PUCHAR vendorStrPtr; + PUCHAR deviceStrPtr; + + UCHAR BaseClass; + UCHAR SubClass; + ULONG VendorID; + ULONG DeviceID; + ULONG RevID; + ULONG dev_id; + PCI_SLOT_NUMBER slotData; + + ULONG i; +// PUCHAR ioSpace; +// UCHAR statusByte; + +// UCHAR tmp8; +// ULONG irq; + + BOOLEAN found = FALSE; + BOOLEAN MasterDev; + BOOLEAN simplexOnly = FALSE; + BOOLEAN skip_find_dev = FALSE; + BOOLEAN AltInit = FALSE; + + PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL; + +// NTSTATUS status; + PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo = + (PPORT_CONFIGURATION_INFORMATION_COMMON)ConfigInfo; + + *Again = FALSE; + + if(InDriverEntry) { + i = (ULONG)Context; + } else { + for(i=0; iSlotNumber && + BMList[i].busNumber == ConfigInfo->SystemIoBusNumber) { + break; + } + } + if(i >= BMListLen) { + KdPrint2((PRINT_PREFIX "unexpected device arrival => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } + } + + KdPrint2((PRINT_PREFIX "UniataFindFakeBusMasterController (WDM)\n")); + + if (!deviceExtension) { + KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n")); + return SP_RETURN_ERROR; + } + + RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION)); + + vendorStrPtr = vendorString; + deviceStrPtr = deviceString; + + slotNumber = BMList[i].slotNumber; + SystemIoBusNumber = BMList[i].busNumber; + + KdPrint2((PRINT_PREFIX "AdapterInterfaceType=%#x\n",ConfigInfo->AdapterInterfaceType)); + KdPrint2((PRINT_PREFIX "IoBusNumber=%#x\n",ConfigInfo->SystemIoBusNumber)); + KdPrint2((PRINT_PREFIX "slotNumber=%#x\n",slotNumber)); + + // this buffer must be global and already filled for UNIATA_CORE build + busDataRead = HalGetBusData( + //busDataRead = ScsiPortGetBusData(HwDeviceExtension, + PCIConfiguration, + SystemIoBusNumber, + slotNumber, + &pciData, + PCI_COMMON_HDR_LENGTH); + + if (busDataRead < PCI_COMMON_HDR_LENGTH) { + KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n")); + return SP_RETURN_ERROR; + } + + KdPrint2((PRINT_PREFIX "busDataRead\n")); + if (pciData.VendorID == PCI_INVALID_VENDORID) { + KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n")); + return SP_RETURN_ERROR; + } + + VendorID = pciData.VendorID; + DeviceID = pciData.DeviceID; + BaseClass = pciData.BaseClass; + SubClass = pciData.SubClass; + RevID = pciData.RevisionID; + dev_id = VendorID | (DeviceID << 16); + slotData.u.AsULONG = slotNumber; + KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass )); + + deviceExtension->slotNumber = slotNumber; + deviceExtension->SystemIoBusNumber = SystemIoBusNumber; + deviceExtension->DevID = dev_id; + deviceExtension->RevID = RevID; + deviceExtension->NumberChannels = 2; // default + deviceExtension->DevIndex = i; + + _snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature), + "UATA%8.8x/%1.1x@%8.8x", dev_id, 0xff, slotNumber); + + if(BaseClass != PCI_DEV_CLASS_STORAGE) { + KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } + + KdPrint2((PRINT_PREFIX "Storage Class\n")); + + // look for known chipsets + if(VendorID != BMList[i].nVendorId || + DeviceID != BMList[i].nDeviceId) { + KdPrint2((PRINT_PREFIX "device not suitable\n")); + return(SP_RETURN_NOT_FOUND); + } + + if((BMList[i].RaidFlags & UNIATA_RAID_CONTROLLER) && + SkipRaids) { + KdPrint2((PRINT_PREFIX "RAID support disabled\n")); + return(SP_RETURN_NOT_FOUND); + } + + switch(SubClass) { + case PCI_DEV_SUBCLASS_IDE: + case PCI_DEV_SUBCLASS_RAID: + case PCI_DEV_SUBCLASS_ATA: + case PCI_DEV_SUBCLASS_SATA: + // ok + break; + default: + KdPrint2((PRINT_PREFIX "Subclass not supported\n")); + return(SP_RETURN_NOT_FOUND); + } + + ConfigInfo->AlignmentMask = 0x00000003; + + found = UniataChipDetect(HwDeviceExtension, &pciData, i, ConfigInfo, &simplexOnly); + KdPrint2((PRINT_PREFIX "ForceSimplex = %d\n", simplexOnly)); + KdPrint2((PRINT_PREFIX "HwFlags = %x\n (0)", deviceExtension->HwFlags)); + switch(dev_id) { + /* additional checks for some supported chipsets */ + case 0xc6931080: + if (SubClass != PCI_DEV_SUBCLASS_IDE) { + KdPrint2((PRINT_PREFIX "0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n")); + found = FALSE; + } else { + found = FALSE; + } + break; + + /* unknown chipsets, try generic DMA if it seems possible */ + default: + if (found) + break; + KdPrint2((PRINT_PREFIX "Default device\n")); + if(!Ata_is_supported_dev(&pciData)) { + KdPrint2((PRINT_PREFIX "!Ata_is_supported_dev => found = FALSE\n")); + found = FALSE; + } else { + KdPrint2((PRINT_PREFIX "Ata_is_supported_dev\n")); + found = TRUE; + } + deviceExtension->UnknownDev = TRUE; + break; + } + + KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags)); + if(!found) { + KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } + + KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags)); + KdPrint2((PRINT_PREFIX "found suitable device\n")); + + /***********************************************************/ + /***********************************************************/ + /***********************************************************/ + + deviceExtension->UseDpc = TRUE; + KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags)); + if(deviceExtension->HwFlags & UNIATA_NO_DPC) { + /* CMD 649, ROSB SWK33, ICH4 */ + KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: UNIATA_NO_DPC (0)\n")); + deviceExtension->UseDpc = FALSE; + } + + MasterDev = IsMasterDev(&pciData); + + if(MasterDev) { + KdPrint2((PRINT_PREFIX "MasterDev\n")); + deviceExtension->MasterDev = TRUE; + deviceExtension->NumberChannels = 1; + } else { + KdPrint2((PRINT_PREFIX "!MasterDev => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } + + if(deviceExtension->AltRegMap) { + KdPrint2((PRINT_PREFIX " Non-standard registers layout => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } + if(IsBusMaster(&pciData)) { + KdPrint2((PRINT_PREFIX " !BusMaster => SP_RETURN_NOT_FOUND\n")); + return(SP_RETURN_NOT_FOUND); + } + + KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE\n")); + BaseIoAddressBM_0 = (PIDE_BUSMASTER_REGISTERS) + (AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber, + 4, 0, 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id + if(BaseIoAddressBM_0) { + UniataInitMapBM(deviceExtension, + BaseIoAddressBM_0, + (*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE); + deviceExtension->BusMaster = TRUE; + deviceExtension->BaseIoAddressBM_0.Addr = (ULONG)BaseIoAddressBM_0; + if((*ConfigInfo->AccessRanges)[4].RangeInMemory) { + deviceExtension->BaseIoAddressBM_0.MemIo = TRUE; + } + } + KdPrint2((PRINT_PREFIX " BusMasterAddress (base): %#x\n", BaseIoAddressBM_0)); + + /* + * the Cypress chip is a mess, it contains two ATA functions, but + * both channels are visible on the first one. + * simply ignore the second function for now, as the right + * solution (ignoring the second channel on the first function) + * doesn't work with the crappy ATA interrupt setup on the alpha. + */ + if (dev_id == 0xc6931080 && slotData.u.bits.FunctionNumber > 1) { + KdPrint2((PRINT_PREFIX "dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n")); + goto exit_findbm; + } + + // Indicate number of buses. + ConfigInfo->NumberOfBuses = 0; + if(!ConfigInfo->InitiatorBusId[0]) { + ConfigInfo->InitiatorBusId[0] = (CHAR)(IoGetConfigurationInformation()->ScsiPortCount); + KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0])); + } + // Indicate four devices can be attached to the adapter + ConfigInfo->MaximumNumberOfTargets = 0; + + ConfigInfo->MultipleRequestPerLu = FALSE; + ConfigInfo->AutoRequestSense = FALSE; + ConfigInfo->TaggedQueuing = FALSE; + + if((WinVer_Id() >= WinVer_NT) || + (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4))) { + _ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION); + _ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION); + _ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ); + } + if((WinVer_Id() > WinVer_2k) || + (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) { + _ConfigInfo->w2k.Dma64BitAddresses = 0; + _ConfigInfo->w2k.ResetTargetSupported = FALSE; + _ConfigInfo->w2k.MaximumNumberOfLogicalUnits = 0; + } + + // Save the Interrupe Mode for later use + deviceExtension->InterruptMode = ConfigInfo->InterruptMode; + deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel; + deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector; + deviceExtension->Channel = 0; + deviceExtension->DevIndex = i; + deviceExtension->OrigAdapterInterfaceType + = ConfigInfo->AdapterInterfaceType; + deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask; + deviceExtension->AdapterInterfaceType = PCIBus; + + KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n")); + ConfigInfo->MapBuffers = TRUE; +#ifdef USE_OWN_DMA + ConfigInfo->NeedPhysicalAddresses = FALSE; +#else + ConfigInfo->NeedPhysicalAddresses = TRUE; +#endif //USE_OWN_DMA + +exit_findbm: + + KdPrint2((PRINT_PREFIX "return SP_RETURN_FOUND\n")); + //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]); + + return SP_RETURN_FOUND; + +} // end UniataFindFakeBusMasterController() + + /*++ Routine Description: @@ -1716,6 +2177,10 @@ AtapiFindController( deviceExtension->MaxTransferMode = ATA_PIO4; deviceExtension->NumberChannels = 1; + deviceExtension->AdapterInterfaceType = + deviceExtension->OrigAdapterInterfaceType + = ConfigInfo->AdapterInterfaceType; + #ifndef UNIATA_CORE /* do extra chipset specific setups */ @@ -1754,6 +2219,7 @@ AtapiFindController( // Since we have pre-configured information we only need to go through this loop once preConfig = TRUE; portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart); + KdPrint2((PRINT_PREFIX " preconfig, portBase=%x\n", portBase)); } #ifndef UNIATA_CORE @@ -1763,7 +2229,11 @@ AtapiFindController( #endif //UNIATA_CORE retryCount = 4; + deviceExtension->DevIndex = (*adapterCount); + portBase = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", portBase); + irq = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", irq); + for (i = 0; i < 4; i++) { // Zero device fields to ensure that if earlier devices were found, // but not claimed, the fields are cleared. @@ -1791,7 +2261,7 @@ AtapiFindController( TRUE); } - }// ConfigInfo check + } BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace; // Update the adapter count. @@ -1816,16 +2286,30 @@ AtapiFindController( // Get the system physical address for the second IO range. if (BaseIoAddress1) { - ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, - ConfigInfo->AdapterInterfaceType, - ConfigInfo->SystemIoBusNumber, - ScsiPortConvertUlongToPhysicalAddress((ULONG)BaseIoAddress1 + ATA_ALTOFFSET), - ATA_ALTIOSIZE, - TRUE); + if(preConfig && + !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) { + KdPrint2((PRINT_PREFIX "AtapiFindController: PCMCIA ?\n")); + ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, + ConfigInfo->AdapterInterfaceType, + ConfigInfo->SystemIoBusNumber, + ScsiPortConvertUlongToPhysicalAddress((ULONG)BaseIoAddress1 + 0x0E), + ATA_ALTIOSIZE, + TRUE); + } else { + ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension, + ConfigInfo->AdapterInterfaceType, + ConfigInfo->SystemIoBusNumber, + ScsiPortConvertUlongToPhysicalAddress((ULONG)BaseIoAddress1 + ATA_ALTOFFSET), + ATA_ALTIOSIZE, + TRUE); + } } BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace; + KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1)); + KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2)); UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2); + UniataInitMapBM(deviceExtension, 0, FALSE); retryIdentifier: @@ -1993,8 +2477,8 @@ not_found: "AtapiFindController: look for devices\n")); // Search for devices on this controller. if (FindDevices(HwDeviceExtension, - /*atapiOnly*/ FALSE, - 0)) { + 0, + 0 /* Channel */)) { KdPrint2((PRINT_PREFIX "AtapiFindController: detected\n")); @@ -2022,7 +2506,14 @@ not_found: } } - KdPrint2((PRINT_PREFIX + if(deviceExtension->AdapterInterfaceType == Isa) { + IsaCount++; + } else + if(deviceExtension->AdapterInterfaceType == MicroChannel) { + MCACount++; + } + + KdPrint2((PRINT_PREFIX "AtapiFindController: return SP_RETURN_FOUND\n")); return(SP_RETURN_FOUND); } @@ -2047,41 +2538,55 @@ not_found: BOOLEAN UniataAnybodyHome( IN PVOID HwDeviceExtension, - IN ULONG Channel, + IN ULONG lChannel, IN ULONG deviceNumber ) { PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; - PHW_CHANNEL chan = &(deviceExtension->chan[Channel]); - ULONG ldev = GET_LDEV2(Channel, deviceNumber, 0); + PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); + ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0); PHW_LU_EXTENSION LunExt = &(deviceExtension->lun[ldev]); SATA_SSTATUS_REG SStatus; UCHAR signatureLow; + UCHAR signatureHigh; + if(LunExt->DeviceFlags & DFLAGS_HIDDEN) { + KdPrint2((PRINT_PREFIX " hidden\n")); + UniataForgetDevice(LunExt); + return FALSE; + } // Select the device. SelectDrive(chan, deviceNumber); - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow); + signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh); + + if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) { + KdPrint2((PRINT_PREFIX " ATAPI at home\n", signatureLow)); + return TRUE; + } + + if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { AtapiStallExecution(10); - AtapiWritePort1(chan, IDX_IO1_o_BlockCount, 0x55); - AtapiWritePort1(chan, IDX_IO1_o_BlockCount, 0x55); + AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55); + AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0x55); AtapiStallExecution(5); - signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockCount); + signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); if(signatureLow != 0x55) { KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow)); - LunExt->DeviceFlags = 0; + UniataForgetDevice(LunExt); return FALSE; } - AtapiWritePort1(chan, IDX_IO1_o_BlockCount, 0xAA); - AtapiWritePort1(chan, IDX_IO1_o_BlockCount, 0xAA); + AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA); + AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, 0xAA); AtapiStallExecution(5); - signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockCount); + signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber); if(signatureLow != 0xAA) { KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow)); - LunExt->DeviceFlags = 0; + UniataForgetDevice(LunExt); return FALSE; } } else { @@ -2108,14 +2613,14 @@ UniataAnybodyHome( ULONG CheckDevice( IN PVOID HwDeviceExtension, - IN ULONG Channel, + IN ULONG lChannel, IN ULONG deviceNumber, IN BOOLEAN ResetDev ) { PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; - PHW_CHANNEL chan = &(deviceExtension->chan[Channel]); - ULONG ldev = GET_LDEV2(Channel, deviceNumber, 0); + PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]); + ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0); PHW_LU_EXTENSION LunExt = &(deviceExtension->lun[ldev]); UCHAR signatureLow, @@ -2131,7 +2636,7 @@ CheckDevice( // Reset device AtapiSoftReset(chan, deviceNumber); - if(!UniataAnybodyHome(HwDeviceExtension, Channel, deviceNumber)) { + if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { return 0; } statusByte = WaitOnBusy(chan); @@ -2148,17 +2653,17 @@ CheckDevice( } if((statusByte | IDE_STATUS_BUSY) == 0xff) { - KdPrint2((PRINT_PREFIX + KdPrint2((PRINT_PREFIX "CheckDevice: no dev ?\n")); } else - if(deviceExtension->BaseIoAddressSATA_0.Addr) { + if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { //if(deviceExtension->HwFlags & UNIATA_SATA) { KdPrint2((PRINT_PREFIX "CheckDevice: try enable SATA Phy\n")); - statusByte = UniataSataPhyEnable(HwDeviceExtension, Channel); + statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel); if(statusByte == 0xff) { KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte)); - LunExt->DeviceFlags = 0; + UniataForgetDevice(LunExt); return 0; } } @@ -2166,7 +2671,7 @@ CheckDevice( // Select the device. SelectDrive(chan, deviceNumber); - if(!UniataAnybodyHome(HwDeviceExtension, Channel, deviceNumber)) { + if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) { return 0; } @@ -2174,14 +2679,14 @@ CheckDevice( GetBaseStatus(chan, statusByte); if(deviceExtension->HwFlags & UNIATA_SATA) { - UniataSataClearErr(HwDeviceExtension, Channel, UNIATA_SATA_IGNORE_CONNECT); + UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT); } KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte)); if(((statusByte | IDE_STATUS_BUSY) == 0xff) || (statusByte & IDE_STATUS_BUSY)) { KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n")); - LunExt->DeviceFlags = 0; + UniataForgetDevice(LunExt); return 0; } @@ -2205,7 +2710,7 @@ CheckDevice( // Issue ATAPI packet identify command. if (IssueIdentify(HwDeviceExtension, deviceNumber, - Channel, + lChannel, IDE_COMMAND_ATAPI_IDENTIFY, FALSE)) { // Indicate ATAPI device. @@ -2234,7 +2739,7 @@ CheckDevice( KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n", deviceNumber)); - LunExt->DeviceFlags = 0; + UniataForgetDevice(LunExt); RetVal = 0; } GetBaseStatus(chan, statusByte); @@ -2252,7 +2757,7 @@ CheckDevice( } if (IssueIdentify(HwDeviceExtension, deviceNumber, - Channel, + lChannel, IDE_COMMAND_IDENTIFY, FALSE)) { // IDE drive found. @@ -2292,12 +2797,13 @@ Return Value: BOOLEAN FindDevices( IN PVOID HwDeviceExtension, - IN BOOLEAN AtapiOnly, + IN ULONG Flags, IN ULONG Channel ) { PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; PHW_CHANNEL chan = &(deviceExtension->chan[Channel]); + PHW_LU_EXTENSION LunExt; BOOLEAN deviceResponded = FALSE, skipSetParameters = FALSE; ULONG waitCount = 10000; @@ -2306,6 +2812,7 @@ FindDevices( UCHAR statusByte; ULONG ldev; ULONG max_ldev; + BOOLEAN AtapiOnly = FALSE; KdPrint2((PRINT_PREFIX "FindDevices:\n")); @@ -2322,64 +2829,69 @@ FindDevices( // Search for devices. for (i = 0; i < max_ldev; i++) { AtapiDisableInterrupts(deviceExtension, Channel); - deviceResponded |= + if(Flags & UNIATA_FIND_DEV_UNHIDE) { + ldev = GET_LDEV2(Channel, i, 0); + deviceExtension->lun[ldev].DeviceFlags &= ~DFLAGS_HIDDEN; + } + deviceResponded |= (CheckDevice(HwDeviceExtension, Channel, i, TRUE) != 0); AtapiEnableInterrupts(deviceExtension, Channel); } for (i = 0; i < max_ldev; i++) { ldev = GET_LDEV2(Channel, i, 0); + LunExt = &(deviceExtension->lun[ldev]); - if (( deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT) && - !(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_LBA_ENABLED) && - !(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) { + if (( LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) && + !(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) && + !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) { // This hideous hack is to deal with ESDI devices that return // garbage geometry in the IDENTIFY data. // This is ONLY for the crashdump environment as // these are ESDI devices. - if (deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack == + if (LunExt->IdentifyData.SectorsPerTrack == 0x35 && - deviceExtension->lun[ldev].IdentifyData.NumberOfHeads == + LunExt->IdentifyData.NumberOfHeads == 0x07) { - KdPrint2((PRINT_PREFIX + KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n")); // Change these values to something reasonable. - deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack = + LunExt->IdentifyData.SectorsPerTrack = 0x34; - deviceExtension->lun[ldev].IdentifyData.NumberOfHeads = + LunExt->IdentifyData.NumberOfHeads = 0x0E; } - if (deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack == + if (LunExt->IdentifyData.SectorsPerTrack == 0x35 && - deviceExtension->lun[ldev].IdentifyData.NumberOfHeads == + LunExt->IdentifyData.NumberOfHeads == 0x0F) { - KdPrint2((PRINT_PREFIX + KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n")); // Change these values to something reasonable. - deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack = + LunExt->IdentifyData.SectorsPerTrack = 0x34; - deviceExtension->lun[ldev].IdentifyData.NumberOfHeads = + LunExt->IdentifyData.NumberOfHeads = 0x0F; } - if (deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack == + if (LunExt->IdentifyData.SectorsPerTrack == 0x36 && - deviceExtension->lun[ldev].IdentifyData.NumberOfHeads == + LunExt->IdentifyData.NumberOfHeads == 0x07) { KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n")); // Change these values to something reasonable. - deviceExtension->lun[ldev].IdentifyData.SectorsPerTrack = + LunExt->IdentifyData.SectorsPerTrack = 0x3F; - deviceExtension->lun[ldev].IdentifyData.NumberOfHeads = + LunExt->IdentifyData.NumberOfHeads = 0x10; skipSetParameters = TRUE; } @@ -2429,11 +2941,12 @@ FindDevices( "FindDevices: Set drive parameters for device %d failed\n", i)); // Don't use this device as writes could cause corruption. - deviceExtension->lun[ldev].DeviceFlags = 0; + LunExt->DeviceFlags &= ~DFLAGS_DEVICE_PRESENT; + UniataForgetDevice(&(deviceExtension->lun[ldev])); continue; } - if (deviceExtension->lun[ldev].DeviceFlags & DFLAGS_REMOVABLE_DRIVE) { + if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) { // Pick up ALL IDE removable drives that conform to Yosemite V0.2... AtapiOnly = FALSE; @@ -2461,23 +2974,22 @@ FindDevices( if(deviceResponded) { for (i = 0; i < max_ldev; i++) { ldev = GET_LDEV2(Channel, i, 0); + LunExt = &(deviceExtension->lun[ldev]); - if(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT) { - // Make sure some device (master is preferred) is selected on exit. - KdPrint2((PRINT_PREFIX - "FindDevices: select %d dev to clear INTR\n", i)); - SelectDrive(chan, i); - GetBaseStatus(chan, statusByte); - KdPrint2((PRINT_PREFIX - "FindDevices: statusByte=%#x\n", statusByte)); - } + KdPrint2((PRINT_PREFIX + "FindDevices: select %d dev to clear INTR\n", i)); + SelectDrive(chan, i); + GetBaseStatus(chan, statusByte); + KdPrint2((PRINT_PREFIX + "FindDevices: statusByte=%#x\n", statusByte)); } for (i = 0; i < max_ldev; i++) { ldev = GET_LDEV2(Channel, i, 0); + LunExt = &(deviceExtension->lun[ldev]); - if(deviceExtension->lun[ldev].DeviceFlags & DFLAGS_DEVICE_PRESENT) { + if(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) { // Make sure some device (master is preferred) is selected on exit. - KdPrint2((PRINT_PREFIX + KdPrint2((PRINT_PREFIX "FindDevices: select %d dev on exit\n", i)); SelectDrive(chan, i); break; diff --git a/reactos/drivers/storage/ide/uniata/id_queue.cpp b/reactos/drivers/storage/ide/uniata/id_queue.cpp index b68ac96600e..986ddb13554 100644 --- a/reactos/drivers/storage/ide/uniata/id_queue.cpp +++ b/reactos/drivers/storage/ide/uniata/id_queue.cpp @@ -350,7 +350,7 @@ UniataGetNextChannel( cost_c = chan->queue_depth * (chan->ChannelSelectWaitCount+1); } } - if(best_c == 0xFFFFFFFF) { + if(best_c == CHAN_NOT_SPECIFIED) { KdPrint2((PRINT_PREFIX " empty queues\n")); return NULL; } diff --git a/reactos/drivers/storage/ide/uniata/id_sata.cpp b/reactos/drivers/storage/ide/uniata/id_sata.cpp index eda1a661863..0611cdc3fa2 100644 --- a/reactos/drivers/storage/ide/uniata/id_sata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_sata.cpp @@ -19,7 +19,7 @@ UniataSataConnect( KdPrint2((PRINT_PREFIX "UniataSataConnect:\n")); - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { KdPrint2((PRINT_PREFIX " no I/O range\n")); return IDE_STATUS_IDLE; } @@ -73,7 +73,7 @@ UniataSataPhyEnable( KdPrint2((PRINT_PREFIX "UniataSataPhyEnable:\n")); - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { KdPrint2((PRINT_PREFIX " no I/O range\n")); return IDE_STATUS_IDLE; } @@ -130,7 +130,7 @@ UniataSataClearErr( SATA_SSTATUS_REG SStatus; SATA_SERROR_REG SError; - if(deviceExtension->BaseIoAddressSATA_0.Addr) { + if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) { //if(ChipFlags & UNIATA_SATA) { SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus); @@ -172,7 +172,7 @@ UniataSataEvent( UCHAR Status; ULONG ldev = lChannel*2; - if(!deviceExtension->BaseIoAddressSATA_0.Addr) { + if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) { return FALSE; } @@ -189,7 +189,7 @@ UniataSataEvent( break; case UNIATA_SATA_EVENT_DETACH: KdPrint2((PRINT_PREFIX " DISCONNECTED\n")); - deviceExtension->lun[ldev].DeviceFlags = 0; + UniataForgetDevice(&(deviceExtension->lun[ldev])); return TRUE; break; } @@ -287,3 +287,127 @@ UniataAhciInit( return TRUE; } // end UniataAhciInit() +UCHAR +UniataAhciStatus( + IN PVOID HwDeviceExtension, + IN ULONG lChannel + ) +{ + PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; + PHW_CHANNEL chan = &deviceExtension->chan[lChannel]; + ULONG Channel = deviceExtension->Channel + lChannel; + ULONG hIS; + ULONG CI; + AHCI_IS_REG IS; + SATA_SSTATUS_REG SStatus; + SATA_SERROR_REG SError; + ULONG offs = sizeof(IDE_AHCI_REGISTERS) + Channel*sizeof(IDE_AHCI_PORT_REGISTERS); + ULONG base; + ULONG tag=0; + + KdPrint(("UniataAhciStatus:\n")); + + hIS = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_IS); + KdPrint((" hIS %x\n", hIS)); + hIS &= (1 << Channel); + if(!hIS) { + return 0; + } + base = (ULONG)&deviceExtension->BaseIoAHCI_0 + offs; + IS.Reg = AtapiReadPort4(chan, base + IDX_AHCI_P_IS); + CI = AtapiReadPort4(chan, base + IDX_AHCI_P_CI); + SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus); + SError.Reg = AtapiReadPort4(chan, IDX_SATA_SError); + + /* clear interrupt(s) */ + AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_IS, hIS); + AtapiWritePort4(chan, base + IDX_AHCI_P_IS, IS.Reg); + AtapiWritePort4(chan, IDX_SATA_SError, SError.Reg); + + KdPrint((" AHCI: status=%08x sstatus=%08x error=%08x CI=%08x\n", + IS.Reg, SStatus.Reg, SError.Reg, CI)); + + /* do we have cold connect surprise */ + if(IS.CPDS) { + } + + /* check for and handle connect events */ + if(IS.PCS) { + UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH); + } + if(IS.PRCS) { + UniataSataEvent(HwDeviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH); + } + if(CI & (1 << tag)) { + return 1; + } + KdPrint((" AHCI: unexpected\n")); + return 2; + +} // end UniataAhciStatus() + +ULONG +UniataAhciSetupFIS( + IN PHW_DEVICE_EXTENSION deviceExtension, + IN ULONG DeviceNumber, + IN ULONG lChannel, + OUT PUCHAR fis, + IN UCHAR command, + IN ULONGLONG lba, + IN USHORT count, + IN USHORT feature, + IN ULONG flags + ) +{ + ULONG ldev = lChannel*2 + DeviceNumber; + ULONG i; + PUCHAR plba; + + KdPrint2((PRINT_PREFIX " AHCI setup FIS\n" )); + i = 0; + plba = (PUCHAR)&lba; + + /* translate command into 48bit version */ + if ((lba >= ATA_MAX_LBA28 || count > 256) && + deviceExtension->lun[ldev].IdentifyData.FeaturesSupport.Address48) { + if(AtaCommandFlags[command] & ATA_CMD_FLAG_48supp) { + command = AtaCommands48[command]; + } else { + KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n")); + return 0; + } + } + + fis[i++] = 0x27; /* host to device */ + fis[i++] = 0x80; /* command FIS (note PM goes here) */ + fis[i++] = command; + fis[i++] = (UCHAR)feature; + + fis[i++] = plba[0]; + fis[i++] = plba[1]; + fis[i++] = plba[2]; + fis[i] = IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1); + if ((lba >= ATA_MAX_LBA28 || count > 256) && + deviceExtension->lun[ldev].IdentifyData.FeaturesSupport.Address48) { + i++; + } else { + fis[i++] |= (plba[3] >> 24) & 0x0f; + } + + fis[i++] = plba[3]; + fis[i++] = plba[4]; + fis[i++] = plba[5]; + fis[i++] = (UCHAR)(feature>>8) & 0xff; + + fis[i++] = (UCHAR)count & 0xff; + fis[i++] = (UCHAR)(count>>8) & 0xff; + fis[i++] = 0x00; + fis[i++] = IDE_DC_A_4BIT; + + fis[i++] = 0x00; + fis[i++] = 0x00; + fis[i++] = 0x00; + fis[i++] = 0x00; + return i; +} // end UniataAhciSetupFIS() + diff --git a/reactos/drivers/storage/ide/uniata/id_sata.h b/reactos/drivers/storage/ide/uniata/id_sata.h index ef6bc21a773..1571e8b54a2 100644 --- a/reactos/drivers/storage/ide/uniata/id_sata.h +++ b/reactos/drivers/storage/ide/uniata/id_sata.h @@ -33,4 +33,33 @@ UniataSataEvent( IN ULONG Action ); +#define UniataIsSATARangeAvailable(deviceExtension, lChannel) \ + ((deviceExtension->BaseIoAddressSATA_0.Addr || \ + deviceExtension->BaseIoAHCI_0.Addr) && \ + (deviceExtension->chan[lChannel].RegTranslation[IDX_SATA_SStatus].Addr)) + +BOOLEAN +UniataAhciInit( + IN PVOID HwDeviceExtension + ); + +UCHAR +UniataAhciStatus( + IN PVOID HwDeviceExtension, + IN ULONG lChannel + ); + +ULONG +UniataAhciSetupFIS( + IN PHW_DEVICE_EXTENSION deviceExtension, + IN ULONG DeviceNumber, + IN ULONG lChannel, + OUT PUCHAR fis, + IN UCHAR command, + IN ULONGLONG lba, + IN USHORT count, + IN USHORT feature, + IN ULONG flags + ); + #endif //__UNIATA_SATA__H__ diff --git a/reactos/drivers/storage/ide/uniata/idedma.rc b/reactos/drivers/storage/ide/uniata/idedma.rc index 3f580f41fed..d64ec14ba9c 100644 --- a/reactos/drivers/storage/ide/uniata/idedma.rc +++ b/reactos/drivers/storage/ide/uniata/idedma.rc @@ -1,6 +1,6 @@ #include "uniata_ver.h" -#define VERSION 0,38,2,0 +#define VERSION 0,39,6,0 #define VERSION_STR "0." UNIATA_VER_STR #define REACTOS_FILETYPE VFT_DRV diff --git a/reactos/drivers/storage/ide/uniata/ntddk_ex.h b/reactos/drivers/storage/ide/uniata/ntddk_ex.h index 40f1bfe2da2..0939fca2886 100644 --- a/reactos/drivers/storage/ide/uniata/ntddk_ex.h +++ b/reactos/drivers/storage/ide/uniata/ntddk_ex.h @@ -1,16 +1,20 @@ #ifndef __NTDDK_EX__H__ #define __NTDDK_EX__H__ +#ifndef __REACTOS__ #undef ASSERT #define ASSERT +#else +#undef ASSERT +#define ASSERT //(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); } +#endif //__REACTOS__ -typedef enum _SYSTEM_INFORMATION_CLASS -{ +typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, SystemPerformanceInformation, SystemTimeOfDayInformation, - SystemPathInformation, /// Obsolete: Use KUSER_SHARED_DATA + SystemPathInformation, SystemProcessInformation, SystemCallCountInformation, SystemDeviceInformation, @@ -36,9 +40,15 @@ typedef enum _SYSTEM_INFORMATION_CLASS SystemUnloadGdiDriverInformation, SystemTimeAdjustmentInformation, SystemSummaryMemoryInformation, +#ifndef __REACTOS__ + SystemNextEventIdInformation, + SystemEventIdsInformation, + SystemCrashDumpInformation, +#else SystemMirrorMemoryInformation, SystemPerformanceTraceInformation, SystemObsolete0, +#endif SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, @@ -48,10 +58,17 @@ typedef enum _SYSTEM_INFORMATION_CLASS SystemPrioritySeperation, SystemPlugPlayBusInformation, SystemDockInformation, +#ifdef __REACTOS__ SystemPowerInformationNative, +#elif defined IRP_MN_START_DEVICE + SystemPowerInformationInfo, +#else + SystemPowerInformation, +#endif SystemProcessorSpeedInformation, SystemCurrentTimeZoneInformation, SystemLookasideInformation, +#ifdef __REACTOS__ SystemTimeSlipNotification, SystemSessionCreate, SystemSessionDetach, @@ -105,8 +122,10 @@ typedef enum _SYSTEM_INFORMATION_CLASS SystemPrefetchPathInformation, SystemVerifierFaultsInformation, MaxSystemInfoClass, +#endif //__REACTOS__ } SYSTEM_INFORMATION_CLASS; + NTSYSAPI NTSTATUS NTAPI @@ -161,7 +180,9 @@ typedef struct _SYSTEM_MODULE_INFORMATION } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; typedef unsigned short WORD; -//typedef unsigned int BOOL; +#ifndef __REACTOS__ +typedef unsigned int BOOL; +#endif //__REACTOS__ typedef unsigned long DWORD; typedef unsigned char BYTE; diff --git a/reactos/drivers/storage/ide/uniata/srb.h b/reactos/drivers/storage/ide/uniata/srb.h index 3bf8579c989..5847ed175ad 100644 --- a/reactos/drivers/storage/ide/uniata/srb.h +++ b/reactos/drivers/storage/ide/uniata/srb.h @@ -423,39 +423,39 @@ typedef struct _SCSI_WMI_REQUEST_BLOCK { // typedef -BOOLEAN DDKAPI -(*PHW_INITIALIZE) ( +BOOLEAN +(DDKAPI *PHW_INITIALIZE) ( IN PVOID DeviceExtension ); typedef -BOOLEAN DDKAPI -(*PHW_STARTIO) ( +BOOLEAN +(DDKAPI *PHW_STARTIO) ( IN PVOID DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb ); typedef -BOOLEAN DDKAPI -(*PHW_INTERRUPT) ( +BOOLEAN +(DDKAPI *PHW_INTERRUPT) ( IN PVOID DeviceExtension ); typedef -VOID DDKAPI -(*PHW_TIMER) ( +VOID +(DDKAPI *PHW_TIMER) ( IN PVOID DeviceExtension ); typedef -VOID DDKAPI -(*PHW_DMA_STARTED) ( +VOID +(DDKAPI *PHW_DMA_STARTED) ( IN PVOID DeviceExtension ); typedef -ULONG DDKAPI -(*PHW_FIND_ADAPTER) ( +ULONG +(DDKAPI *PHW_FIND_ADAPTER) ( IN PVOID DeviceExtension, IN PVOID HwContext, IN PVOID BusInformation, @@ -465,23 +465,23 @@ ULONG DDKAPI ); typedef -BOOLEAN DDKAPI -(*PHW_RESET_BUS) ( +BOOLEAN +(DDKAPI *PHW_RESET_BUS) ( IN PVOID DeviceExtension, IN ULONG PathId ); typedef -BOOLEAN DDKAPI -(*PHW_ADAPTER_STATE) ( +BOOLEAN +(DDKAPI *PHW_ADAPTER_STATE) ( IN PVOID DeviceExtension, IN PVOID Context, IN BOOLEAN SaveState ); typedef -SCSI_ADAPTER_CONTROL_STATUS DDKAPI -(*PHW_ADAPTER_CONTROL) ( +SCSI_ADAPTER_CONTROL_STATUS +(DDKAPI *PHW_ADAPTER_CONTROL) ( IN PVOID DeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters diff --git a/reactos/drivers/storage/ide/uniata/stdafx.h b/reactos/drivers/storage/ide/uniata/stdafx.h index 6c2f834c0c1..1953fd728e9 100644 --- a/reactos/drivers/storage/ide/uniata/stdafx.h +++ b/reactos/drivers/storage/ide/uniata/stdafx.h @@ -19,7 +19,17 @@ extern "C" { #include "id_queue.h" +#ifdef ExAllocatePool +#undef ExAllocatePool +#endif + +#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) +#define TAG_UNIATA TAG('a', 't', 'a', 'U') + +#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,TAG_UNIATA) + #endif //UNIATA_CORE #include "badblock.h" + diff --git a/reactos/drivers/storage/ide/uniata/uata_ctl.h b/reactos/drivers/storage/ide/uniata/uata_ctl.h index 1845b4c59b4..b199d2b8e51 100644 --- a/reactos/drivers/storage/ide/uniata/uata_ctl.h +++ b/reactos/drivers/storage/ide/uniata/uata_ctl.h @@ -50,6 +50,7 @@ extern "C" { #define MAX_QUEUE_STAT 8 +#define UNIATA_COMM_PORT_VENDOR_STR "UNIATA " "Management Port " UNIATA_VER_STR #ifndef UNIATA_CORE @@ -65,6 +66,11 @@ extern "C" { typedef struct _ADDREMOVEDEV { ULONG WaitForPhysicalLink; // us + ULONG Flags; + +#define UNIATA_REMOVE_FLAGS_HIDE 0x01 +#define UNIATA_ADD_FLAGS_UNHIDE 0x01 + } ADDREMOVEDEV, *PADDREMOVEDEV; typedef struct _SETTRANSFERMODE { @@ -127,11 +133,49 @@ typedef struct _ADAPTERINFO { ULONG NumberChannels; BOOLEAN ChanInfoValid; + CHAR Reserved[3]; + + ULONG AdapterInterfaceType; CHANINFO Chan[AHCI_MAX_PORT]; } ADAPTERINFO, *PADAPTERINFO; +#ifdef USER_MODE + +typedef enum _INTERFACE_TYPE { + InterfaceTypeUndefined = -1, + Internal, + Isa, + Eisa, + MicroChannel, + TurboChannel, + PCIBus, + VMEBus, + NuBus, + PCMCIABus, + CBus, + MPIBus, + MPSABus, + ProcessorInternal, + InternalPowerBus, + PNPISABus, + MaximumInterfaceType +} INTERFACE_TYPE, *PINTERFACE_TYPE; + +typedef struct _PCI_SLOT_NUMBER { + union { + struct { + ULONG DeviceNumber:5; + ULONG FunctionNumber:3; + ULONG Reserved:24; + } bits; + ULONG AsULONG; + } u; +} PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER; + +#endif + #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. @@ -179,22 +223,28 @@ typedef struct _IDEREGS_EX { #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 +#define UNIATA_SPTI_EX_USE_DMA 0x20 // Force DMA transfer mode 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 + UCHAR bReserved2; // 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 RegSz:3; // 0=1, 1=2, 2=4, 3=1+1 (for lba48) 4=2+2 (for lba48) UCHAR InOut:1; // 0=in, 1=out - UCHAR Reserved:5; + UCHAR Reserved:4; UCHAR Reserved1; - ULONG Data; + union { + ULONG Data; + ULONG d32; + USHORT d16[2]; + USHORT d8[2]; + }; } UNIATA_REG_IO, *PUNIATA_REG_IO; typedef struct _UNIATA_REG_IO_HDR { diff --git a/reactos/drivers/storage/ide/uniata/uniata.rbuild b/reactos/drivers/storage/ide/uniata/uniata.rbuild index 47804d37670..85b58c5293e 100644 --- a/reactos/drivers/storage/ide/uniata/uniata.rbuild +++ b/reactos/drivers/storage/ide/uniata/uniata.rbuild @@ -2,7 +2,6 @@ - . inc ntoskrnl diff --git a/reactos/drivers/storage/ide/uniata/uniata_ver.h b/reactos/drivers/storage/ide/uniata/uniata_ver.h index d5a3377000e..849442532d2 100644 --- a/reactos/drivers/storage/ide/uniata/uniata_ver.h +++ b/reactos/drivers/storage/ide/uniata/uniata_ver.h @@ -1,2 +1,6 @@ - -#define UNIATA_VER_STR "38c2" +#define UNIATA_VER_STR "39f" +#define UNIATA_VER_DOT 0.39.6.0 +#define UNIATA_VER_DOT_COMMA 0,39,6,0 +#define UNIATA_VER_DOT_STR "0.39.6.0" +#define UNIATA_VER_YEAR 2007 +#define UNIATA_VER_YEAR_STR "2007"