From 9f4cee2ca1cfb86a4a89e3171e9271fd3c41ecc6 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 13 Aug 2012 16:25:08 +0000 Subject: [PATCH] [UNIATA] [ATACTL] * Sync to 0.43a1. See issue #7237 for more details. svn path=/trunk/; revision=57072 --- reactos/base/applications/atactl/atactl.cpp | 222 +++++++++--------- reactos/drivers/storage/ide/uniata/atapi.h | 117 +++++++++ reactos/drivers/storage/ide/uniata/bm_devs.h | 38 --- reactos/drivers/storage/ide/uniata/bsmaster.h | 5 +- reactos/drivers/storage/ide/uniata/id_ata.cpp | 161 +++++++++++-- reactos/drivers/storage/ide/uniata/id_dma.cpp | 30 ++- .../drivers/storage/ide/uniata/id_init.cpp | 18 +- .../drivers/storage/ide/uniata/id_sata.cpp | 7 + reactos/drivers/storage/ide/uniata/uata_ctl.h | 23 +- 9 files changed, 423 insertions(+), 198 deletions(-) diff --git a/reactos/base/applications/atactl/atactl.cpp b/reactos/base/applications/atactl/atactl.cpp index 113945e07b2..69ea2f99224 100644 --- a/reactos/base/applications/atactl/atactl.cpp +++ b/reactos/base/applications/atactl/atactl.cpp @@ -37,6 +37,7 @@ int g_extended = 0; int g_adapter_info = 0; char* g_bb_list = NULL; int gRadix = 16; +PADAPTERINFO g_AdapterInfo = NULL; void print_help() { printf("Usage:\n" @@ -262,6 +263,14 @@ ata_send_ioctl( AtaCtl->addr.Length = sizeof(AtaCtl->addr); } + if(outBufferLength) { + if(addr) { + memset(&AtaCtl->RawData, 0, outBufferLength); + } else { + memset(&AtaCtl->addr, 0, outBufferLength); + } + } + if(inBuffer && inBufferLength) { if(addr) { memcpy(&AtaCtl->RawData, inBuffer, inBufferLength); @@ -298,80 +307,17 @@ ata_send_ioctl( IO_SCSI_CAPABILITIES g_capabilities; UCHAR g_inquiry_buffer[2048]; -int -ata_is_sata( - PIDENTIFY_DATA ident - ) -{ - return (ident->SataEnable && ident->SataEnable != 0xffff); -} - -int -ata_cur_mode_from_ident( - PIDENTIFY_DATA ident - ) -{ - if(ata_is_sata(ident)) { - return ATA_SA150-1; - } - - if (ident->UdmaModesValid) { - if (ident->UltraDMAActive & 0x40) - return ATA_UDMA0+6; - if (ident->UltraDMAActive & 0x20) - return ATA_UDMA0+5; - if (ident->UltraDMAActive & 0x10) - return ATA_UDMA0+4; - if (ident->UltraDMAActive & 0x08) - return ATA_UDMA0+3; - if (ident->UltraDMAActive & 0x04) - return ATA_UDMA0+2; - if (ident->UltraDMAActive & 0x02) - return ATA_UDMA0+1; - if (ident->UltraDMAActive & 0x01) - return ATA_UDMA0+0; - } - - if (ident->MultiWordDMAActive & 0x04) - return ATA_WDMA0+2; - if (ident->MultiWordDMAActive & 0x02) - return ATA_WDMA0+1; - if (ident->MultiWordDMAActive & 0x01) - return ATA_WDMA0+0; - - if (ident->SingleWordDMAActive & 0x04) - return ATA_SDMA0+2; - if (ident->SingleWordDMAActive & 0x02) - return ATA_SDMA0+1; - if (ident->SingleWordDMAActive & 0x01) - return ATA_SDMA0+0; - - if (ident->PioTimingsValid) { - if (ident->AdvancedPIOModes & AdvancedPIOModes_5) - return ATA_PIO0+5; - if (ident->AdvancedPIOModes & AdvancedPIOModes_4) - return ATA_PIO0+4; - if (ident->AdvancedPIOModes & AdvancedPIOModes_3) - return ATA_PIO0+3; - } - if (ident->PioCycleTimingMode == 2) - return ATA_PIO0+2; - if (ident->PioCycleTimingMode == 1) - return ATA_PIO0+1; - if (ident->PioCycleTimingMode == 0) - return ATA_PIO0+0; - - return ATA_PIO; -} // end ata_cur_mode_from_ident() - void ata_mode_to_str( char* str, int mode ) { - if(mode == ATA_SA150-1) { - sprintf(str, "SATA"); + if(mode > ATA_SA600) { + sprintf(str, "SATA-600+"); + } else + if(mode >= ATA_SA600) { + sprintf(str, "SATA-600"); } else if(mode >= ATA_SA300) { sprintf(str, "SATA-300"); @@ -413,6 +359,12 @@ ata_str_to_mode( int mode; int len; + if(!_stricmp(str, "SATA600")) + return ATA_SA600; + if(!_stricmp(str, "SATA300")) + return ATA_SA300; + if(!_stricmp(str, "SATA150")) + return ATA_SA150; if(!_stricmp(str, "SATA")) return ATA_SA150; @@ -620,10 +572,34 @@ ata_check_unit( return FALSE; } + // Note: adapterInfo->NumberOfBuses is 1 greater than g_AdapterInfo->NumberChannels + // because of virtual communication port adapterInfo = (PSCSI_ADAPTER_BUS_INFO)g_inquiry_buffer; - for (i = 0; i < adapterInfo->NumberOfBuses; i++) { + for (i = 0; i+1 < adapterInfo->NumberOfBuses; i++) { inquiryData = (PSCSI_INQUIRY_DATA) (g_inquiry_buffer + adapterInfo->BusData[i].InquiryDataOffset); + + if(g_extended && g_AdapterInfo && g_AdapterInfo->ChanHeaderLengthValid && + g_AdapterInfo->NumberChannels < i) { + PCHANINFO ChanInfo; + + ChanInfo = (PCHANINFO) + (((PCHAR)g_AdapterInfo)+ + sizeof(ADAPTERINFO)+ + g_AdapterInfo->ChanHeaderLength*i); + + io_mode = ChanInfo->MaxTransferMode; + if(io_mode != -1) { + ata_mode_to_str(mode_str, io_mode); + } else { + mode_str[0] = 0; + } + printf(" b%u [%s]\n", + i, + mode_str + ); + } + while (adapterInfo->BusData[i].InquiryDataOffset) { /* if(dev_id/adapterInfo->BusData[i].NumberOfLogicalUnits == @@ -641,7 +617,7 @@ ata_check_unit( if(l_dev_id == dev_id || dev_id == -1) { - if(!memcmp(&inquiryData->InquiryData[8], UNIATA_COMM_PORT_VENDOR_STR, 24)) { + if(!memcmp(&(inquiryData->InquiryData[8]), UNIATA_COMM_PORT_VENDOR_STR, 24)) { // skip communication port goto next_dev; } @@ -651,7 +627,7 @@ ata_check_unit( if(inquiryData->Lun) { sprintf(lun_str, ":l%d", inquiryData->Lun); } else { - sprintf(lun_str, " ", inquiryData->Lun); + sprintf(lun_str, " "); } @@ -665,14 +641,17 @@ ata_check_unit( addr.PathId = inquiryData->PathId; addr.TargetId = inquiryData->TargetId; addr.Lun = inquiryData->Lun; - status = ata_send_ioctl(h, &addr, "-UNIATA-", + status = ata_send_ioctl(h, &addr, (PCHAR)"-UNIATA-", IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE, NULL, 0, &IoMode, sizeof(IoMode), &returned); if(status) { //io_mode = min(IoMode.CurrentMode, IoMode.MaxMode); - io_mode = min(max(IoMode.CurrentMode,IoMode.OrigMode),IoMode.MaxMode); + io_mode = IoMode.PhyMode; + if(!io_mode) { + io_mode = min(max(IoMode.CurrentMode,IoMode.OrigMode),IoMode.MaxMode); + } } else { io_mode = -1; } @@ -684,7 +663,7 @@ ata_check_unit( // probably, we shall change this in future to support SATA splitters pin.bDriveNumber = inquiryData->PathId*2+inquiryData->TargetId; - status = ata_send_ioctl(h, NULL, "SCSIDISK", + status = ata_send_ioctl(h, NULL, (PCHAR)"SCSIDISK", IOCTL_SCSI_MINIPORT_IDENTIFY, &pin, sizeof(pin), buff, sizeof(buff), @@ -698,7 +677,7 @@ ata_check_unit( // probably, we shall change this in future to support SATA splitters pin.bDriveNumber = inquiryData->PathId*2+inquiryData->TargetId; - status = ata_send_ioctl(h, NULL, "SCSIDISK", + status = ata_send_ioctl(h, NULL, (PCHAR)"SCSIDISK", IOCTL_SCSI_MINIPORT_IDENTIFY, &pin, sizeof(pin), buff, sizeof(buff), @@ -708,7 +687,7 @@ ata_check_unit( if(status) { if(!g_extended) { - printf(" b%d:d%d%s %24.24s %4.4s ", + printf(" b%u:d%d%s %24.24s %4.4s ", i, inquiryData->TargetId, lun_str, @@ -717,7 +696,7 @@ ata_check_unit( (g_extended ? (PUCHAR)"" : &inquiryData->InquiryData[8+24]) ); } else { - printf(" b%d:d%d%s ", + printf(" b%u:d%d%s ", i, inquiryData->TargetId, lun_str @@ -806,27 +785,27 @@ ata_check_unit( if(BlockMode_valid) { if(ident->MaximumBlockTransfer) { - printf(" Multi-block mode: %d block%s\n", ident->MaximumBlockTransfer, ident->MaximumBlockTransfer == 1 ? "" : "s"); + printf(" Multi-block mode: %u block%s\n", ident->MaximumBlockTransfer, ident->MaximumBlockTransfer == 1 ? "" : "s"); } else { printf(" Multi-block mode: N/A\n"); } } if(print_geom) { - printf(" C/H/S: %d/%d/%d \n", chs[0], chs[1], chs[2]); - printf(" LBA: %d \n", max_lba); + printf(" C/H/S: %u/%u/%u \n", chs[0], chs[1], chs[2]); + printf(" LBA: %I64u \n", max_lba); if(max_lba < 2) { - printf(" Size: %d kb\n", max_lba/2); + printf(" Size: %u kb\n", max_lba/2); } else if(max_lba < 2*1024*1024) { - printf(" Size: %d Mb\n", max_lba/2048); + printf(" Size: %u Mb\n", max_lba/2048); } else if(max_lba < (ULONG)2*1024*1024*1024) { - printf(" Size: %d.%d (%d) Gb\n", (ULONG)(max_lba/2048/1024), + printf(" Size: %u.%u (%u) Gb\n", (ULONG)(max_lba/2048/1024), (ULONG)(((max_lba/2048)%1024)/10), (ULONG)(max_lba*512/1000/1000/1000) ); } else { - printf(" Size: %d.%d (%d) Tb\n", (ULONG)(max_lba/2048/1024/1024), + printf(" Size: %u.%u (%u) Tb\n", (ULONG)(max_lba/2048/1024/1024), (ULONG)((max_lba/2048/1024)%1024)/10, (ULONG)(max_lba*512/1000/1000/1000) ); @@ -868,11 +847,13 @@ ata_adapter_info( { char dev_name[64]; HANDLE h; - ADAPTERINFO AdapterInfo; + PADAPTERINFO AdapterInfo; ULONG status; ULONG returned; SCSI_ADDRESS addr; PCI_SLOT_NUMBER slotData; + char mode_str[12]; + ULONG len; sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id); h = ata_open_dev(dev_name); @@ -880,35 +861,52 @@ ata_adapter_info( return FALSE; addr.PortNumber = bus_id; - memset(&AdapterInfo, 0, sizeof(AdapterInfo)); + len = sizeof(ADAPTERINFO)+sizeof(CHANINFO)*AHCI_MAX_PORT; + if(!g_AdapterInfo) { + AdapterInfo = (PADAPTERINFO)GlobalAlloc(GMEM_FIXED, len); + if(!AdapterInfo) { + return FALSE; + } + } else { + AdapterInfo = g_AdapterInfo; + } + memset(AdapterInfo, 0, len); - status = ata_send_ioctl(h, &addr, "-UNIATA-", + status = ata_send_ioctl(h, &addr, (PCHAR)"-UNIATA-", IOCTL_SCSI_MINIPORT_UNIATA_ADAPTER_INFO, - &AdapterInfo, sizeof(AdapterInfo), - &AdapterInfo, sizeof(AdapterInfo), + AdapterInfo, len, + AdapterInfo, len, &returned); - printf("Scsi%d: %s\n", bus_id, status ? "[UniATA]" : ""); + if(status) { + ata_mode_to_str(mode_str, AdapterInfo->MaxTransferMode); + } + printf("Scsi%d: %s %s\n", bus_id, status ? "[UniATA]" : "", status ? mode_str : ""); if(print_info) { if(!status) { printf("Can't get adapter info\n"); } else { - if(AdapterInfo.AdapterInterfaceType == PCIBus) { - slotData.u.AsULONG = AdapterInfo.slotNumber; - printf(" PCI Bus/Dev/Func: %d/%d/%d%s\n", - AdapterInfo.SystemIoBusNumber, slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber, - AdapterInfo.AdapterInterfaceType == AdapterInfo.OrigAdapterInterfaceType ? "" : " (ISA-Bridged)"); - printf(" VendorId/DevId/Rev: %#04x/%#04x/%#02x\n", AdapterInfo.DevID >> 16, AdapterInfo.DevID & 0xffff, AdapterInfo.RevID); - if(AdapterInfo.DeviceName[0]) { - printf(" Name: %s\n", AdapterInfo.DeviceName); + if(AdapterInfo->AdapterInterfaceType == PCIBus) { + slotData.u.AsULONG = AdapterInfo->slotNumber; + printf(" PCI Bus/Dev/Func: %u/%u/%u%s\n", + AdapterInfo->SystemIoBusNumber, slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber, + AdapterInfo->AdapterInterfaceType == AdapterInfo->OrigAdapterInterfaceType ? "" : " (ISA-Bridged)"); + printf(" VendorId/DevId/Rev: %#04x/%#04x/%#02x\n", + (USHORT)(AdapterInfo->DevID >> 16), + (USHORT)(AdapterInfo->DevID & 0xffff), + (UCHAR)(AdapterInfo->RevID)); + if(AdapterInfo->DeviceName[0]) { + printf(" Name: %s\n", AdapterInfo->DeviceName); } } else - if(AdapterInfo.AdapterInterfaceType == Isa) { + if(AdapterInfo->AdapterInterfaceType == Isa) { printf(" ISA Bus\n"); } - printf(" IRQ: %d\n", AdapterInfo.BusInterruptLevel); + printf(" IRQ: %d\n", AdapterInfo->BusInterruptLevel); } } ata_close_dev(h); + //GlobalFree(AdapterInfo); + g_AdapterInfo = AdapterInfo; return status ? TRUE : FALSE; } // end ata_adapter_info() @@ -996,7 +994,7 @@ ata_mode( // IoMode.ApplyImmediately = TRUE; IoMode.OrigMode = mode; - status = ata_send_ioctl(h, &addr, "-UNIATA-", + status = ata_send_ioctl(h, &addr, (PCHAR)"-UNIATA-", IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE, &IoMode, sizeof(IoMode), NULL, 0, @@ -1094,7 +1092,7 @@ ata_hide( if(lock) { printf("ATTENTION: you have %d seconds to disconnect cable\n", lock); } - status = ata_send_ioctl(h, &addr, "-UNIATA-", + status = ata_send_ioctl(h, &addr, (PCHAR)"-UNIATA-", IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE, &to, sizeof(to), NULL, 0, @@ -1144,7 +1142,7 @@ ata_scan( if(lock) { printf("You have %d seconds to connect device.\n", lock); } - status = ata_send_ioctl(h, &addr, "-UNIATA-", + status = ata_send_ioctl(h, &addr, (PCHAR)"-UNIATA-", IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES, &to, sizeof(to), NULL, 0, @@ -1233,12 +1231,12 @@ ata_bblk( print_help(); return FALSE; } - if((dev_id >> 16) & 0xff == 0xff) { + if(((dev_id >> 16) & 0xff) == 0xff) { printf("\nERROR: Target device bus number (channel) must be specified with b:\n\n"); print_help(); return FALSE; } - if((dev_id >> 8) & 0xff == 0xff) { + if(((dev_id >> 8) & 0xff) == 0xff) { printf("\nERROR: Target device ID must be specified with d:\n\n"); print_help(); return FALSE; @@ -1289,7 +1287,7 @@ ata_bblk( addr.TargetId = (UCHAR)(dev_id >> 8); addr.Lun = (UCHAR)(dev_id); - status = ata_send_ioctl(h, &addr, "-UNIATA-", + status = ata_send_ioctl(h, &addr, (PCHAR)"-UNIATA-", IOCTL_SCSI_MINIPORT_UNIATA_RESETBB, NULL, 0, NULL, 0, @@ -1355,7 +1353,7 @@ ata_bblk( } k = k0; if(radix == 10) { - b = sscanf(BB_Msg+k, "%I64d\t%I64d", &tmp_bb_lba, &tmp_bb_len); + b = sscanf(BB_Msg+k, "%I64u\t%I64u", &tmp_bb_lba, &tmp_bb_len); } else { b = sscanf(BB_Msg+k, "%I64x\t%I64x", &tmp_bb_lba, &tmp_bb_len); } @@ -1464,7 +1462,7 @@ ata_bblk( while(len >= sizeof(LONGLONG)*2) { tmp_bb_lba = ((LONGLONG*)bblist)[i*2+0]; tmp_bb_len = ((LONGLONG*)bblist)[i*2+1] - tmp_bb_lba; - b = sprintf(BB_Msg, "%I64x\t%I64x\n", tmp_bb_lba, tmp_bb_len); + b = sprintf(BB_Msg, "%I64u\t%I64u\n", tmp_bb_lba, tmp_bb_len); WriteFile(hf, BB_Msg, b, &returned, NULL); i++; len -= sizeof(LONGLONG)*2; @@ -1511,7 +1509,7 @@ main ( int persistent_hide=0; printf("Console ATA control utility for Windows NT3.51/NT4/2000/XP/2003\n" - "Version 0." UNIATA_VER_STR ", Copyright (c) Alexander A. Telyatnikov, 2003-2008\n" + "Version 0." UNIATA_VER_STR ", Copyright (c) Alexander A. Telyatnikov, 2003-2012\n" "Home site: http://alter.org.ua\n"); for(i=1; iSataCapabilities && ident->SataCapabilities != 0xffff); +} // end ata_is_sata() + +__inline +LONG +ata_cur_mode_from_ident( + PIDENTIFY_DATA ident + ) +{ + if(ata_is_sata(ident)) { + if(ident->SataCapabilities & ATA_SATA_GEN3) { + return ATA_SA600; + } else + if(ident->SataCapabilities & ATA_SATA_GEN2) { + return ATA_SA300; + } else + if(ident->SataCapabilities & ATA_SATA_GEN1) { + return ATA_SA150; + } + return ATA_SA150; + } + + if (ident->UdmaModesValid) { + if (ident->UltraDMAActive & 0x40) + return ATA_UDMA0+6; + if (ident->UltraDMAActive & 0x20) + return ATA_UDMA0+5; + if (ident->UltraDMAActive & 0x10) + return ATA_UDMA0+4; + if (ident->UltraDMAActive & 0x08) + return ATA_UDMA0+3; + if (ident->UltraDMAActive & 0x04) + return ATA_UDMA0+2; + if (ident->UltraDMAActive & 0x02) + return ATA_UDMA0+1; + if (ident->UltraDMAActive & 0x01) + return ATA_UDMA0+0; + } + + if (ident->MultiWordDMAActive & 0x04) + return ATA_WDMA0+2; + if (ident->MultiWordDMAActive & 0x02) + return ATA_WDMA0+1; + if (ident->MultiWordDMAActive & 0x01) + return ATA_WDMA0+0; + + if (ident->SingleWordDMAActive & 0x04) + return ATA_SDMA0+2; + if (ident->SingleWordDMAActive & 0x02) + return ATA_SDMA0+1; + if (ident->SingleWordDMAActive & 0x01) + return ATA_SDMA0+0; + + if (ident->PioTimingsValid) { + if (ident->AdvancedPIOModes & AdvancedPIOModes_5) + return ATA_PIO0+5; + if (ident->AdvancedPIOModes & AdvancedPIOModes_4) + return ATA_PIO0+4; + if (ident->AdvancedPIOModes & AdvancedPIOModes_3) + return ATA_PIO0+3; + } + if (ident->PioCycleTimingMode == 2) + return ATA_PIO0+2; + if (ident->PioCycleTimingMode == 1) + return ATA_PIO0+1; + if (ident->PioCycleTimingMode == 0) + return ATA_PIO0+0; + + return ATA_PIO; +} // end ata_cur_mode_from_ident() + #pragma pack(pop) #endif // __GLOBAL_H__ diff --git a/reactos/drivers/storage/ide/uniata/bm_devs.h b/reactos/drivers/storage/ide/uniata/bm_devs.h index f14cca9becf..039f111a4ee 100644 --- a/reactos/drivers/storage/ide/uniata/bm_devs.h +++ b/reactos/drivers/storage/ide/uniata/bm_devs.h @@ -41,44 +41,6 @@ Revision History: #define MAX_QUEUE_STAT 8 -// -// values for TransferMode -// -#define ATA_PIO 0x00 -#define ATA_PIO_NRDY 0x01 - -#define ATA_PIO0 0x08 -#define ATA_PIO1 0x09 -#define ATA_PIO2 0x0a -#define ATA_PIO3 0x0b -#define ATA_PIO4 0x0c -#define ATA_PIO5 0x0d - -#define ATA_DMA 0x10 -#define ATA_SDMA 0x10 -#define ATA_SDMA0 0x10 -#define ATA_SDMA1 0x11 -#define ATA_SDMA2 0x12 - -#define ATA_WDMA 0x20 -#define ATA_WDMA0 0x20 -#define ATA_WDMA1 0x21 -#define ATA_WDMA2 0x22 - -#define ATA_UDMA 0x40 -#define ATA_UDMA0 0x40 // ATA-16 -#define ATA_UDMA1 0x41 // ATA-25 -#define ATA_UDMA2 0x42 // ATA-33 -#define ATA_UDMA3 0x43 // ATA-44 -#define ATA_UDMA4 0x44 // ATA-66 -#define ATA_UDMA5 0x45 // ATA-100 -#define ATA_UDMA6 0x46 // ATA-133 -//#define ATA_UDMA7 0x47 // ATA-166 - -#define ATA_SA150 0x47 /*0x80*/ -#define ATA_SA300 0x48 /*0x81*/ -#define ATA_SA600 0x49 /*0x82*/ - // define PIO timings in nanoseconds #define PIO0_TIMING 600 diff --git a/reactos/drivers/storage/ide/uniata/bsmaster.h b/reactos/drivers/storage/ide/uniata/bsmaster.h index ba017b16af3..864f7eab5db 100644 --- a/reactos/drivers/storage/ide/uniata/bsmaster.h +++ b/reactos/drivers/storage/ide/uniata/bsmaster.h @@ -1085,13 +1085,14 @@ typedef struct _HW_LU_EXTENSION { ULONG DiscsPresent; // Indicates number of platters on changer-ish devices. BOOLEAN DWordIO; // Indicates use of 32-bit PIO UCHAR ReturningMediaStatus; + UCHAR MaximumBlockXfer; + UCHAR Padding0[1]; // padding UCHAR TransferMode; // current transfer mode UCHAR LimitedTransferMode; // user-defined or IDE cable limitation UCHAR OrigTransferMode; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL) + UCHAR PhyTransferMode; // phy transfer mode (actual bus transfer mode for PATA DMA and SATA) - UCHAR MaximumBlockXfer; - UCHAR Padding0[2]; // padding ULONG ErrorCount; // Count of errors. Used to turn off features. // ATA_QUEUE cmd_queue; LONGLONG ReadCmdCost; diff --git a/reactos/drivers/storage/ide/uniata/id_ata.cpp b/reactos/drivers/storage/ide/uniata/id_ata.cpp index d362a766e87..08933792018 100644 --- a/reactos/drivers/storage/ide/uniata/id_ata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_ata.cpp @@ -717,6 +717,14 @@ AtapiSoftReset( } else { AtapiStallExecution(500); AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET); + AtapiStallExecution(30); + + // Wait for BUSY assertion, in some cases delay may occure + while (!(AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) && + i--) + { + AtapiStallExecution(30); + } // ReactOS modification: Already stop looping when we know that the drive has finished resetting. // Not all controllers clear the IDE_STATUS_BUSY flag (e.g. not the VMware one), so ensure that @@ -1066,6 +1074,24 @@ AtaUmode(PIDENTIFY_DATA2 ident) return IOMODE_NOT_SPECIFIED; } // end AtaUmode() +LONG +NTAPI +AtaSAmode(PIDENTIFY_DATA2 ident) { + if(!ident->SataCapabilities || + ident->SataCapabilities == 0xffff) { + return IOMODE_NOT_SPECIFIED; + } + if(ident->SataCapabilities & ATA_SATA_GEN3) { + return ATA_SA600; + } else + if(ident->SataCapabilities & ATA_SATA_GEN2) { + return ATA_SA300; + } else + if(ident->SataCapabilities & ATA_SATA_GEN1) { + return ATA_SA150; + } + return IOMODE_NOT_SPECIFIED; +} // end AtaSAmode() #ifndef UNIATA_CORE @@ -1581,6 +1607,12 @@ IssueIdentify( deviceExtension->FullIdentifyData.SataSupport, deviceExtension->FullIdentifyData.SataCapabilities)); + LunExt->LimitedTransferMode = + LunExt->OrigTransferMode = + (UCHAR)ata_cur_mode_from_ident(&(deviceExtension->FullIdentifyData)); + + KdPrint2((PRINT_PREFIX "OrigTransferMode: %x\n", LunExt->OrigTransferMode)); + // Check out a few capabilities / limitations of the device. if (deviceExtension->FullIdentifyData.RemovableStatus & 1) { // Determine if this drive supports the MSN functions. @@ -3001,7 +3033,7 @@ AtapiHwInitialize__( } PreferedMode = LunExt->opt_MaxTransferMode; - if(PreferedMode == 0xffffffff) { + if((PreferedMode == 0xffffffff) || (PreferedMode > chan->MaxTransferMode)) { KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode)); PreferedMode = chan->MaxTransferMode; } @@ -3012,14 +3044,12 @@ AtapiHwInitialize__( } KdPrint2((PRINT_PREFIX " try mode %#x\n", PreferedMode)); - LunExt->OrigTransferMode = LunExt->LimitedTransferMode = LunExt->TransferMode = (CHAR)PreferedMode; AtapiDmaInit__(deviceExtension, LunExt); - LunExt->OrigTransferMode = LunExt->LimitedTransferMode = LunExt->TransferMode; KdPrint2((PRINT_PREFIX "Using %#x mode\n", LunExt->TransferMode)); @@ -5033,11 +5063,10 @@ IntrPrepareResetController: } else { AtaReq->WordsLeft -= AtaReq->WordsTransfered; } - if(AtaReq->WordsLeft) { + if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) { status = SRB_STATUS_DATA_OVERRUN; - } else { - status = SRB_STATUS_SUCCESS; } + status = SRB_STATUS_SUCCESS; chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION; goto CompleteRequest; } else @@ -5106,11 +5135,13 @@ IntrPrepareResetController: "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount)); if(AtaReq->WordsLeft > wordCount) { AtaReq->WordsLeft -= wordCount; + AtaReq->WordsTransfered += wordCount; AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; goto ReturnEnableIntr; } dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/); } + AtaReq->WordsTransfered = AtaReq->WordsLeft; AtaReq->WordsLeft = 0; status = SRB_STATUS_SUCCESS; chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION; @@ -5152,6 +5183,7 @@ IntrPrepareResetController: // Advance data buffer pointer and bytes left. AtaReq->DataBuffer += wordCount; AtaReq->WordsLeft -= wordCount; + AtaReq->WordsTransfered += wordCount; if (atapiDev) { AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; @@ -5205,12 +5237,14 @@ IntrPrepareResetController: "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount)); if(AtaReq->WordsLeft > wordCount) { AtaReq->WordsLeft -= wordCount; + AtaReq->WordsTransfered += wordCount; AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR; goto ReturnEnableIntr; } dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/); } //ASSERT(AtaReq->WordsLeft == wordCount); + AtaReq->WordsTransfered = AtaReq->WordsLeft; AtaReq->WordsLeft = 0; status = SRB_STATUS_SUCCESS; chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION; @@ -5281,6 +5315,7 @@ IntrPrepareResetController: // Advance data buffer pointer and bytes left. AtaReq->DataBuffer += wordCount; AtaReq->WordsLeft -= wordCount; + AtaReq->WordsTransfered += wordCount; // Check for read command complete. if (AtaReq->WordsLeft == 0) { @@ -5358,13 +5393,14 @@ IntrPrepareResetController: // Command complete. if(DmaTransfer) { KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was DmaTransfer\n")); + AtaReq->WordsTransfered = AtaReq->WordsLeft; AtaReq->WordsLeft = 0; } - if (AtaReq->WordsLeft) { - status = SRB_STATUS_DATA_OVERRUN; - } else { + //if (AtaReq->WordsLeft) { + // status = SRB_STATUS_DATA_OVERRUN; + //} else { status = SRB_STATUS_SUCCESS; - } + //} #ifdef UNIATA_DUMP_ATAPI if(srb && @@ -5419,6 +5455,12 @@ CompleteRequest: KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, srbstatus %x\n", status)); // Check and see if we are processing our secret (mechanism status/request sense) srb + + if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) { + KdPrint2((PRINT_PREFIX "WordsLeft %#x -> SRB_STATUS_SUCCESS\n", AtaReq->WordsLeft)); + status = SRB_STATUS_DATA_OVERRUN; + } + if (AtaReq->OriginalSrb) { ULONG srbStatus; @@ -5691,10 +5733,10 @@ PIO_wait_DRQ: } } if(status == SRB_STATUS_SUCCESS) { - if(!(deviceExtension->HwFlags & UNIATA_AHCI)) { - // This should be set in UniataAhciEndTransaction() for AHCI - AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2; - } + //if(!(deviceExtension->HwFlags & UNIATA_AHCI) && !atapiDev) { + // // This should be set in UniataAhciEndTransaction() for AHCI + // 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", @@ -6788,7 +6830,6 @@ GetLba2: // check if DMA read/write if(deviceExtension->HwFlags & UNIATA_SATA) { - // DEBUG !!!! for TEST ONLY KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (ahci)\n")); use_dma = TRUE; goto setup_dma; @@ -8809,8 +8850,16 @@ do_bus_reset: //ULONG ldev = GET_LDEV2(AtaCtl->addr.PathId, AtaCtl->addr.TargetId, 0); ULONG DeviceNumber = AtaCtl->addr.TargetId; BOOLEAN bad_ldev; - ULONG i; + ULONG i, pos; + + pos = FIELD_OFFSET(UNIATA_CTL, RawData); //chan = &(deviceExtension->chan[lChannel]); + if(len < pos) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + FIELD_OFFSET(UNIATA_CTL, RawData) )); + status = SRB_STATUS_DATA_OVERRUN; + break; + } if(AtaCtl->addr.Lun || AtaCtl->addr.TargetId >= deviceExtension->NumberLuns || @@ -8875,6 +8924,12 @@ handle_bad_ldev: } goto uata_ctl_queue; case IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE: + if(len < pos+sizeof(AtaCtl->SetMode)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->SetMode) )); + status = SRB_STATUS_DATA_OVERRUN; + goto complete_req; + } if(!AtaCtl->SetMode.ApplyImmediately) { break; } @@ -8905,6 +8960,12 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: rescan bus\n")); + if(len < pos+sizeof(AtaCtl->FindDelDev)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->FindDelDev) )); + status = SRB_STATUS_DATA_OVERRUN; + goto complete_req; + } if(AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE) { KdPrint2((PRINT_PREFIX "AtapiStartIo: unhide from further detection\n")); if(AtaCtl->addr.TargetId != 0xff) { @@ -8929,10 +8990,17 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: remove %#x:%#x\n", AtaCtl->addr.PathId, AtaCtl->addr.TargetId)); + if(len < pos+sizeof(AtaCtl->FindDelDev)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->FindDelDev) )); + status = SRB_STATUS_DATA_OVERRUN; + goto complete_req; + } LunExt->DeviceFlags = 0; if(AtaCtl->FindDelDev.Flags & UNIATA_REMOVE_FLAGS_HIDE) { KdPrint2((PRINT_PREFIX "AtapiStartIo: hide from further detection\n")); - LunExt->DeviceFlags |= DFLAGS_HIDDEN; + //LunExt->DeviceFlags |= DFLAGS_HIDDEN; + UniataForgetDevice(LunExt); } for(i=0; iFindDelDev.WaitForPhysicalLink && i<30; i++) { @@ -8946,6 +9014,12 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Set transfer mode\n")); + if(len < pos+sizeof(AtaCtl->SetMode)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->SetMode) )); + status = SRB_STATUS_DATA_OVERRUN; + goto complete_req; + } if(AtaCtl->SetMode.OrigMode != IOMODE_NOT_SPECIFIED) { LunExt->OrigTransferMode = (UCHAR)(AtaCtl->SetMode.OrigMode); } @@ -8973,9 +9047,16 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Get transfer mode\n")); + if(len < pos+sizeof(AtaCtl->GetMode)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->GetMode) )); + status = SRB_STATUS_DATA_OVERRUN; + goto complete_req; + } AtaCtl->GetMode.OrigMode = LunExt->OrigTransferMode; AtaCtl->GetMode.MaxMode = LunExt->LimitedTransferMode; AtaCtl->GetMode.CurrentMode = LunExt->TransferMode; + AtaCtl->GetMode.PhyMode = LunExt->PhyTransferMode; status = SRB_STATUS_SUCCESS; break; @@ -8984,6 +9065,12 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Get version\n")); + if(len < pos+sizeof(AtaCtl->Version)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->Version) )); + status = SRB_STATUS_DATA_OVERRUN; + goto complete_req; + } AtaCtl->Version.Length = sizeof(GETDRVVERSION); AtaCtl->Version.VersionMj = UNIATA_VER_MJ; AtaCtl->Version.VersionMn = UNIATA_VER_MN; @@ -8997,14 +9084,13 @@ uata_ctl_queue: KdPrint2((PRINT_PREFIX "AtapiStartIo: Get adapter info\n")); - AtaCtl->AdapterInfo.HeaderLength = FIELD_OFFSET(ADAPTERINFO, Chan); - - if(len < AtaCtl->AdapterInfo.HeaderLength + sizeof(AtaCtl->AdapterInfo.Chan)) { - KdPrint2((PRINT_PREFIX "AtapiStartIo: Buffer too small: %#x < %#x\n", len, - AtaCtl->AdapterInfo.HeaderLength + sizeof(AtaCtl->AdapterInfo.Chan))); + if(len < pos+sizeof(AtaCtl->AdapterInfo)) { + KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len, + pos+sizeof(AtaCtl->AdapterInfo) )); status = SRB_STATUS_DATA_OVERRUN; - break; + goto complete_req; } + AtaCtl->AdapterInfo.HeaderLength = sizeof(ADAPTERINFO); AtaCtl->AdapterInfo.DevID = deviceExtension->DevID; AtaCtl->AdapterInfo.RevID = deviceExtension->RevID; @@ -9031,8 +9117,35 @@ uata_ctl_queue: } AtaCtl->AdapterInfo.ChanInfoValid = FALSE; AtaCtl->AdapterInfo.LunInfoValid = FALSE; + AtaCtl->AdapterInfo.ChanHeaderLengthValid = TRUE; - RtlZeroMemory(&AtaCtl->AdapterInfo.Chan, sizeof(AtaCtl->AdapterInfo.Chan)); + pos += AtaCtl->AdapterInfo.HeaderLength; + + // zero tail + RtlZeroMemory(((PCHAR)AtaCtl)+pos, + len-pos); + + if(len >= pos+AtaCtl->AdapterInfo.NumberChannels*sizeof(CHANINFO)) { + PCHANINFO ChanInfo = (PCHANINFO)( ((PCHAR)AtaCtl)+pos ); + PHW_CHANNEL cur_chan; + KdPrint2((PRINT_PREFIX "AtapiStartIo: Fill channel info\n")); + for(i=0;iAdapterInfo.NumberChannels;i++) { + KdPrint2((PRINT_PREFIX "chan[%d] %x\n", i, cur_chan)); + cur_chan = &(deviceExtension->chan[i]); + ChanInfo->MaxTransferMode = cur_chan->MaxTransferMode; + ChanInfo->ChannelCtrlFlags = cur_chan->ChannelCtrlFlags; + RtlCopyMemory(&(ChanInfo->QueueStat), &(cur_chan->QueueStat), sizeof(ChanInfo->QueueStat)); + ChanInfo->ReorderCount = cur_chan->ReorderCount; + ChanInfo->IntersectCount = cur_chan->IntersectCount; + ChanInfo->TryReorderCount = cur_chan->TryReorderCount; + ChanInfo->TryReorderHeadCount = cur_chan->TryReorderHeadCount; + ChanInfo->TryReorderTailCount = cur_chan->TryReorderTailCount; + //ChanInfo->opt_MaxTransferMode = cur_chan->opt_MaxTransferMode; + ChanInfo++; + } + AtaCtl->AdapterInfo.ChanInfoValid = TRUE; + AtaCtl->AdapterInfo.ChanHeaderLength = sizeof(*ChanInfo); + } status = SRB_STATUS_SUCCESS; break; diff --git a/reactos/drivers/storage/ide/uniata/id_dma.cpp b/reactos/drivers/storage/ide/uniata/id_dma.cpp index 8c4c3da9a4c..208f07dda91 100644 --- a/reactos/drivers/storage/ide/uniata/id_dma.cpp +++ b/reactos/drivers/storage/ide/uniata/id_dma.cpp @@ -879,9 +879,23 @@ AtaSetTransferMode( KdPrint3((PRINT_PREFIX " assume that drive doesn't support mode swithing using PIO%d\n", apiomode)); mode = ATA_PIO0 + apiomode; } - //if(mode <= ATA_UDMA6) { - LunExt->TransferMode = (UCHAR)mode; - //} + // SATA sets actual transfer rate in LunExt on init. + // There is no run-time SATA rate adjustment yet. + // On the other hand, we may turn SATA device in PIO mode + LunExt->TransferMode = (UCHAR)mode; + if(deviceExtension->HwFlags & UNIATA_SATA) { + if(mode < ATA_SA150) { + LunExt->PhyTransferMode = max(LunExt->PhyTransferMode, LunExt->TransferMode); + } else { + LunExt->PhyTransferMode = LunExt->TransferMode; + } + } else { + if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) { + LunExt->PhyTransferMode = max(LunExt->LimitedTransferMode, LunExt->TransferMode); + } else { + LunExt->PhyTransferMode = LunExt->TransferMode; + } + } return TRUE; } // end AtaSetTransferMode() @@ -999,8 +1013,7 @@ AtapiDmaInit( if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || chan->MaxTransferMode >= ATA_SA150) { /* some drives report UDMA6, some UDMA5 */ /* ATAPI may not have SataCapabilities set in IDENTIFY DATA */ - if(LunExt->IdentifyData.SataCapabilities != 0x0000 && - LunExt->IdentifyData.SataCapabilities != 0xffff) { + if(ata_is_sata(&(LunExt->IdentifyData))) { //udmamode = min(udmamode, 6); KdPrint2((PRINT_PREFIX "LunExt->LimitedTransferMode %x, LunExt->OrigTransferMode %x\n", LunExt->LimitedTransferMode, LunExt->OrigTransferMode)); @@ -1011,7 +1024,7 @@ AtapiDmaInit( } else { KdPrint2((PRINT_PREFIX "SATA -> PATA adapter ?\n")); - if (udmamode > 2 && !LunExt->IdentifyData.HwResCableId) { + if (udmamode > 2 && (!LunExt->IdentifyData.HwResCableId || (LunExt->IdentifyData.HwResValid != IDENTIFY_CABLE_ID_VALID) )) { KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n")); udmamode = 2; apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0)); @@ -1041,9 +1054,8 @@ AtapiDmaInit( goto try_generic_dma; } - if(udmamode > 2 && !LunExt->IdentifyData.HwResCableId) { - if(LunExt->IdentifyData.SataCapabilities != 0x0000 && - LunExt->IdentifyData.SataCapabilities != 0xffff) { + if(udmamode > 2 && (!LunExt->IdentifyData.HwResCableId || (LunExt->IdentifyData.HwResValid != IDENTIFY_CABLE_ID_VALID)) ) { + if(ata_is_sata(&(LunExt->IdentifyData))) { KdPrint2((PRINT_PREFIX "AtapiDmaInit: SATA beyond adapter or Controller compat mode\n")); } else { KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n")); diff --git a/reactos/drivers/storage/ide/uniata/id_init.cpp b/reactos/drivers/storage/ide/uniata/id_init.cpp index ea20552a8d0..bc844ca4c15 100644 --- a/reactos/drivers/storage/ide/uniata/id_init.cpp +++ b/reactos/drivers/storage/ide/uniata/id_init.cpp @@ -1350,10 +1350,11 @@ hpt_cable80( GetPciConfig1(0x5a, res); res = res & (channel ? 0x01 : 0x02); SetPciConfig1(reg, val); + KdPrint2((PRINT_PREFIX "hpt_cable80(%d) = %d\n", channel, !res)); return !res; } // end hpt_cable80() - +/* ULONG NTAPI via_cable80( @@ -1398,9 +1399,11 @@ via_cable80( res |= TRUE; //(1 << (1 - (i >> 4))); } } + KdPrint2((PRINT_PREFIX "via_cable80(%d) = %d\n", channel, res)); return res; } // end via_cable80() +*/ BOOLEAN NTAPI @@ -1426,9 +1429,11 @@ generic_cable80( GetPciConfig1(pci_reg, tmp8); if(!(tmp8 & (1 << (channel << bit_offs)))) { chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2); + KdPrint2((PRINT_PREFIX "generic_cable80(%d, %#x, %d) = 0\n", channel, pci_reg, bit_offs)); return FALSE; } + KdPrint2((PRINT_PREFIX "generic_cable80(%d, %#x, %d) = 1\n", channel, pci_reg, bit_offs)); return TRUE; } // end generic_cable80() @@ -1599,7 +1604,7 @@ NTAPI AtapiChipInit( IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, - IN ULONG channel // physical channel + IN ULONG channel // logical channel ) { PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension; @@ -1628,10 +1633,12 @@ AtapiChipInit( c = CHAN_NOT_SPECIFIED; break; default: - c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers) + //c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers) + c = channel; + channel += deviceExtension->Channel; } - KdPrint2((PRINT_PREFIX "AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber, channel )); + KdPrint2((PRINT_PREFIX "AtapiChipInit: dev %#x, ph chan %d, c %d\n", DeviceNumber, channel, c)); KdPrint2((PRINT_PREFIX "HwFlags: %#x\n", deviceExtension->HwFlags)); KdPrint2((PRINT_PREFIX "VendorID/DeviceID/Rev %#x/%#x/%#x\n", VendorID, DeviceID, RevID)); @@ -2236,11 +2243,12 @@ AtapiChipInit( UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0); break; } - +/* // check 80-pin cable if(!via_cable80(deviceExtension, channel)) { chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2); } +*/ } break; diff --git a/reactos/drivers/storage/ide/uniata/id_sata.cpp b/reactos/drivers/storage/ide/uniata/id_sata.cpp index 70a8c869064..6f6c8ac5c8d 100644 --- a/reactos/drivers/storage/ide/uniata/id_sata.cpp +++ b/reactos/drivers/storage/ide/uniata/id_sata.cpp @@ -68,7 +68,14 @@ UniataSataConnect( if(SStatus.SPD == SStatus_SPD_Gen1 || SStatus.SPD == SStatus_SPD_Gen2 || SStatus.SPD == SStatus_SPD_Gen3) { + // SATA sets actual transfer rate in LunExt on init. + // There is no run-time SATA rate adjustment yet. + // On the other hand, we may turn SATA device in PIO mode + // TODO: make separate states for interface speed and transfer mode (DMA vs PIO) + chan->lun[0]->LimitedTransferMode = + chan->lun[0]->PhyTransferMode = chan->lun[0]->TransferMode = ATA_SA150 + (UCHAR)(SStatus.SPD - 1); + KdPrint2((PRINT_PREFIX "SATA TransferMode %#x\n", chan->lun[0]->TransferMode)); if(chan->MaxTransferMode < chan->lun[0]->TransferMode) { KdPrint2((PRINT_PREFIX "SATA upd chan TransferMode\n")); diff --git a/reactos/drivers/storage/ide/uniata/uata_ctl.h b/reactos/drivers/storage/ide/uniata/uata_ctl.h index e377be310bc..9a2ccce4714 100644 --- a/reactos/drivers/storage/ide/uniata/uata_ctl.h +++ b/reactos/drivers/storage/ide/uniata/uata_ctl.h @@ -85,7 +85,7 @@ typedef struct _GETTRANSFERMODE { ULONG MaxMode; ULONG OrigMode; ULONG CurrentMode; - ULONG Reserved; + ULONG PhyMode; // since v0.42i6 } GETTRANSFERMODE, *PGETTRANSFERMODE; typedef struct _GETDRVVERSION { @@ -100,14 +100,13 @@ typedef struct _GETDRVVERSION { typedef struct _CHANINFO { ULONG MaxTransferMode; // may differ from Controller's value due to 40-pin cable ULONG ChannelCtrlFlags; -//#ifdef QUEUE_STATISTICS LONGLONG QueueStat[MAX_QUEUE_STAT]; LONGLONG ReorderCount; LONGLONG IntersectCount; LONGLONG TryReorderCount; LONGLONG TryReorderHeadCount; LONGLONG TryReorderTailCount; /* in-order requests */ -//#endif //QUEUE_STATISTICS +// ULONG opt_MaxTransferMode; // user-specified } CHANINFO, *PCHANINFO; typedef struct _ADAPTERINFO { @@ -143,13 +142,15 @@ typedef struct _ADAPTERINFO { ULONG NumberChannels; BOOLEAN ChanInfoValid; - UCHAR NumberLuns; + UCHAR NumberLuns; // per channel BOOLEAN LunInfoValid; - CHAR Reserved; + BOOLEAN ChanHeaderLengthValid; // since v0.42i8 ULONG AdapterInterfaceType; + ULONG ChanHeaderLength; + ULONG LunHeaderLength; - CHANINFO Chan[AHCI_MAX_PORT]; + //CHANINFO Chan[0]; } ADAPTERINFO, *PADAPTERINFO; @@ -216,7 +217,9 @@ typedef struct _ATA_PASS_THROUGH_DIRECT { #endif //ATA_FLAGS_DRDY_REQUIRED -#pragma pack(1) +#pragma pack(pop) + +#pragma pack(push, 1) typedef struct _IDEREGS_EX { UCHAR bFeaturesReg; // Used for specifying SMART "commands". UCHAR bSectorCountReg; // IDE sector count register @@ -263,11 +266,15 @@ typedef struct _UNIATA_REG_IO_HDR { ULONG ItemCount; UNIATA_REG_IO r[1]; } UNIATA_REG_IO_HDR, *PUNIATA_REG_IO_HDR; -#pragma pack() + +#pragma pack(pop) + +#pragma pack(push, 1) typedef struct _UNIATA_CTL { SRB_IO_CONTROL hdr; SCSI_ADDRESS addr; + ULONG Reserved; union { UCHAR RawData[1]; ADDREMOVEDEV FindDelDev;