[UNIATA] [ATACTL]

* Sync to 0.43a1.
See issue #7237 for more details.

svn path=/trunk/; revision=57072
This commit is contained in:
Amine Khaldi 2012-08-13 16:25:08 +00:00
parent f3e0eb8fe0
commit 9f4cee2ca1
9 changed files with 423 additions and 198 deletions

View file

@ -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:<bus id>\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:<device id>\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; i<argc; i++) {
@ -1633,7 +1631,7 @@ main (
j = strlen(argv[i])-1;
break;
case 'd' :
if(cmd && cmd != CMD_ATA_FIND && cmd != CMD_ATA_HIDE) {
if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE)) {
print_help();
}
i++;
@ -1680,12 +1678,12 @@ main (
d_dev = 127;
l_dev = 127;
} else
if(d_dev == -1 && b_dev != -1) {
if((d_dev == -1) && (b_dev != -1)) {
d_dev = 127;
l_dev = 127;
}
if(d_dev != -1 && b_dev != -1) {
if((d_dev != -1) && (b_dev != -1)) {
dev_id = (b_dev << 16) | (d_dev << 8) | l_dev;
}
if(cmd == CMD_ATA_LIST) {

View file

@ -296,6 +296,44 @@ typedef struct _MODE_PARAMETER_HEADER_10 {
UCHAR Reserved[5];
}MODE_PARAMETER_HEADER_10, *PMODE_PARAMETER_HEADER_10;
//
// 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*/
//
// IDE command definitions
//
@ -767,6 +805,8 @@ typedef struct _IDENTIFY_DATA {
USHORT HwResCableId : 1;
USHORT HwResValid : 2;
#define IDENTIFY_CABLE_ID_VALID 0x01
USHORT CurrentAcoustic : 8; // 94
USHORT VendorAcoustic : 8;
@ -1489,6 +1529,83 @@ extern UCHAR AtaCommandFlags[256];
#endif //USER_MODE
__inline
BOOLEAN
ata_is_sata(
PIDENTIFY_DATA ident
)
{
return (ident->SataCapabilities && 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__

View file

@ -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

View file

@ -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;

View file

@ -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; i<AtaCtl->FindDelDev.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;i<AtaCtl->AdapterInfo.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;

View file

@ -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"));

View file

@ -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;

View file

@ -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"));

View file

@ -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;