mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[UNIATA] [ATACTL]
* Sync to 0.43a1. See issue #7237 for more details. svn path=/trunk/; revision=57072
This commit is contained in:
parent
f3e0eb8fe0
commit
9f4cee2ca1
9 changed files with 423 additions and 198 deletions
|
@ -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 = 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) {
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
// 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"));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue