mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:25:41 +00:00
* Reapply r57265 now that the testbot issues are solved.
[UNIATA]: Sync to 0.43f5. [ATACTL]: Sync to 0.43f5. CORE-6563 #comment Committed the 0.43f5 sync. svn path=/trunk/; revision=57292
This commit is contained in:
parent
134c7287e0
commit
534a4aec24
15 changed files with 1762 additions and 886 deletions
|
@ -39,6 +39,13 @@ char* g_bb_list = NULL;
|
||||||
int gRadix = 16;
|
int gRadix = 16;
|
||||||
PADAPTERINFO g_AdapterInfo = NULL;
|
PADAPTERINFO g_AdapterInfo = NULL;
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
ata_power_mode(
|
||||||
|
int bus_id,
|
||||||
|
int dev_id,
|
||||||
|
int power_mode
|
||||||
|
);
|
||||||
|
|
||||||
void print_help() {
|
void print_help() {
|
||||||
printf("Usage:\n"
|
printf("Usage:\n"
|
||||||
" atactl -<switches> c|s<controller id>:b<bus id>:d<device id>[:l<lun>]\n"
|
" atactl -<switches> c|s<controller id>:b<bus id>:d<device id>[:l<lun>]\n"
|
||||||
|
@ -61,6 +68,12 @@ void print_help() {
|
||||||
" d [XXX] lock ATA/SATA bus for device removal for XXX seconds or\n"
|
" d [XXX] lock ATA/SATA bus for device removal for XXX seconds or\n"
|
||||||
" for %d seconds if no lock timeout specified.\n"
|
" for %d seconds if no lock timeout specified.\n"
|
||||||
" can be used with -h, -m or standalone.\n"
|
" can be used with -h, -m or standalone.\n"
|
||||||
|
" D [XXX] disable device (turn into sleep mode) and lock ATA/SATA bus \n"
|
||||||
|
" for device removal for XXX seconds or\n"
|
||||||
|
" for %d seconds if no lock timeout specified.\n"
|
||||||
|
" can be used with -h, -m or standalone.\n"
|
||||||
|
" pX change power state to X, where X is\n"
|
||||||
|
" 0 - active, 1 - idle, 2 - standby, 3 - sleep\n"
|
||||||
" r (R)eset device\n"
|
" r (R)eset device\n"
|
||||||
" ba (A)ssign (B)ad-block list\n"
|
" ba (A)ssign (B)ad-block list\n"
|
||||||
" bl get assigned (B)ad-block (L)ist\n"
|
" bl get assigned (B)ad-block (L)ist\n"
|
||||||
|
@ -116,6 +129,7 @@ void print_help() {
|
||||||
#define CMD_ATA_MODE 0x04
|
#define CMD_ATA_MODE 0x04
|
||||||
#define CMD_ATA_RESET 0x05
|
#define CMD_ATA_RESET 0x05
|
||||||
#define CMD_ATA_BBLK 0x06
|
#define CMD_ATA_BBLK 0x06
|
||||||
|
#define CMD_ATA_POWER 0x07
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
ata_open_dev(
|
ata_open_dev(
|
||||||
|
@ -304,6 +318,76 @@ ata_send_ioctl(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} // end ata_send_ioctl()
|
} // end ata_send_ioctl()
|
||||||
|
|
||||||
|
int
|
||||||
|
ata_send_scsi(
|
||||||
|
HANDLE h,
|
||||||
|
PSCSI_ADDRESS addr,
|
||||||
|
PCDB cdb,
|
||||||
|
UCHAR cdbLength,
|
||||||
|
PVOID Buffer,
|
||||||
|
ULONG BufferLength,
|
||||||
|
BOOLEAN DataIn,
|
||||||
|
PSENSE_DATA senseData,
|
||||||
|
PULONG returned
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG status;
|
||||||
|
PSCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
|
||||||
|
ULONG data_len = BufferLength;
|
||||||
|
ULONG len;
|
||||||
|
|
||||||
|
len = BufferLength + offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf);
|
||||||
|
|
||||||
|
sptwb = (PSCSI_PASS_THROUGH_WITH_BUFFERS)GlobalAlloc(GMEM_FIXED, len);
|
||||||
|
if(!sptwb) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
memset(sptwb, 0, offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf));
|
||||||
|
|
||||||
|
sptwb->spt.Length = sizeof(SCSI_PASS_THROUGH);
|
||||||
|
sptwb->spt.PathId = addr->PathId;
|
||||||
|
sptwb->spt.TargetId = addr->TargetId;
|
||||||
|
sptwb->spt.Lun = addr->Lun;
|
||||||
|
sptwb->spt.CdbLength = cdbLength;
|
||||||
|
sptwb->spt.SenseInfoLength = 24;
|
||||||
|
sptwb->spt.DataIn = Buffer ? (DataIn ? SCSI_IOCTL_DATA_IN : SCSI_IOCTL_DATA_OUT) : 0;
|
||||||
|
sptwb->spt.DataTransferLength = BufferLength;
|
||||||
|
sptwb->spt.TimeOutValue = 10;
|
||||||
|
sptwb->spt.DataBufferOffset =
|
||||||
|
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
|
||||||
|
sptwb->spt.SenseInfoOffset =
|
||||||
|
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
|
||||||
|
memcpy(&sptwb->spt.Cdb, cdb, cdbLength);
|
||||||
|
|
||||||
|
if(Buffer && !DataIn) {
|
||||||
|
memcpy(&sptwb->ucSenseBuf, Buffer, BufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = DeviceIoControl(h,
|
||||||
|
IOCTL_SCSI_PASS_THROUGH,
|
||||||
|
sptwb,
|
||||||
|
(Buffer && !DataIn) ? len : sizeof(SCSI_PASS_THROUGH),
|
||||||
|
sptwb,
|
||||||
|
(Buffer && DataIn) ? len : offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf),
|
||||||
|
returned,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
if(Buffer && DataIn) {
|
||||||
|
memcpy(Buffer, &sptwb->ucDataBuf, BufferLength);
|
||||||
|
}
|
||||||
|
if(senseData) {
|
||||||
|
memcpy(senseData, &sptwb->ucSenseBuf, sizeof(sptwb->ucSenseBuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalFree(sptwb);
|
||||||
|
|
||||||
|
if(!status) {
|
||||||
|
status = GetLastError();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
} // end ata_send_scsi()
|
||||||
|
|
||||||
IO_SCSI_CAPABILITIES g_capabilities;
|
IO_SCSI_CAPABILITIES g_capabilities;
|
||||||
UCHAR g_inquiry_buffer[2048];
|
UCHAR g_inquiry_buffer[2048];
|
||||||
|
|
||||||
|
@ -535,9 +619,10 @@ ata_check_unit(
|
||||||
GETTRANSFERMODE IoMode;
|
GETTRANSFERMODE IoMode;
|
||||||
PSENDCMDOUTPARAMS pout;
|
PSENDCMDOUTPARAMS pout;
|
||||||
PIDENTIFY_DATA ident;
|
PIDENTIFY_DATA ident;
|
||||||
|
PINQUIRYDATA scsi_ident;
|
||||||
char buff[sizeof(SENDCMDOUTPARAMS)+/*sizeof(IDENTIFY_DATA)*/2048];
|
char buff[sizeof(SENDCMDOUTPARAMS)+/*sizeof(IDENTIFY_DATA)*/2048];
|
||||||
char mode_str[12];
|
char mode_str[12];
|
||||||
ULONG bus_id = (dev_id >> 24) & 0xff;
|
//ULONG bus_id = (dev_id >> 24) & 0xff;
|
||||||
BOOLEAN found = FALSE;
|
BOOLEAN found = FALSE;
|
||||||
SENDCMDINPARAMS pin;
|
SENDCMDINPARAMS pin;
|
||||||
int io_mode = -1;
|
int io_mode = -1;
|
||||||
|
@ -546,7 +631,7 @@ ata_check_unit(
|
||||||
char lun_str[10];
|
char lun_str[10];
|
||||||
HKEY hKey2;
|
HKEY hKey2;
|
||||||
ULONGLONG max_lba = -1;
|
ULONGLONG max_lba = -1;
|
||||||
USHORT chs[3];
|
USHORT chs[3] = { 0 };
|
||||||
|
|
||||||
if(dev_id != -1) {
|
if(dev_id != -1) {
|
||||||
dev_id &= 0x00ffffff;
|
dev_id &= 0x00ffffff;
|
||||||
|
@ -594,7 +679,7 @@ ata_check_unit(
|
||||||
} else {
|
} else {
|
||||||
mode_str[0] = 0;
|
mode_str[0] = 0;
|
||||||
}
|
}
|
||||||
printf(" b%u [%s]\n",
|
printf(" b%lu [%s]\n",
|
||||||
i,
|
i,
|
||||||
mode_str
|
mode_str
|
||||||
);
|
);
|
||||||
|
@ -617,7 +702,8 @@ ata_check_unit(
|
||||||
|
|
||||||
if(l_dev_id == dev_id || dev_id == -1) {
|
if(l_dev_id == dev_id || dev_id == -1) {
|
||||||
|
|
||||||
if(!memcmp(&(inquiryData->InquiryData[8]), UNIATA_COMM_PORT_VENDOR_STR, 24)) {
|
scsi_ident = (PINQUIRYDATA)&(inquiryData->InquiryData);
|
||||||
|
if(!memcmp(&(scsi_ident->VendorId[0]), UNIATA_COMM_PORT_VENDOR_STR, 24)) {
|
||||||
// skip communication port
|
// skip communication port
|
||||||
goto next_dev;
|
goto next_dev;
|
||||||
}
|
}
|
||||||
|
@ -685,29 +771,27 @@ ata_check_unit(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status) {
|
|
||||||
if(!g_extended) {
|
if(!g_extended) {
|
||||||
printf(" b%u:d%d%s %24.24s %4.4s ",
|
printf(" b%lu:d%d%s %24.24s %4.4s ",
|
||||||
i,
|
i,
|
||||||
inquiryData->TargetId,
|
inquiryData->TargetId,
|
||||||
lun_str,
|
lun_str,
|
||||||
/*(inquiryData->DeviceClaimed) ? "Y" : "N",*/
|
/*(inquiryData->DeviceClaimed) ? "Y" : "N",*/
|
||||||
(g_extended ? (PUCHAR)"" : &inquiryData->InquiryData[8]),
|
(g_extended ? (PUCHAR)"" : &scsi_ident->VendorId[0]),
|
||||||
(g_extended ? (PUCHAR)"" : &inquiryData->InquiryData[8+24])
|
(g_extended ? (PUCHAR)"" : &scsi_ident->ProductRevisionLevel[0])
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
printf(" b%u:d%d%s ",
|
printf(" b%lu:d%d%s ",
|
||||||
i,
|
i,
|
||||||
inquiryData->TargetId,
|
inquiryData->TargetId,
|
||||||
lun_str
|
lun_str
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if(io_mode == -1) {
|
|
||||||
io_mode = ata_cur_mode_from_ident(ident);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
goto next_dev;
|
|
||||||
|
|
||||||
|
if(status) {
|
||||||
|
if(io_mode == -1) {
|
||||||
|
io_mode = ata_cur_mode_from_ident(ident, IDENT_MODE_ACTIVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(io_mode != -1) {
|
if(io_mode != -1) {
|
||||||
ata_mode_to_str(mode_str, io_mode);
|
ata_mode_to_str(mode_str, io_mode);
|
||||||
|
@ -725,7 +809,8 @@ ata_check_unit(
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
if(status && g_extended) {
|
if(g_extended) {
|
||||||
|
if(status) {
|
||||||
|
|
||||||
BOOLEAN BlockMode_valid = TRUE;
|
BOOLEAN BlockMode_valid = TRUE;
|
||||||
BOOLEAN print_geom = FALSE;
|
BOOLEAN print_geom = FALSE;
|
||||||
|
@ -751,7 +836,7 @@ ata_check_unit(
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf(" Hard Drive ");
|
printf(" Hard Drive ");
|
||||||
print_geom = 1;
|
print_geom = TRUE;
|
||||||
//MOV_DD_SWP(max_lba, ident->UserAddressableSectors);
|
//MOV_DD_SWP(max_lba, ident->UserAddressableSectors);
|
||||||
max_lba = ident->UserAddressableSectors;
|
max_lba = ident->UserAddressableSectors;
|
||||||
if(ident->FeaturesSupport.Address48) {
|
if(ident->FeaturesSupport.Address48) {
|
||||||
|
@ -794,31 +879,69 @@ ata_check_unit(
|
||||||
printf(" C/H/S: %u/%u/%u \n", chs[0], chs[1], chs[2]);
|
printf(" C/H/S: %u/%u/%u \n", chs[0], chs[1], chs[2]);
|
||||||
printf(" LBA: %I64u \n", max_lba);
|
printf(" LBA: %I64u \n", max_lba);
|
||||||
if(max_lba < 2) {
|
if(max_lba < 2) {
|
||||||
printf(" Size: %u kb\n", max_lba/2);
|
printf(" Size: %lu kb\n", (ULONG)(max_lba/2));
|
||||||
} else
|
} else
|
||||||
if(max_lba < 2*1024*1024) {
|
if(max_lba < 2*1024*1024) {
|
||||||
printf(" Size: %u Mb\n", max_lba/2048);
|
printf(" Size: %lu Mb\n", (ULONG)(max_lba/2048));
|
||||||
} else
|
} else
|
||||||
if(max_lba < (ULONG)2*1024*1024*1024) {
|
if(max_lba < (ULONG)2*1024*1024*1024) {
|
||||||
printf(" Size: %u.%u (%u) Gb\n", (ULONG)(max_lba/2048/1024),
|
printf(" Size: %lu.%lu (%lu) Gb\n", (ULONG)(max_lba/2048/1024),
|
||||||
(ULONG)(((max_lba/2048)%1024)/10),
|
(ULONG)(((max_lba/2048)%1024)/10),
|
||||||
(ULONG)(max_lba*512/1000/1000/1000)
|
(ULONG)(max_lba*512/1000/1000/1000)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
printf(" Size: %u.%u (%u) Tb\n", (ULONG)(max_lba/2048/1024/1024),
|
printf(" Size: %lu.%lu (%lu) Tb\n", (ULONG)(max_lba/2048/1024/1024),
|
||||||
(ULONG)((max_lba/2048/1024)%1024)/10,
|
(ULONG)((max_lba/2048/1024)%1024)/10,
|
||||||
(ULONG)(max_lba*512/1000/1000/1000)
|
(ULONG)(max_lba*512/1000/1000/1000)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = 0;
|
len = 0;
|
||||||
if(hKey2 = ata_get_bblist_regh(ident, DevSerial, TRUE)) {
|
if((hKey2 = ata_get_bblist_regh(ident, DevSerial, TRUE))) {
|
||||||
if(RegQueryValueEx(hKey2, DevSerial, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
|
if(RegQueryValueEx(hKey2, DevSerial, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
|
||||||
printf(" !!! Assigned bad-block list !!!\n");
|
printf(" !!! Assigned bad-block list !!!\n");
|
||||||
}
|
}
|
||||||
RegCloseKey(hKey2);
|
RegCloseKey(hKey2);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
switch(scsi_ident->DeviceType) {
|
||||||
|
case DIRECT_ACCESS_DEVICE:
|
||||||
|
if(scsi_ident->RemovableMedia) {
|
||||||
|
printf(" Floppy ");
|
||||||
|
} else {
|
||||||
|
printf(" Hard Drive ");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SEQUENTIAL_ACCESS_DEVICE:
|
||||||
|
printf(" Tape Drive ");
|
||||||
|
break;
|
||||||
|
case PRINTER_DEVICE:
|
||||||
|
printf(" Printer ");
|
||||||
|
break;
|
||||||
|
case PROCESSOR_DEVICE:
|
||||||
|
printf(" Processor ");
|
||||||
|
break;
|
||||||
|
case WRITE_ONCE_READ_MULTIPLE_DEVICE:
|
||||||
|
printf(" WORM Drive ");
|
||||||
|
break;
|
||||||
|
case READ_ONLY_DIRECT_ACCESS_DEVICE:
|
||||||
|
printf(" CDROM Drive ");
|
||||||
|
break;
|
||||||
|
case SCANNER_DEVICE:
|
||||||
|
printf(" Scanner ");
|
||||||
|
break;
|
||||||
|
case OPTICAL_DEVICE:
|
||||||
|
printf(" Optical Drive ");
|
||||||
|
break;
|
||||||
|
case MEDIUM_CHANGER:
|
||||||
|
printf(" Changer ");
|
||||||
|
break;
|
||||||
|
case COMMUNICATION_DEVICE:
|
||||||
|
printf(" Comm. device ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memcpy(&g_ident, ident, sizeof(IDENTIFY_DATA));
|
memcpy(&g_ident, ident, sizeof(IDENTIFY_DATA));
|
||||||
}
|
}
|
||||||
|
@ -887,7 +1010,7 @@ ata_adapter_info(
|
||||||
} else {
|
} else {
|
||||||
if(AdapterInfo->AdapterInterfaceType == PCIBus) {
|
if(AdapterInfo->AdapterInterfaceType == PCIBus) {
|
||||||
slotData.u.AsULONG = AdapterInfo->slotNumber;
|
slotData.u.AsULONG = AdapterInfo->slotNumber;
|
||||||
printf(" PCI Bus/Dev/Func: %u/%u/%u%s\n",
|
printf(" PCI Bus/Dev/Func: %lu/%lu/%lu%s\n",
|
||||||
AdapterInfo->SystemIoBusNumber, slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber,
|
AdapterInfo->SystemIoBusNumber, slotData.u.bits.DeviceNumber, slotData.u.bits.FunctionNumber,
|
||||||
AdapterInfo->AdapterInterfaceType == AdapterInfo->OrigAdapterInterfaceType ? "" : " (ISA-Bridged)");
|
AdapterInfo->AdapterInterfaceType == AdapterInfo->OrigAdapterInterfaceType ? "" : " (ISA-Bridged)");
|
||||||
printf(" VendorId/DevId/Rev: %#04x/%#04x/%#02x\n",
|
printf(" VendorId/DevId/Rev: %#04x/%#04x/%#02x\n",
|
||||||
|
@ -901,7 +1024,7 @@ ata_adapter_info(
|
||||||
if(AdapterInfo->AdapterInterfaceType == Isa) {
|
if(AdapterInfo->AdapterInterfaceType == Isa) {
|
||||||
printf(" ISA Bus\n");
|
printf(" ISA Bus\n");
|
||||||
}
|
}
|
||||||
printf(" IRQ: %d\n", AdapterInfo->BusInterruptLevel);
|
printf(" IRQ: %ld\n", AdapterInfo->BusInterruptLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ata_close_dev(h);
|
ata_close_dev(h);
|
||||||
|
@ -1060,7 +1183,8 @@ ata_hide(
|
||||||
int bus_id,
|
int bus_id,
|
||||||
int dev_id,
|
int dev_id,
|
||||||
int lock,
|
int lock,
|
||||||
int persistent_hide
|
int persistent_hide,
|
||||||
|
int power_mode
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char dev_name[64];
|
char dev_name[64];
|
||||||
|
@ -1073,6 +1197,11 @@ ata_hide(
|
||||||
if(dev_id == -1) {
|
if(dev_id == -1) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(power_mode) {
|
||||||
|
ata_power_mode(bus_id, dev_id, power_mode);
|
||||||
|
}
|
||||||
|
|
||||||
if(lock < 0) {
|
if(lock < 0) {
|
||||||
lock = DEFAULT_REMOVAL_LOCK_TIMEOUT;
|
lock = DEFAULT_REMOVAL_LOCK_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
@ -1261,7 +1390,7 @@ ata_bblk(
|
||||||
}
|
}
|
||||||
|
|
||||||
len = GetFileSize(hf, NULL);
|
len = GetFileSize(hf, NULL);
|
||||||
if(!len || len == -1)
|
if(!len || len == INVALID_FILE_SIZE)
|
||||||
goto exit;
|
goto exit;
|
||||||
bblist = (char*)GlobalAlloc(GMEM_FIXED, len*8);
|
bblist = (char*)GlobalAlloc(GMEM_FIXED, len*8);
|
||||||
}
|
}
|
||||||
|
@ -1310,7 +1439,7 @@ ata_bblk(
|
||||||
j++;
|
j++;
|
||||||
BB_Msg[sizeof(BB_Msg)-1] = 0;
|
BB_Msg[sizeof(BB_Msg)-1] = 0;
|
||||||
k=0;
|
k=0;
|
||||||
while(a = BB_Msg[k]) {
|
while((a = BB_Msg[k])) {
|
||||||
if(a == ' ' || a == '\t' || a == '\r') {
|
if(a == ' ' || a == '\t' || a == '\r') {
|
||||||
k++;
|
k++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1329,7 +1458,7 @@ ata_bblk(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
k0 = k;
|
k0 = k;
|
||||||
while(a = BB_Msg[k]) {
|
while((a = BB_Msg[k])) {
|
||||||
if(a == ' ' || a == '\t' || a == '\r') {
|
if(a == ' ' || a == '\t' || a == '\r') {
|
||||||
BB_Msg[k] = '\t';
|
BB_Msg[k] = '\t';
|
||||||
}
|
}
|
||||||
|
@ -1480,6 +1609,52 @@ exit:
|
||||||
return retval;
|
return retval;
|
||||||
} // end ata_bblk()
|
} // end ata_bblk()
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
ata_power_mode(
|
||||||
|
int bus_id,
|
||||||
|
int dev_id,
|
||||||
|
int power_mode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char dev_name[64];
|
||||||
|
HANDLE h;
|
||||||
|
ULONG status;
|
||||||
|
ULONG returned;
|
||||||
|
SCSI_ADDRESS addr;
|
||||||
|
CDB cdb;
|
||||||
|
SENSE_DATA senseData;
|
||||||
|
|
||||||
|
if(dev_id == -1) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if(!power_mode) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(dev_name, "\\\\.\\Scsi%d:", bus_id);
|
||||||
|
h = ata_open_dev(dev_name);
|
||||||
|
if(!h)
|
||||||
|
return FALSE;
|
||||||
|
addr.PortNumber = bus_id;
|
||||||
|
addr.PathId = (UCHAR)(dev_id >> 16);
|
||||||
|
addr.TargetId = (UCHAR)(dev_id >> 8);
|
||||||
|
addr.Lun = (UCHAR)(dev_id);
|
||||||
|
|
||||||
|
memset(&cdb, 0, sizeof(cdb));
|
||||||
|
cdb.START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
|
||||||
|
cdb.START_STOP.Immediate = 1;
|
||||||
|
cdb.START_STOP.PowerConditions = power_mode;
|
||||||
|
cdb.START_STOP.Start = (power_mode != StartStop_Power_Sleep);
|
||||||
|
|
||||||
|
printf("Changing power state to ...\n");
|
||||||
|
|
||||||
|
status = ata_send_scsi(h, &addr, &cdb, 6,
|
||||||
|
NULL, 0, FALSE,
|
||||||
|
&senseData, &returned);
|
||||||
|
ata_close_dev(h);
|
||||||
|
return TRUE;
|
||||||
|
} // end ata_power_mode()
|
||||||
|
|
||||||
int
|
int
|
||||||
ata_num_to_x_dev(
|
ata_num_to_x_dev(
|
||||||
char a
|
char a
|
||||||
|
@ -1496,7 +1671,7 @@ main (
|
||||||
char* argv[]
|
char* argv[]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ULONG Flags = 0;
|
//ULONG Flags = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
char a;
|
char a;
|
||||||
int bus_id = -1;
|
int bus_id = -1;
|
||||||
|
@ -1507,6 +1682,7 @@ main (
|
||||||
int mode=-1;
|
int mode=-1;
|
||||||
int list_bb=0;
|
int list_bb=0;
|
||||||
int persistent_hide=0;
|
int persistent_hide=0;
|
||||||
|
int power_mode=StartStop_Power_NoChg;
|
||||||
|
|
||||||
printf("Console ATA control utility for Windows NT3.51/NT4/2000/XP/2003\n"
|
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-2012\n"
|
"Version 0." UNIATA_VER_STR ", Copyright (c) Alexander A. Telyatnikov, 2003-2012\n"
|
||||||
|
@ -1516,7 +1692,7 @@ main (
|
||||||
if(!argv[i])
|
if(!argv[i])
|
||||||
continue;
|
continue;
|
||||||
if((a = argv[i][0]) != '-') {
|
if((a = argv[i][0]) != '-') {
|
||||||
for(j=0; a = argv[i][j]; j++) {
|
for(j=0; (a = argv[i][j]); j++) {
|
||||||
switch(a) {
|
switch(a) {
|
||||||
case 'a' :
|
case 'a' :
|
||||||
case 's' :
|
case 's' :
|
||||||
|
@ -1630,10 +1806,47 @@ main (
|
||||||
g_bb_list=argv[i];
|
g_bb_list=argv[i];
|
||||||
j = strlen(argv[i])-1;
|
j = strlen(argv[i])-1;
|
||||||
break;
|
break;
|
||||||
case 'd' :
|
case 'p' :
|
||||||
if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE)) {
|
if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE)) {
|
||||||
print_help();
|
print_help();
|
||||||
}
|
}
|
||||||
|
switch(argv[i][j+1]) {
|
||||||
|
case '0':
|
||||||
|
case 'a':
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
case 'i':
|
||||||
|
power_mode = StartStop_Power_Idle;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
case 's':
|
||||||
|
power_mode = StartStop_Power_Standby;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
case 'p':
|
||||||
|
power_mode = StartStop_Power_Sleep;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
if(power_mode && !cmd) {
|
||||||
|
cmd = CMD_ATA_POWER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D' :
|
||||||
|
power_mode = StartStop_Power_Sleep;
|
||||||
|
if(cmd && (cmd != CMD_ATA_HIDE)) {
|
||||||
|
print_help();
|
||||||
|
}
|
||||||
|
case 'd' :
|
||||||
|
if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE) && (cmd != CMD_ATA_POWER)) {
|
||||||
|
print_help();
|
||||||
|
}
|
||||||
|
if(!cmd) {
|
||||||
|
cmd = CMD_ATA_HIDE;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
if(!argv[i]) {
|
if(!argv[i]) {
|
||||||
print_help();
|
print_help();
|
||||||
|
@ -1699,10 +1912,13 @@ main (
|
||||||
ata_scan(bus_id, dev_id, lock, persistent_hide);
|
ata_scan(bus_id, dev_id, lock, persistent_hide);
|
||||||
} else
|
} else
|
||||||
if(cmd == CMD_ATA_HIDE) {
|
if(cmd == CMD_ATA_HIDE) {
|
||||||
ata_hide(bus_id, dev_id, lock, persistent_hide);
|
ata_hide(bus_id, dev_id, lock, persistent_hide, power_mode);
|
||||||
} else
|
} else
|
||||||
if(cmd == CMD_ATA_BBLK) {
|
if(cmd == CMD_ATA_BBLK) {
|
||||||
ata_bblk(bus_id, dev_id, list_bb);
|
ata_bblk(bus_id, dev_id, list_bb);
|
||||||
|
} else
|
||||||
|
if(cmd == CMD_ATA_POWER) {
|
||||||
|
ata_power_mode(bus_id, dev_id, power_mode);
|
||||||
} else {
|
} else {
|
||||||
print_help();
|
print_help();
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,7 +387,9 @@ typedef struct _MODE_PARAMETER_HEADER_10 {
|
||||||
#define IDE_COMMAND_DOOR_LOCK 0xDE
|
#define IDE_COMMAND_DOOR_LOCK 0xDE
|
||||||
#define IDE_COMMAND_DOOR_UNLOCK 0xDF
|
#define IDE_COMMAND_DOOR_UNLOCK 0xDF
|
||||||
#define IDE_COMMAND_STANDBY_IMMED 0xE0 // flush and spin down
|
#define IDE_COMMAND_STANDBY_IMMED 0xE0 // flush and spin down
|
||||||
|
#define IDE_COMMAND_IDLE_IMMED 0xE1
|
||||||
#define IDE_COMMAND_STANDBY 0xE2 // flush and spin down and enable autopowerdown timer
|
#define IDE_COMMAND_STANDBY 0xE2 // flush and spin down and enable autopowerdown timer
|
||||||
|
#define IDE_COMMAND_IDLE 0xE3
|
||||||
#define IDE_COMMAND_READ_PM 0xE4 // SATA PM
|
#define IDE_COMMAND_READ_PM 0xE4 // SATA PM
|
||||||
#define IDE_COMMAND_SLEEP 0xE6 // flush, spin down and deactivate interface
|
#define IDE_COMMAND_SLEEP 0xE6 // flush, spin down and deactivate interface
|
||||||
#define IDE_COMMAND_FLUSH_CACHE 0xE7
|
#define IDE_COMMAND_FLUSH_CACHE 0xE7
|
||||||
|
@ -559,6 +561,25 @@ typedef union _ATAPI_REGISTERS_2 {
|
||||||
#define ATA_C_F_ENAB_MEDIASTAT 0x95 /* enable media status */
|
#define ATA_C_F_ENAB_MEDIASTAT 0x95 /* enable media status */
|
||||||
#define ATA_C_F_DIS_MEDIASTAT 0x31 /* disable media status */
|
#define ATA_C_F_DIS_MEDIASTAT 0x31 /* disable media status */
|
||||||
|
|
||||||
|
#define ATA_C_F_ENAB_APM 0x05 /* enable advanced power management */
|
||||||
|
#define ATA_C_F_DIS_APM 0x85 /* disable advanced power management */
|
||||||
|
#define ATA_C_F_APM_CNT_MAX_PERF 0xfe /* maximum performance */
|
||||||
|
#define ATA_C_F_APM_CNT_MIN_NO_STANDBY 0x80 /* min. power w/o standby */
|
||||||
|
#define ATA_C_F_APM_CNT_MIN_STANDBY 0x01 /* min. power with standby */
|
||||||
|
|
||||||
|
#define ATA_C_F_ENAB_ACOUSTIC 0x42 /* enable acoustic management */
|
||||||
|
#define ATA_C_F_DIS_ACOUSTIC 0xc2 /* disable acoustic management */
|
||||||
|
#define ATA_C_F_AAM_CNT_MAX_PERF 0xfe /* maximum performance */
|
||||||
|
#define ATA_C_F_AAM_CNT_MAX_POWER_SAVE 0x80 /* min. power */
|
||||||
|
|
||||||
|
// New SMART Feature definitions
|
||||||
|
#ifndef READ_LOG_SECTOR
|
||||||
|
#define READ_LOG_SECTOR 0xD5
|
||||||
|
#define WRITE_LOG_SECTOR 0xD6
|
||||||
|
#define WRITE_THRESHOLDS 0xD7
|
||||||
|
#define AUTO_OFFLINE 0xDB
|
||||||
|
#endif // READ_LOG_SECTOR
|
||||||
|
|
||||||
//
|
//
|
||||||
// ATAPI interrupt reasons
|
// ATAPI interrupt reasons
|
||||||
//
|
//
|
||||||
|
@ -920,6 +941,7 @@ typedef struct _IDENTIFY_DATA {
|
||||||
union {
|
union {
|
||||||
USHORT Integrity; // 255
|
USHORT Integrity; // 255
|
||||||
struct {
|
struct {
|
||||||
|
#define ATA_ChecksumValid 0xA5
|
||||||
USHORT ChecksumValid:8;
|
USHORT ChecksumValid:8;
|
||||||
USHORT Checksum:8;
|
USHORT Checksum:8;
|
||||||
};
|
};
|
||||||
|
@ -1538,12 +1560,17 @@ ata_is_sata(
|
||||||
return (ident->SataCapabilities && ident->SataCapabilities != 0xffff);
|
return (ident->SataCapabilities && ident->SataCapabilities != 0xffff);
|
||||||
} // end ata_is_sata()
|
} // end ata_is_sata()
|
||||||
|
|
||||||
|
#define IDENT_MODE_MAX FALSE
|
||||||
|
#define IDENT_MODE_ACTIVE TRUE
|
||||||
|
|
||||||
__inline
|
__inline
|
||||||
LONG
|
LONG
|
||||||
ata_cur_mode_from_ident(
|
ata_cur_mode_from_ident(
|
||||||
PIDENTIFY_DATA ident
|
PIDENTIFY_DATA ident,
|
||||||
|
BOOLEAN Active
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
USHORT mode;
|
||||||
if(ata_is_sata(ident)) {
|
if(ata_is_sata(ident)) {
|
||||||
if(ident->SataCapabilities & ATA_SATA_GEN3) {
|
if(ident->SataCapabilities & ATA_SATA_GEN3) {
|
||||||
return ATA_SA600;
|
return ATA_SA600;
|
||||||
|
@ -1558,22 +1585,24 @@ ata_cur_mode_from_ident(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ident->UdmaModesValid) {
|
if (ident->UdmaModesValid) {
|
||||||
if (ident->UltraDMAActive & 0x40)
|
mode = Active ? ident->UltraDMAActive : ident->UltraDMASupport;
|
||||||
|
if (mode & 0x40)
|
||||||
return ATA_UDMA0+6;
|
return ATA_UDMA0+6;
|
||||||
if (ident->UltraDMAActive & 0x20)
|
if (mode & 0x20)
|
||||||
return ATA_UDMA0+5;
|
return ATA_UDMA0+5;
|
||||||
if (ident->UltraDMAActive & 0x10)
|
if (mode & 0x10)
|
||||||
return ATA_UDMA0+4;
|
return ATA_UDMA0+4;
|
||||||
if (ident->UltraDMAActive & 0x08)
|
if (mode & 0x08)
|
||||||
return ATA_UDMA0+3;
|
return ATA_UDMA0+3;
|
||||||
if (ident->UltraDMAActive & 0x04)
|
if (mode & 0x04)
|
||||||
return ATA_UDMA0+2;
|
return ATA_UDMA0+2;
|
||||||
if (ident->UltraDMAActive & 0x02)
|
if (mode & 0x02)
|
||||||
return ATA_UDMA0+1;
|
return ATA_UDMA0+1;
|
||||||
if (ident->UltraDMAActive & 0x01)
|
if (mode & 0x01)
|
||||||
return ATA_UDMA0+0;
|
return ATA_UDMA0+0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode = Active ? ident->MultiWordDMAActive : ident->MultiWordDMASupport;
|
||||||
if (ident->MultiWordDMAActive & 0x04)
|
if (ident->MultiWordDMAActive & 0x04)
|
||||||
return ATA_WDMA0+2;
|
return ATA_WDMA0+2;
|
||||||
if (ident->MultiWordDMAActive & 0x02)
|
if (ident->MultiWordDMAActive & 0x02)
|
||||||
|
@ -1581,6 +1610,7 @@ ata_cur_mode_from_ident(
|
||||||
if (ident->MultiWordDMAActive & 0x01)
|
if (ident->MultiWordDMAActive & 0x01)
|
||||||
return ATA_WDMA0+0;
|
return ATA_WDMA0+0;
|
||||||
|
|
||||||
|
mode = Active ? ident->SingleWordDMAActive : ident->SingleWordDMASupport;
|
||||||
if (ident->SingleWordDMAActive & 0x04)
|
if (ident->SingleWordDMAActive & 0x04)
|
||||||
return ATA_SDMA0+2;
|
return ATA_SDMA0+2;
|
||||||
if (ident->SingleWordDMAActive & 0x02)
|
if (ident->SingleWordDMAActive & 0x02)
|
||||||
|
@ -1589,13 +1619,15 @@ ata_cur_mode_from_ident(
|
||||||
return ATA_SDMA0+0;
|
return ATA_SDMA0+0;
|
||||||
|
|
||||||
if (ident->PioTimingsValid) {
|
if (ident->PioTimingsValid) {
|
||||||
if (ident->AdvancedPIOModes & AdvancedPIOModes_5)
|
mode = ident->AdvancedPIOModes;
|
||||||
|
if (mode & AdvancedPIOModes_5)
|
||||||
return ATA_PIO0+5;
|
return ATA_PIO0+5;
|
||||||
if (ident->AdvancedPIOModes & AdvancedPIOModes_4)
|
if (mode & AdvancedPIOModes_4)
|
||||||
return ATA_PIO0+4;
|
return ATA_PIO0+4;
|
||||||
if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
|
if (mode & AdvancedPIOModes_3)
|
||||||
return ATA_PIO0+3;
|
return ATA_PIO0+3;
|
||||||
}
|
}
|
||||||
|
mode = ident->PioCycleTimingMode;
|
||||||
if (ident->PioCycleTimingMode == 2)
|
if (ident->PioCycleTimingMode == 2)
|
||||||
return ATA_PIO0+2;
|
return ATA_PIO0+2;
|
||||||
if (ident->PioCycleTimingMode == 1)
|
if (ident->PioCycleTimingMode == 1)
|
||||||
|
|
|
@ -50,11 +50,12 @@ Revision History:
|
||||||
#ifndef __IDE_BUSMASTER_DEVICES_H__
|
#ifndef __IDE_BUSMASTER_DEVICES_H__
|
||||||
#define __IDE_BUSMASTER_DEVICES_H__
|
#define __IDE_BUSMASTER_DEVICES_H__
|
||||||
|
|
||||||
#ifdef USER_MODE
|
/*#ifdef USER_MODE
|
||||||
#define PVEN_STR PCSTR
|
#define PVEN_STR PCSTR
|
||||||
#else // USER_MODE
|
#else // USER_MODE
|
||||||
#define PVEN_STR PCHAR
|
#define PVEN_STR PCHAR
|
||||||
#endif // USER_MODE
|
#endif // USER_MODE*/
|
||||||
|
#define PVEN_STR PCSTR
|
||||||
|
|
||||||
typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||||
PVEN_STR VendorId;
|
PVEN_STR VendorId;
|
||||||
|
@ -76,9 +77,12 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||||
CHAR MasterDev;
|
CHAR MasterDev;
|
||||||
BOOLEAN Known;
|
BOOLEAN Known;
|
||||||
#ifndef USER_MODE
|
#ifndef USER_MODE
|
||||||
CHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary
|
UCHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary, 0x80 - PciIde claimed
|
||||||
BOOLEAN Isr2Enable;
|
BOOLEAN Isr2Enable;
|
||||||
|
union {
|
||||||
PDEVICE_OBJECT Isr2DevObj;
|
PDEVICE_OBJECT Isr2DevObj;
|
||||||
|
PDEVICE_OBJECT PciIdeDevObj;
|
||||||
|
};
|
||||||
KIRQL Isr2Irql;
|
KIRQL Isr2Irql;
|
||||||
KAFFINITY Isr2Affinity;
|
KAFFINITY Isr2Affinity;
|
||||||
ULONG Isr2Vector;
|
ULONG Isr2Vector;
|
||||||
|
@ -634,7 +638,8 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||||
#define ICH5 0x0200
|
#define ICH5 0x0200
|
||||||
#define I6CH 0x0400
|
#define I6CH 0x0400
|
||||||
#define I6CH2 0x0800
|
#define I6CH2 0x0800
|
||||||
#define I1CH 0x1000
|
//#define I1CH 0x1000 // obsolete
|
||||||
|
#define ICH7 0x1000
|
||||||
|
|
||||||
#define NV4OFF 0x0100
|
#define NV4OFF 0x0100
|
||||||
#define NVQ 0x0200
|
#define NVQ 0x0200
|
||||||
|
@ -717,7 +722,7 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
|
||||||
|
|
||||||
PCI_DEV_HW_SPEC_BM( 1230, 8086, 0x00, ATA_WDMA2, "Intel PIIX" , 0 ),
|
PCI_DEV_HW_SPEC_BM( 1230, 8086, 0x00, ATA_WDMA2, "Intel PIIX" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 7010, 8086, 0x00, ATA_WDMA2, "Intel PIIX3" , 0 ),
|
PCI_DEV_HW_SPEC_BM( 7010, 8086, 0x00, ATA_WDMA2, "Intel PIIX3" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 7111, 8086, 0x00, ATA_UDMA3, "Intel PIIX4" , 0 ),
|
PCI_DEV_HW_SPEC_BM( 7111, 8086, 0x00, ATA_UDMA2, "Intel PIIX3" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 7199, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ),
|
PCI_DEV_HW_SPEC_BM( 7199, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 84ca, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ),
|
PCI_DEV_HW_SPEC_BM( 84ca, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 7601, 8086, 0x00, ATA_UDMA2, "Intel ICH0" , 0 ),
|
PCI_DEV_HW_SPEC_BM( 7601, 8086, 0x00, ATA_UDMA2, "Intel ICH0" , 0 ),
|
||||||
|
@ -747,15 +752,15 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
|
||||||
PCI_DEV_HW_SPEC_BM( 2652, 8086, 0x00, ATA_SA150, "Intel ICH6" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2652, 8086, 0x00, ATA_SA150, "Intel ICH6" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2653, 8086, 0x00, ATA_SA150, "Intel ICH6M" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2653, 8086, 0x00, ATA_SA150, "Intel ICH6M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
|
|
||||||
PCI_DEV_HW_SPEC_BM( 27df, 8086, 0x00, ATA_UDMA5, "Intel ICH7" , I1CH ),
|
PCI_DEV_HW_SPEC_BM( 27df, 8086, 0x00, ATA_UDMA5, "Intel ICH7" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 27c0, 8086, 0x00, ATA_SA300, "Intel ICH7 S1" , UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 27c0, 8086, 0x00, ATA_SA300, "Intel ICH7 S1" , ICH7 | UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 27c1, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 27c1, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
PCI_DEV_HW_SPEC_BM( 27c3, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 27c3, 8086, 0x00, ATA_SA300, "Intel ICH7" , UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 27c4, 8086, 0x00, ATA_SA150, "Intel ICH7M R1" , UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 27c4, 8086, 0x00, ATA_SA150, "Intel ICH7M R1" , ICH7 | UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 27c5, 8086, 0x00, ATA_SA150, "Intel ICH7M" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 27c5, 8086, 0x00, ATA_SA150, "Intel ICH7M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
PCI_DEV_HW_SPEC_BM( 27c6, 8086, 0x00, ATA_SA150, "Intel ICH7M" , UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 27c6, 8086, 0x00, ATA_SA150, "Intel ICH7M" , UNIATA_SATA ),
|
||||||
|
|
||||||
PCI_DEV_HW_SPEC_BM( 269e, 8086, 0x00, ATA_UDMA5, "Intel 63XXESB2" , I1CH ),
|
PCI_DEV_HW_SPEC_BM( 269e, 8086, 0x00, ATA_UDMA5, "Intel 63XXESB2" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2680, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 2680, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2681, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2681, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2682, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2682, 8086, 0x00, ATA_SA300, "Intel 63XXESB2" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
|
@ -769,7 +774,7 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
|
||||||
PCI_DEV_HW_SPEC_BM( 2828, 8086, 0x00, ATA_SA300, "Intel ICH8M" , I6CH | UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 2828, 8086, 0x00, ATA_SA300, "Intel ICH8M" , I6CH | UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2829, 8086, 0x00, ATA_SA300, "Intel ICH8M" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2829, 8086, 0x00, ATA_SA300, "Intel ICH8M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
PCI_DEV_HW_SPEC_BM( 282a, 8086, 0x00, ATA_SA300, "Intel ICH8M" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 282a, 8086, 0x00, ATA_SA300, "Intel ICH8M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2850, 8086, 0x00, ATA_UDMA5, "Intel ICH8M" , I1CH ),
|
PCI_DEV_HW_SPEC_BM( 2850, 8086, 0x00, ATA_UDMA5, "Intel ICH8M" , 0 ),
|
||||||
|
|
||||||
PCI_DEV_HW_SPEC_BM( 2920, 8086, 0x00, ATA_SA300, "Intel ICH9" , I6CH | UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 2920, 8086, 0x00, ATA_SA300, "Intel ICH9" , I6CH | UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2926, 8086, 0x00, ATA_SA300, "Intel ICH9" , I6CH2 | UNIATA_SATA ),
|
PCI_DEV_HW_SPEC_BM( 2926, 8086, 0x00, ATA_SA300, "Intel ICH9" , I6CH2 | UNIATA_SATA ),
|
||||||
|
@ -842,7 +847,7 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
|
||||||
PCI_DEV_HW_SPEC_BM( 1e0f, 8086, 0x00, ATA_SA300, "Intel Panther Point" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 1e0f, 8086, 0x00, ATA_SA300, "Intel Panther Point" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
|
|
||||||
// PCI_DEV_HW_SPEC_BM( 3200, 8086, 0x00, ATA_SA150, "Intel 31244" , UNIATA_SATA ),
|
// PCI_DEV_HW_SPEC_BM( 3200, 8086, 0x00, ATA_SA150, "Intel 31244" , UNIATA_SATA ),
|
||||||
PCI_DEV_HW_SPEC_BM( 811a, 8086, 0x00, ATA_UDMA5, "Intel SCH" , I1CH ),
|
PCI_DEV_HW_SPEC_BM( 811a, 8086, 0x00, ATA_UDMA5, "Intel SCH" , 0 ),
|
||||||
PCI_DEV_HW_SPEC_BM( 2323, 8086, 0x00, ATA_SA300, "Intel DH98xxCC" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2323, 8086, 0x00, ATA_SA300, "Intel DH98xxCC" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
|
|
||||||
PCI_DEV_HW_SPEC_BM( 2360, 197b, 0x00, ATA_SA300, "JMB360" , UNIATA_SATA | UNIATA_AHCI ),
|
PCI_DEV_HW_SPEC_BM( 2360, 197b, 0x00, ATA_SA300, "JMB360" , UNIATA_SATA | UNIATA_AHCI ),
|
||||||
|
|
|
@ -562,9 +562,9 @@ typedef struct _IDE_AHCI_PORT_REGISTERS {
|
||||||
ULONG Reg; // signature
|
ULONG Reg; // signature
|
||||||
struct {
|
struct {
|
||||||
UCHAR SectorCount;
|
UCHAR SectorCount;
|
||||||
UCHAR LbaLow;
|
UCHAR LbaLow; // IDX_IO1_i_BlockNumber
|
||||||
UCHAR LbaMid;
|
UCHAR LbaMid; // IDX_IO1_i_CylinderLow
|
||||||
UCHAR LbaHigh;
|
UCHAR LbaHigh; // IDX_IO1_i_CylinderHigh
|
||||||
};
|
};
|
||||||
} SIG; // 0x100 + 0x80*c + 0x0024
|
} SIG; // 0x100 + 0x80*c + 0x0024
|
||||||
union {
|
union {
|
||||||
|
@ -1060,6 +1060,7 @@ typedef struct _HW_CHANNEL {
|
||||||
#define CTRFLAGS_DSC_BSY 0x0080
|
#define CTRFLAGS_DSC_BSY 0x0080
|
||||||
#define CTRFLAGS_NO_SLAVE 0x0100
|
#define CTRFLAGS_NO_SLAVE 0x0100
|
||||||
//#define CTRFLAGS_PATA 0x0200
|
//#define CTRFLAGS_PATA 0x0200
|
||||||
|
//#define CTRFLAGS_NOT_PRESENT 0x0200
|
||||||
#define CTRFLAGS_AHCI_PM 0x0400
|
#define CTRFLAGS_AHCI_PM 0x0400
|
||||||
#define CTRFLAGS_AHCI_PM2 0x0800
|
#define CTRFLAGS_AHCI_PM2 0x0800
|
||||||
|
|
||||||
|
@ -1086,7 +1087,7 @@ typedef struct _HW_LU_EXTENSION {
|
||||||
BOOLEAN DWordIO; // Indicates use of 32-bit PIO
|
BOOLEAN DWordIO; // Indicates use of 32-bit PIO
|
||||||
UCHAR ReturningMediaStatus;
|
UCHAR ReturningMediaStatus;
|
||||||
UCHAR MaximumBlockXfer;
|
UCHAR MaximumBlockXfer;
|
||||||
UCHAR Padding0[1]; // padding
|
UCHAR PowerState;
|
||||||
|
|
||||||
UCHAR TransferMode; // current transfer mode
|
UCHAR TransferMode; // current transfer mode
|
||||||
UCHAR LimitedTransferMode; // user-defined or IDE cable limitation
|
UCHAR LimitedTransferMode; // user-defined or IDE cable limitation
|
||||||
|
@ -1117,8 +1118,10 @@ typedef struct _HW_LU_EXTENSION {
|
||||||
BOOLEAN opt_ReadCacheEnable;
|
BOOLEAN opt_ReadCacheEnable;
|
||||||
BOOLEAN opt_WriteCacheEnable;
|
BOOLEAN opt_WriteCacheEnable;
|
||||||
UCHAR opt_ReadOnly;
|
UCHAR opt_ReadOnly;
|
||||||
// padding
|
UCHAR opt_AdvPowerMode;
|
||||||
BOOLEAN opt_reserved[1];
|
UCHAR opt_AcousticMode;
|
||||||
|
UCHAR opt_StandbyTimer;
|
||||||
|
UCHAR opt_Padding[2]; // padding
|
||||||
|
|
||||||
struct _SBadBlockListItem* bbListDescr;
|
struct _SBadBlockListItem* bbListDescr;
|
||||||
struct _SBadBlockRange* arrBadBlocks;
|
struct _SBadBlockRange* arrBadBlocks;
|
||||||
|
@ -1216,6 +1219,9 @@ typedef struct _HW_DEVICE_EXTENSION {
|
||||||
BOOLEAN MasterDev;
|
BOOLEAN MasterDev;
|
||||||
BOOLEAN Host64;
|
BOOLEAN Host64;
|
||||||
BOOLEAN DWordIO; // Indicates use of 32-bit PIO
|
BOOLEAN DWordIO; // Indicates use of 32-bit PIO
|
||||||
|
/* // Indicates, that HW Initialized is already called for this controller
|
||||||
|
// 0 bit for Primary, 1 - for Secondary. Is used to manage AltInit under w2k+
|
||||||
|
UCHAR Initialized; */
|
||||||
UCHAR Reserved1[2];
|
UCHAR Reserved1[2];
|
||||||
|
|
||||||
LONG ReCheckIntr;
|
LONG ReCheckIntr;
|
||||||
|
@ -1238,6 +1244,7 @@ typedef struct _HW_DEVICE_EXTENSION {
|
||||||
IORES BaseIoAHCI_0;
|
IORES BaseIoAHCI_0;
|
||||||
//PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
|
//PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
|
||||||
ULONG AHCI_CAP;
|
ULONG AHCI_CAP;
|
||||||
|
ULONG AHCI_PI;
|
||||||
PATA_REQ AhciInternalAtaReq0;
|
PATA_REQ AhciInternalAtaReq0;
|
||||||
PSCSI_REQUEST_BLOCK AhciInternalSrb0;
|
PSCSI_REQUEST_BLOCK AhciInternalSrb0;
|
||||||
|
|
||||||
|
@ -1260,6 +1267,9 @@ typedef struct _ISR2_DEVICE_EXTENSION {
|
||||||
ULONG DevIndex;
|
ULONG DevIndex;
|
||||||
} ISR2_DEVICE_EXTENSION, *PISR2_DEVICE_EXTENSION;
|
} ISR2_DEVICE_EXTENSION, *PISR2_DEVICE_EXTENSION;
|
||||||
|
|
||||||
|
typedef ISR2_DEVICE_EXTENSION PCIIDE_DEVICE_EXTENSION;
|
||||||
|
typedef PISR2_DEVICE_EXTENSION PPCIIDE_DEVICE_EXTENSION;
|
||||||
|
|
||||||
#define HBAFLAGS_DMA_DISABLED 0x01
|
#define HBAFLAGS_DMA_DISABLED 0x01
|
||||||
#define HBAFLAGS_DMA_DISABLED_LBA48 0x02
|
#define HBAFLAGS_DMA_DISABLED_LBA48 0x02
|
||||||
|
|
||||||
|
@ -1268,6 +1278,7 @@ extern PBUSMASTER_CONTROLLER_INFORMATION BMList;
|
||||||
extern ULONG BMListLen;
|
extern ULONG BMListLen;
|
||||||
extern ULONG IsaCount;
|
extern ULONG IsaCount;
|
||||||
extern ULONG MCACount;
|
extern ULONG MCACount;
|
||||||
|
extern UNICODE_STRING SavedRegPath;
|
||||||
|
|
||||||
//extern const CHAR retry_Wdma[MAX_RETRIES+1];
|
//extern const CHAR retry_Wdma[MAX_RETRIES+1];
|
||||||
//extern const CHAR retry_Udma[MAX_RETRIES+1];
|
//extern const CHAR retry_Udma[MAX_RETRIES+1];
|
||||||
|
@ -1322,14 +1333,10 @@ UniataFindBusMasterController(
|
||||||
OUT PBOOLEAN Again
|
OUT PBOOLEAN Again
|
||||||
);
|
);
|
||||||
|
|
||||||
extern ULONG NTAPI
|
extern NTSTATUS
|
||||||
UniataFindFakeBusMasterController(
|
NTAPI
|
||||||
IN PVOID HwDeviceExtension,
|
UniataClaimLegacyPCIIDE(
|
||||||
IN PVOID Context,
|
ULONG i
|
||||||
IN PVOID BusInformation,
|
|
||||||
IN PCHAR ArgumentString,
|
|
||||||
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
|
||||||
OUT PBOOLEAN Again
|
|
||||||
);
|
);
|
||||||
|
|
||||||
extern NTSTATUS
|
extern NTSTATUS
|
||||||
|
@ -1508,6 +1515,14 @@ AtapiGetIoRange(
|
||||||
IN ULONG length //range id
|
IN ULONG length //range id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
extern USHORT
|
||||||
|
NTAPI
|
||||||
|
UniataEnableIoPCI(
|
||||||
|
IN ULONG busNumber,
|
||||||
|
IN ULONG slotNumber,
|
||||||
|
IN OUT PPCI_COMMON_CONFIG pciData
|
||||||
|
);
|
||||||
|
|
||||||
/****************** 1 *****************/
|
/****************** 1 *****************/
|
||||||
#define GetPciConfig1(offs, op) { \
|
#define GetPciConfig1(offs, op) { \
|
||||||
ScsiPortGetBusDataByOffset(HwDeviceExtension, \
|
ScsiPortGetBusDataByOffset(HwDeviceExtension, \
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -944,19 +944,19 @@ AtapiDmaInit(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit transfer mode (controller limitation)
|
// Limit transfer mode (controller limitation)
|
||||||
if((LONG)deviceExtension->MaxTransferMode >= ATA_UDMA) {
|
if((LONG)chan->MaxTransferMode >= ATA_UDMA) {
|
||||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: deviceExtension->MaxTransferMode >= ATA_UDMA\n"));
|
KdPrint2((PRINT_PREFIX "AtapiDmaInit: chan->MaxTransferMode >= ATA_UDMA\n"));
|
||||||
udmamode = min( udmamode, (CHAR)(deviceExtension->MaxTransferMode - ATA_UDMA));
|
udmamode = min( udmamode, (CHAR)(chan->MaxTransferMode - ATA_UDMA));
|
||||||
} else
|
} else
|
||||||
if((LONG)deviceExtension->MaxTransferMode >= ATA_WDMA) {
|
if((LONG)chan->MaxTransferMode >= ATA_WDMA) {
|
||||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: deviceExtension->MaxTransferMode >= ATA_WDMA\n"));
|
KdPrint2((PRINT_PREFIX "AtapiDmaInit: chan->MaxTransferMode >= ATA_WDMA\n"));
|
||||||
udmamode = -1;
|
udmamode = -1;
|
||||||
wdmamode = min( wdmamode, (CHAR)(deviceExtension->MaxTransferMode - ATA_WDMA));
|
wdmamode = min( wdmamode, (CHAR)(chan->MaxTransferMode - ATA_WDMA));
|
||||||
} else
|
} else
|
||||||
if((LONG)deviceExtension->MaxTransferMode >= ATA_PIO0) {
|
if((LONG)chan->MaxTransferMode >= ATA_PIO0) {
|
||||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: NO DMA\n"));
|
KdPrint2((PRINT_PREFIX "AtapiDmaInit: NO DMA\n"));
|
||||||
wdmamode = udmamode = -1;
|
wdmamode = udmamode = -1;
|
||||||
apiomode = min( apiomode, (CHAR)(deviceExtension->MaxTransferMode - ATA_PIO0));
|
apiomode = min( apiomode, (CHAR)(chan->MaxTransferMode - ATA_PIO0));
|
||||||
} else {
|
} else {
|
||||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: PIO0\n"));
|
KdPrint2((PRINT_PREFIX "AtapiDmaInit: PIO0\n"));
|
||||||
wdmamode = udmamode = -1;
|
wdmamode = udmamode = -1;
|
||||||
|
@ -1003,14 +1003,16 @@ AtapiDmaInit(
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
|
if(UniataIsSATARangeAvailable(deviceExtension, lChannel) ||
|
||||||
|
(ChipFlags & UNIATA_AHCI) || (chan->MaxTransferMode >= ATA_SA150)
|
||||||
|
) {
|
||||||
//if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
|
//if(ChipFlags & (UNIATA_SATA | UNIATA_AHCI)) {
|
||||||
/****************/
|
/****************/
|
||||||
/* SATA Generic */
|
/* SATA Generic */
|
||||||
/****************/
|
/****************/
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "SATA Generic\n"));
|
KdPrint2((PRINT_PREFIX "SATA Generic\n"));
|
||||||
if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || chan->MaxTransferMode >= ATA_SA150) {
|
if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || (chan->MaxTransferMode >= ATA_SA150)) {
|
||||||
/* some drives report UDMA6, some UDMA5 */
|
/* some drives report UDMA6, some UDMA5 */
|
||||||
/* ATAPI may not have SataCapabilities set in IDENTIFY DATA */
|
/* ATAPI may not have SataCapabilities set in IDENTIFY DATA */
|
||||||
if(ata_is_sata(&(LunExt->IdentifyData))) {
|
if(ata_is_sata(&(LunExt->IdentifyData))) {
|
||||||
|
@ -1024,7 +1026,7 @@ AtapiDmaInit(
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
KdPrint2((PRINT_PREFIX "SATA -> PATA adapter ?\n"));
|
KdPrint2((PRINT_PREFIX "SATA -> PATA adapter ?\n"));
|
||||||
if (udmamode > 2 && (!LunExt->IdentifyData.HwResCableId || (LunExt->IdentifyData.HwResValid != IDENTIFY_CABLE_ID_VALID) )) {
|
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"));
|
KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n"));
|
||||||
udmamode = 2;
|
udmamode = 2;
|
||||||
apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0));
|
apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0));
|
||||||
|
@ -1054,7 +1056,7 @@ AtapiDmaInit(
|
||||||
goto try_generic_dma;
|
goto try_generic_dma;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(udmamode > 2 && (!LunExt->IdentifyData.HwResCableId || (LunExt->IdentifyData.HwResValid != IDENTIFY_CABLE_ID_VALID)) ) {
|
if(udmamode > 2 && (!LunExt->IdentifyData.HwResCableId && (LunExt->IdentifyData.HwResValid == IDENTIFY_CABLE_ID_VALID)) ) {
|
||||||
if(ata_is_sata(&(LunExt->IdentifyData))) {
|
if(ata_is_sata(&(LunExt->IdentifyData))) {
|
||||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: SATA beyond adapter or Controller compat mode\n"));
|
KdPrint2((PRINT_PREFIX "AtapiDmaInit: SATA beyond adapter or Controller compat mode\n"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1384,6 +1386,7 @@ set_new_acard:
|
||||||
UCHAR new44 = 0;
|
UCHAR new44 = 0;
|
||||||
UCHAR intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
|
UCHAR intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
|
||||||
0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
|
0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
|
||||||
|
UCHAR intel_utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
|
||||||
|
|
||||||
if(deviceExtension->DevID == ATA_I82371FB) {
|
if(deviceExtension->DevID == ATA_I82371FB) {
|
||||||
if (wdmamode >= 2 && apiomode >= 4) {
|
if (wdmamode >= 2 && apiomode >= 4) {
|
||||||
|
@ -1466,17 +1469,24 @@ set_new_acard:
|
||||||
for(i=udmamode; i>=0; i--) {
|
for(i=udmamode; i>=0; i--) {
|
||||||
if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
|
if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
|
||||||
|
|
||||||
/* Set UDMA reference clock (33/66/133MHz). */
|
/* Set UDMA reference clock (33 MHz or more). */
|
||||||
SetPciConfig1(0x48, reg48 | (0x0001 << dev));
|
SetPciConfig1(0x48, reg48 | (0x0001 << dev));
|
||||||
if(!(ChipFlags & ICH4_FIX)) {
|
if(!(ChipFlags & ICH4_FIX)) {
|
||||||
SetPciConfig2(0x4a, (reg4a & ~(0x3 << (dev<<2))) |
|
if(deviceExtension->MaxTransferMode == ATA_UDMA3) {
|
||||||
(0x01 + !(i & 0x01)) );
|
// Special case (undocumented overclock !) for PIIX4e
|
||||||
|
SetPciConfig2(0x4a, (reg4a | (0x03 << (dev<<2)) ) );
|
||||||
|
} else {
|
||||||
|
SetPciConfig2(0x4a, (reg4a & ~(0x03 << (dev<<2))) |
|
||||||
|
(((USHORT)(intel_utimings[i])) << (dev<<2) ) );
|
||||||
}
|
}
|
||||||
if(i >= 2) {
|
}
|
||||||
|
/* Set UDMA reference clock (66 MHz or more). */
|
||||||
|
if(i > 2) {
|
||||||
reg54 |= (0x1 << dev);
|
reg54 |= (0x1 << dev);
|
||||||
} else {
|
} else {
|
||||||
reg54 &= ~(0x1 << dev);
|
reg54 &= ~(0x1 << dev);
|
||||||
}
|
}
|
||||||
|
/* Set UDMA reference clock (133 MHz). */
|
||||||
if(i >= 5) {
|
if(i >= 5) {
|
||||||
reg54 |= (0x1000 << dev);
|
reg54 |= (0x1000 << dev);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -178,6 +178,7 @@ UniataChipDetectChannels(
|
||||||
KdPrint2((PRINT_PREFIX "New ITE PATA 1 chan\n"));
|
KdPrint2((PRINT_PREFIX "New ITE PATA 1 chan\n"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
case ATA_INTEL_ID:
|
case ATA_INTEL_ID:
|
||||||
/* New Intel PATA controllers */
|
/* New Intel PATA controllers */
|
||||||
if(g_opt_VirtualMachine != VM_VBOX &&
|
if(g_opt_VirtualMachine != VM_VBOX &&
|
||||||
|
@ -193,6 +194,7 @@ UniataChipDetectChannels(
|
||||||
KdPrint2((PRINT_PREFIX "New Intel PATA 1 chan\n"));
|
KdPrint2((PRINT_PREFIX "New Intel PATA 1 chan\n"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif // this code is removed from newer FreeBSD
|
||||||
case ATA_JMICRON_ID:
|
case ATA_JMICRON_ID:
|
||||||
/* New JMicron PATA controllers */
|
/* New JMicron PATA controllers */
|
||||||
if(deviceExtension->DevID == ATA_JMB361 ||
|
if(deviceExtension->DevID == ATA_JMB361 ||
|
||||||
|
@ -1418,6 +1420,11 @@ generic_cable80(
|
||||||
ULONG slotNumber = deviceExtension->slotNumber;
|
ULONG slotNumber = deviceExtension->slotNumber;
|
||||||
ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
|
ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
|
||||||
|
|
||||||
|
if(deviceExtension->MaxTransferMode <= ATA_UDMA2) {
|
||||||
|
KdPrint2((PRINT_PREFIX "generic_cable80(%d, %#x, %d) <= UDMA2\n", channel, pci_reg, bit_offs));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
//ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
|
//ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
|
||||||
PHW_CHANNEL chan;
|
PHW_CHANNEL chan;
|
||||||
ULONG c; // logical channel (for Compatible Mode controllers)
|
ULONG c; // logical channel (for Compatible Mode controllers)
|
||||||
|
@ -1468,6 +1475,27 @@ UniAtaReadLunConfig(
|
||||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"PreferedTransferMode", 0xffffffff);
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"PreferedTransferMode", 0xffffffff);
|
||||||
LunExt->opt_PreferedTransferMode = tmp32;
|
LunExt->opt_PreferedTransferMode = tmp32;
|
||||||
|
|
||||||
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"AdvancedPowerMode", ATA_C_F_APM_CNT_MIN_NO_STANDBY);
|
||||||
|
if(tmp32 > 0xfe) {
|
||||||
|
tmp32 = 0xfe; // max. performance
|
||||||
|
}
|
||||||
|
LunExt->opt_AdvPowerMode = (UCHAR)tmp32;
|
||||||
|
|
||||||
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"AcousticMgmt", ATA_C_F_AAM_CNT_MAX_POWER_SAVE);
|
||||||
|
if(tmp32 > 0xfe) {
|
||||||
|
tmp32 = 0xfe; // max. performance
|
||||||
|
} else
|
||||||
|
if(tmp32 < 0x80) {
|
||||||
|
tmp32 = 0x0; // disable feature
|
||||||
|
}
|
||||||
|
LunExt->opt_AcousticMode = (UCHAR)tmp32;
|
||||||
|
|
||||||
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"StandbyTimer", 0);
|
||||||
|
if(tmp32 == 0xfe) {
|
||||||
|
tmp32 = 0xff;
|
||||||
|
}
|
||||||
|
LunExt->opt_StandbyTimer = (UCHAR)tmp32;
|
||||||
|
|
||||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadOnly", 0);
|
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"ReadOnly", 0);
|
||||||
if(tmp32 <= 2) {
|
if(tmp32 <= 2) {
|
||||||
LunExt->opt_ReadOnly = (UCHAR)tmp32;
|
LunExt->opt_ReadOnly = (UCHAR)tmp32;
|
||||||
|
@ -1623,6 +1651,7 @@ AtapiChipInit(
|
||||||
ULONG tmp32;
|
ULONG tmp32;
|
||||||
ULONG c; // logical channel (for Compatible Mode controllers)
|
ULONG c; // logical channel (for Compatible Mode controllers)
|
||||||
BOOLEAN CheckCable = FALSE;
|
BOOLEAN CheckCable = FALSE;
|
||||||
|
BOOLEAN GlobalInit = FALSE;
|
||||||
//ULONG BaseIoAddress;
|
//ULONG BaseIoAddress;
|
||||||
|
|
||||||
switch(channel) {
|
switch(channel) {
|
||||||
|
@ -1631,6 +1660,7 @@ AtapiChipInit(
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case CHAN_NOT_SPECIFIED:
|
case CHAN_NOT_SPECIFIED:
|
||||||
c = CHAN_NOT_SPECIFIED;
|
c = CHAN_NOT_SPECIFIED;
|
||||||
|
GlobalInit = TRUE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
|
//c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
|
||||||
|
@ -1669,6 +1699,27 @@ AtapiChipInit(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((WinVer_Id() > WinVer_NT) &&
|
||||||
|
GlobalInit &&
|
||||||
|
deviceExtension->MasterDev) {
|
||||||
|
PCI_COMMON_CONFIG pciData;
|
||||||
|
ULONG busDataRead;
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX " re-enable IO resources of MasterDev\n" ));
|
||||||
|
|
||||||
|
busDataRead = HalGetBusData
|
||||||
|
//ScsiPortGetBusData
|
||||||
|
(
|
||||||
|
//HwDeviceExtension,
|
||||||
|
PCIConfiguration, SystemIoBusNumber, slotNumber,
|
||||||
|
&pciData, PCI_COMMON_HDR_LENGTH);
|
||||||
|
if(busDataRead == PCI_COMMON_HDR_LENGTH) {
|
||||||
|
UniataEnableIoPCI(SystemIoBusNumber, slotNumber, &pciData);
|
||||||
|
} else {
|
||||||
|
KdPrint2((PRINT_PREFIX " re-enable IO resources of MasterDev FAILED\n" ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch(VendorID) {
|
switch(VendorID) {
|
||||||
// case ATA_ACARD_ID:
|
// case ATA_ACARD_ID:
|
||||||
// break;
|
// break;
|
||||||
|
@ -1778,8 +1829,16 @@ AtapiChipInit(
|
||||||
KdPrint2((PRINT_PREFIX "Base init\n"));
|
KdPrint2((PRINT_PREFIX "Base init\n"));
|
||||||
/* force all ports active "the legacy way" */
|
/* force all ports active "the legacy way" */
|
||||||
ChangePciConfig2(0x92, (a | 0x0f));
|
ChangePciConfig2(0x92, (a | 0x0f));
|
||||||
|
|
||||||
|
if(deviceExtension->BaseIoAddressSATA_0.Addr && (ChipFlags & ICH7)) {
|
||||||
|
/* Set SCRAE bit to enable registers access. */
|
||||||
|
ChangePciConfig4(0x94, (a | (1 << 9)));
|
||||||
|
/* Set Ports Implemented register bits. */
|
||||||
|
AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x0c,
|
||||||
|
AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x0c) | 0xff);
|
||||||
|
}
|
||||||
/* enable PCI interrupt */
|
/* enable PCI interrupt */
|
||||||
ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
|
ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -1867,7 +1926,7 @@ AtapiChipInit(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(deviceExtension->MaxTransferMode < ATA_UDMA2)
|
if(deviceExtension->MaxTransferMode <= ATA_UDMA2)
|
||||||
break;
|
break;
|
||||||
// check 80-pin cable
|
// check 80-pin cable
|
||||||
if(c == CHAN_NOT_SPECIFIED) {
|
if(c == CHAN_NOT_SPECIFIED) {
|
||||||
|
@ -1875,7 +1934,12 @@ AtapiChipInit(
|
||||||
} else {
|
} else {
|
||||||
chan = &deviceExtension->chan[c];
|
chan = &deviceExtension->chan[c];
|
||||||
GetPciConfig2(0x54, reg54);
|
GetPciConfig2(0x54, reg54);
|
||||||
if( ((reg54 >> (channel*2)) & 30) != 30) {
|
KdPrint2((PRINT_PREFIX " intel 80-pin check (reg54=%x)\n", reg54));
|
||||||
|
if(reg54 == 0x0000 || reg54 == 0xffff) {
|
||||||
|
KdPrint2((PRINT_PREFIX " check failed (not supported)\n"));
|
||||||
|
} else
|
||||||
|
if( ((reg54 >> (channel*2)) & 30) == 0) {
|
||||||
|
KdPrint2((PRINT_PREFIX " intel 40-pin\n"));
|
||||||
chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
|
chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2179,7 +2243,7 @@ AtapiChipInit(
|
||||||
// no init for SATA
|
// no init for SATA
|
||||||
if(ChipFlags & (UNIATA_SATA | VIASATA)) {
|
if(ChipFlags & (UNIATA_SATA | VIASATA)) {
|
||||||
/* enable PCI interrupt */
|
/* enable PCI interrupt */
|
||||||
ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
|
ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vt6420/1 has problems talking to some drives. The following
|
* vt6420/1 has problems talking to some drives. The following
|
||||||
|
@ -2238,6 +2302,8 @@ AtapiChipInit(
|
||||||
// no init for SATA
|
// no init for SATA
|
||||||
if(ChipFlags & (UNIATA_SATA | VIASATA)) {
|
if(ChipFlags & (UNIATA_SATA | VIASATA)) {
|
||||||
if((ChipFlags & VIABAR) && (c >= 2)) {
|
if((ChipFlags & VIABAR) && (c >= 2)) {
|
||||||
|
// this is PATA channel
|
||||||
|
chan->MaxTransferMode = ATA_UDMA5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
|
UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
|
||||||
|
|
|
@ -83,6 +83,50 @@ AtapiDoNothing(VOID)
|
||||||
|
|
||||||
#endif //UNIATA_CORE
|
#endif //UNIATA_CORE
|
||||||
|
|
||||||
|
USHORT
|
||||||
|
NTAPI
|
||||||
|
UniataEnableIoPCI(
|
||||||
|
IN ULONG busNumber,
|
||||||
|
IN ULONG slotNumber,
|
||||||
|
IN OUT PPCI_COMMON_CONFIG pciData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
ULONG busDataRead;
|
||||||
|
|
||||||
|
// Enable Busmastering, IO-space and Mem-space
|
||||||
|
KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n"));
|
||||||
|
KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData->Command));
|
||||||
|
for(i=0; i<3; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case 0:
|
||||||
|
KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n"));
|
||||||
|
pciData->Command |= PCI_ENABLE_IO_SPACE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n"));
|
||||||
|
pciData->Command |= PCI_ENABLE_MEMORY_SPACE;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n"));
|
||||||
|
pciData->Command |= PCI_ENABLE_BUS_MASTER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
HalSetBusDataByOffset( PCIConfiguration, busNumber, slotNumber,
|
||||||
|
&(pciData->Command),
|
||||||
|
offsetof(PCI_COMMON_CONFIG, Command),
|
||||||
|
sizeof(pciData->Command));
|
||||||
|
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData->u.type0.InterruptLine));
|
||||||
|
|
||||||
|
// reread config space
|
||||||
|
busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotNumber,
|
||||||
|
pciData, PCI_COMMON_HDR_LENGTH);
|
||||||
|
KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData->Command));
|
||||||
|
}
|
||||||
|
KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData->Command));
|
||||||
|
return pciData->Command;
|
||||||
|
} // end UniataEnableIoPCI()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get PCI address by ConfigInfo and RID
|
Get PCI address by ConfigInfo and RID
|
||||||
*/
|
*/
|
||||||
|
@ -329,7 +373,6 @@ UniataEnumBusMasterController__(
|
||||||
SubVendorID = pciData.u.type0.SubVendorID;
|
SubVendorID = pciData.u.type0.SubVendorID;
|
||||||
SubSystemID = pciData.u.type0.SubSystemID;
|
SubSystemID = pciData.u.type0.SubSystemID;
|
||||||
|
|
||||||
|
|
||||||
//KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
//KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
||||||
|
|
||||||
// check for (g_opt_VirtualMachine == VM_AUTO) is performed inside each
|
// check for (g_opt_VirtualMachine == VM_AUTO) is performed inside each
|
||||||
|
@ -367,6 +410,14 @@ UniataEnumBusMasterController__(
|
||||||
found = FALSE;
|
found = FALSE;
|
||||||
known = FALSE;
|
known = FALSE;
|
||||||
|
|
||||||
|
if(pciData.u.type0.InterruptPin == 14 ||
|
||||||
|
pciData.u.type0.InterruptPin == 15 ||
|
||||||
|
pciData.u.type0.InterruptLine == 14 ||
|
||||||
|
pciData.u.type0.InterruptLine == 15) {
|
||||||
|
KdPrint2((PRINT_PREFIX "(!) InterruptPin = %#x\n", pciData.u.type0.InterruptPin));
|
||||||
|
KdPrint2((PRINT_PREFIX "(!) InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
||||||
|
}
|
||||||
|
|
||||||
if(deviceExtension) {
|
if(deviceExtension) {
|
||||||
deviceExtension->slotNumber = slotData.u.AsULONG;
|
deviceExtension->slotNumber = slotData.u.AsULONG;
|
||||||
deviceExtension->SystemIoBusNumber = busNumber;
|
deviceExtension->SystemIoBusNumber = busNumber;
|
||||||
|
@ -426,36 +477,7 @@ UniataEnumBusMasterController__(
|
||||||
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
||||||
|
|
||||||
if(!pass && known) {
|
if(!pass && known) {
|
||||||
// Enable Busmastering, IO-space and Mem-space
|
UniataEnableIoPCI(busNumber, slotData.u.AsULONG, &pciData);
|
||||||
KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n"));
|
|
||||||
KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData.Command));
|
|
||||||
for(i=0; i<3; i++) {
|
|
||||||
switch(i) {
|
|
||||||
case 0:
|
|
||||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n"));
|
|
||||||
pciData.Command |= PCI_ENABLE_IO_SPACE;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n"));
|
|
||||||
pciData.Command |= PCI_ENABLE_MEMORY_SPACE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n"));
|
|
||||||
pciData.Command |= PCI_ENABLE_BUS_MASTER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HalSetBusDataByOffset( PCIConfiguration, busNumber, slotData.u.AsULONG,
|
|
||||||
&(pciData.Command),
|
|
||||||
offsetof(PCI_COMMON_CONFIG, Command),
|
|
||||||
sizeof(pciData.Command));
|
|
||||||
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
|
||||||
|
|
||||||
// reread config space
|
|
||||||
busDataRead = HalGetBusData(PCIConfiguration, busNumber, slotData.u.AsULONG,
|
|
||||||
&pciData, PCI_COMMON_HDR_LENGTH);
|
|
||||||
KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData.Command));
|
|
||||||
}
|
|
||||||
KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData.Command));
|
|
||||||
}
|
}
|
||||||
// validate Mem/Io ranges
|
// validate Mem/Io ranges
|
||||||
no_ranges = TRUE;
|
no_ranges = TRUE;
|
||||||
|
@ -1175,37 +1197,7 @@ UniataFindBusMasterController(
|
||||||
deviceExtension->BusMaster = DMA_MODE_NONE;
|
deviceExtension->BusMaster = DMA_MODE_NONE;
|
||||||
|
|
||||||
if(WinVer_WDM_Model && !deviceExtension->UnknownDev) {
|
if(WinVer_WDM_Model && !deviceExtension->UnknownDev) {
|
||||||
ULONG i;
|
UniataEnableIoPCI(ConfigInfo->SystemIoBusNumber, slotData.u.AsULONG, &pciData);
|
||||||
// Enable Busmastering, IO-space and Mem-space
|
|
||||||
KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n"));
|
|
||||||
KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData.Command));
|
|
||||||
for(i=0; i<3; i++) {
|
|
||||||
switch(i) {
|
|
||||||
case 0:
|
|
||||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n"));
|
|
||||||
pciData.Command |= PCI_ENABLE_IO_SPACE;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n"));
|
|
||||||
pciData.Command |= PCI_ENABLE_MEMORY_SPACE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n"));
|
|
||||||
pciData.Command |= PCI_ENABLE_BUS_MASTER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HalSetBusDataByOffset( PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG,
|
|
||||||
&(pciData.Command),
|
|
||||||
offsetof(PCI_COMMON_CONFIG, Command),
|
|
||||||
sizeof(pciData.Command));
|
|
||||||
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
|
||||||
|
|
||||||
// reread config space
|
|
||||||
busDataRead = HalGetBusData(PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG,
|
|
||||||
&pciData, PCI_COMMON_HDR_LENGTH);
|
|
||||||
KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData.Command));
|
|
||||||
}
|
|
||||||
KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData.Command));
|
|
||||||
}
|
}
|
||||||
// validate Mem/Io ranges
|
// validate Mem/Io ranges
|
||||||
//no_ranges = TRUE;
|
//no_ranges = TRUE;
|
||||||
|
@ -1364,6 +1356,7 @@ UniataFindBusMasterController(
|
||||||
KdPrint2((PRINT_PREFIX "!MasterDev\n"));
|
KdPrint2((PRINT_PREFIX "!MasterDev\n"));
|
||||||
ConfigInfo->SlotNumber = slotNumber;
|
ConfigInfo->SlotNumber = slotNumber;
|
||||||
ConfigInfo->SystemIoBusNumber = SystemIoBusNumber;
|
ConfigInfo->SystemIoBusNumber = SystemIoBusNumber;
|
||||||
|
ConfigInfo->InterruptMode = LevelSensitive;
|
||||||
|
|
||||||
/* primary and secondary channels share the same interrupt */
|
/* primary and secondary channels share the same interrupt */
|
||||||
if(!ConfigInfo->BusInterruptVector ||
|
if(!ConfigInfo->BusInterruptVector ||
|
||||||
|
@ -1394,8 +1387,13 @@ UniataFindBusMasterController(
|
||||||
}
|
}
|
||||||
if((WinVer_Id() > WinVer_2k) ||
|
if((WinVer_Id() > WinVer_2k) ||
|
||||||
(ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
|
(ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
|
||||||
KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k\n"));
|
KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k: 64bit %d\n",
|
||||||
_ConfigInfo->w2k.Dma64BitAddresses = 0;
|
deviceExtension->Host64));
|
||||||
|
#ifdef USE_OWN_DMA
|
||||||
|
// We need not set Dma64BitAddresses since we perform address translation manually.
|
||||||
|
#else
|
||||||
|
_ConfigInfo->w2k.Dma64BitAddresses = deviceExtension->Host64;
|
||||||
|
#endif //USE_OWN_DMA
|
||||||
_ConfigInfo->w2k.ResetTargetSupported = TRUE;
|
_ConfigInfo->w2k.ResetTargetSupported = TRUE;
|
||||||
_ConfigInfo->w2k.MaximumNumberOfLogicalUnits = (UCHAR)deviceExtension->NumberLuns;
|
_ConfigInfo->w2k.MaximumNumberOfLogicalUnits = (UCHAR)deviceExtension->NumberLuns;
|
||||||
}
|
}
|
||||||
|
@ -1411,20 +1409,32 @@ UniataFindBusMasterController(
|
||||||
deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask;
|
deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask;
|
||||||
deviceExtension->AdapterInterfaceType = PCIBus;
|
deviceExtension->AdapterInterfaceType = PCIBus;
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX "chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
|
||||||
|
channel,
|
||||||
|
ConfigInfo->InterruptMode,
|
||||||
|
ConfigInfo->BusInterruptLevel,
|
||||||
|
ConfigInfo->BusInterruptLevel2,
|
||||||
|
ConfigInfo->BusInterruptVector,
|
||||||
|
ConfigInfo->BusInterruptVector2
|
||||||
|
));
|
||||||
|
|
||||||
found = FALSE;
|
found = FALSE;
|
||||||
|
|
||||||
if(deviceExtension->BusMaster) {
|
if(deviceExtension->BusMaster) {
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n"));
|
KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n"));
|
||||||
ConfigInfo->MapBuffers = TRUE;
|
|
||||||
#ifdef USE_OWN_DMA
|
#ifdef USE_OWN_DMA
|
||||||
ConfigInfo->NeedPhysicalAddresses = FALSE;
|
ConfigInfo->NeedPhysicalAddresses = FALSE;
|
||||||
#else
|
#else
|
||||||
ConfigInfo->NeedPhysicalAddresses = TRUE;
|
ConfigInfo->NeedPhysicalAddresses = TRUE;
|
||||||
#endif //USE_OWN_DMA
|
#endif //USE_OWN_DMA
|
||||||
if(!MasterDev) {
|
if(!MasterDev) {
|
||||||
|
//#ifdef USE_OWN_DMA
|
||||||
|
// KdPrint2((PRINT_PREFIX "!MasterDev, own DMA\n"));
|
||||||
|
//#else
|
||||||
KdPrint2((PRINT_PREFIX "set Dma32BitAddresses\n"));
|
KdPrint2((PRINT_PREFIX "set Dma32BitAddresses\n"));
|
||||||
ConfigInfo->Dma32BitAddresses = TRUE;
|
ConfigInfo->Dma32BitAddresses = TRUE;
|
||||||
|
//#endif //USE_OWN_DMA
|
||||||
}
|
}
|
||||||
|
|
||||||
// thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
|
// thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
|
||||||
|
@ -1451,9 +1461,10 @@ UniataFindBusMasterController(
|
||||||
ConfigInfo->Master = TRUE;
|
ConfigInfo->Master = TRUE;
|
||||||
ConfigInfo->DmaWidth = Width16Bits;
|
ConfigInfo->DmaWidth = Width16Bits;
|
||||||
#endif //USE_OWN_DMA
|
#endif //USE_OWN_DMA
|
||||||
ConfigInfo->CachesData = TRUE;
|
|
||||||
ConfigInfo->ScatterGather = TRUE;
|
ConfigInfo->ScatterGather = TRUE;
|
||||||
}
|
}
|
||||||
|
ConfigInfo->MapBuffers = TRUE; // Need for PIO and OWN_DMA
|
||||||
|
ConfigInfo->CachesData = TRUE;
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList[i].channel, deviceExtension->NumberChannels, channel));
|
KdPrint2((PRINT_PREFIX "BMList[i].channel %#x, NumberChannels %#x, channel %#x\n",BMList[i].channel, deviceExtension->NumberChannels, channel));
|
||||||
|
|
||||||
|
@ -1486,14 +1497,6 @@ UniataFindBusMasterController(
|
||||||
(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart =
|
(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart =
|
||||||
ScsiPortConvertUlongToPhysicalAddress((channel ? IO_WD2 : IO_WD1) + ATA_ALTOFFSET);
|
ScsiPortConvertUlongToPhysicalAddress((channel ? IO_WD2 : IO_WD1) + ATA_ALTOFFSET);
|
||||||
(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeLength = ATA_ALTIOSIZE;
|
(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeLength = ATA_ALTIOSIZE;
|
||||||
|
|
||||||
// do not claim 2nd BM io-range for Secondary channel of
|
|
||||||
// Compatible-mode controllers
|
|
||||||
if(/*(WinVer_Id() <= WinVer_NT) &&*/ !c && channel == 1) {
|
|
||||||
KdPrint2((PRINT_PREFIX "cheat ScsiPort for 2nd channel, BM io-range\n"));
|
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeLength = 0;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
if(AltInit &&
|
if(AltInit &&
|
||||||
!(*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart.QuadPart &&
|
!(*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart.QuadPart &&
|
||||||
|
@ -1552,8 +1555,8 @@ UniataFindBusMasterController(
|
||||||
|
|
||||||
// Get the system physical address for this IO range.
|
// Get the system physical address for this IO range.
|
||||||
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
||||||
PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
MasterDev ? ConfigInfo->AdapterInterfaceType : PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
||||||
SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
MasterDev ? ConfigInfo->SystemIoBusNumber : SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
||||||
IoBasePort1,
|
IoBasePort1,
|
||||||
ATA_IOSIZE,
|
ATA_IOSIZE,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
@ -1577,8 +1580,8 @@ UniataFindBusMasterController(
|
||||||
|
|
||||||
// Get the system physical address for the second IO range.
|
// Get the system physical address for the second IO range.
|
||||||
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
||||||
PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
MasterDev ? ConfigInfo->AdapterInterfaceType : PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
||||||
SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
MasterDev ? ConfigInfo->SystemIoBusNumber : SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
||||||
IoBasePort2,
|
IoBasePort2,
|
||||||
ATA_ALTIOSIZE,
|
ATA_ALTIOSIZE,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
@ -1744,12 +1747,12 @@ exit_findbm:
|
||||||
KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
|
KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
|
||||||
MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj));
|
MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj));
|
||||||
|
|
||||||
if(WinVer_WDM_Model && MasterDev) {
|
if(/*WinVer_WDM_Model &&*/ MasterDev) {
|
||||||
KdPrint2((PRINT_PREFIX "do not tell system, that we know about this:\n"));
|
KdPrint2((PRINT_PREFIX "do not tell system, that we know about PCI IO ranges\n"));
|
||||||
if(BaseIoAddressBM_0) {
|
/* if(BaseIoAddressBM_0) {
|
||||||
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
||||||
BaseIoAddressBM_0);
|
BaseIoAddressBM_0);
|
||||||
}
|
}*/
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
(*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeLength = 0;
|
(*ConfigInfo->AccessRanges)[4].RangeLength = 0;
|
||||||
(*ConfigInfo->AccessRanges)[5].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
(*ConfigInfo->AccessRanges)[5].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
||||||
|
@ -1761,6 +1764,17 @@ exit_findbm:
|
||||||
found = FALSE;
|
found = FALSE;
|
||||||
goto exit_findbm;
|
goto exit_findbm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX "final chan[%d] InterruptMode: %d, Level %d, Level2 %d, Vector %d, Vector2 %d\n",
|
||||||
|
channel,
|
||||||
|
ConfigInfo->InterruptMode,
|
||||||
|
ConfigInfo->BusInterruptLevel,
|
||||||
|
ConfigInfo->BusInterruptLevel2,
|
||||||
|
ConfigInfo->BusInterruptVector,
|
||||||
|
ConfigInfo->BusInterruptVector2
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //UNIATA_CORE
|
#endif //UNIATA_CORE
|
||||||
|
|
||||||
|
@ -1790,331 +1804,78 @@ exit_notfound:
|
||||||
/*
|
/*
|
||||||
This is for claiming PCI Busmaster in compatible mode under WDM OSes
|
This is for claiming PCI Busmaster in compatible mode under WDM OSes
|
||||||
*/
|
*/
|
||||||
ULONG
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataFindFakeBusMasterController(
|
UniataClaimLegacyPCIIDE(
|
||||||
IN PVOID HwDeviceExtension,
|
ULONG i
|
||||||
IN PVOID Context,
|
|
||||||
IN PVOID BusInformation,
|
|
||||||
IN PCHAR ArgumentString,
|
|
||||||
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
|
||||||
OUT PBOOLEAN Again
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
|
||||||
//PHW_CHANNEL chan = NULL;
|
|
||||||
// this buffer must be global for UNIATA_CORE build
|
|
||||||
PCI_COMMON_CONFIG pciData;
|
|
||||||
|
|
||||||
ULONG slotNumber;
|
|
||||||
ULONG busDataRead;
|
|
||||||
ULONG SystemIoBusNumber;
|
|
||||||
|
|
||||||
UCHAR vendorString[5];
|
|
||||||
UCHAR deviceString[5];
|
|
||||||
PUCHAR vendorStrPtr;
|
|
||||||
PUCHAR deviceStrPtr;
|
|
||||||
|
|
||||||
UCHAR BaseClass;
|
|
||||||
UCHAR SubClass;
|
|
||||||
ULONG VendorID;
|
|
||||||
ULONG DeviceID;
|
|
||||||
ULONG RevID;
|
|
||||||
ULONG dev_id;
|
|
||||||
PCI_SLOT_NUMBER slotData;
|
|
||||||
|
|
||||||
ULONG i;
|
|
||||||
// PUCHAR ioSpace;
|
|
||||||
// UCHAR statusByte;
|
|
||||||
|
|
||||||
// UCHAR tmp8;
|
|
||||||
// ULONG irq;
|
|
||||||
|
|
||||||
BOOLEAN found = FALSE;
|
|
||||||
BOOLEAN MasterDev;
|
|
||||||
BOOLEAN simplexOnly = FALSE;
|
|
||||||
//BOOLEAN skip_find_dev = FALSE;
|
|
||||||
//BOOLEAN AltInit = FALSE;
|
|
||||||
|
|
||||||
PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL;
|
|
||||||
|
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo =
|
PCM_RESOURCE_LIST resourceList;
|
||||||
(PPORT_CONFIGURATION_INFORMATION_COMMON)ConfigInfo;
|
UNICODE_STRING devname;
|
||||||
|
|
||||||
*Again = FALSE;
|
KdPrint2((PRINT_PREFIX "UniataClaimLegacyPCIIDE:\n"));
|
||||||
|
|
||||||
if(InDriverEntry) {
|
if(BMList[i].PciIdeDevObj) {
|
||||||
i = (ULONG)Context;
|
KdPrint2((PRINT_PREFIX "Already initialized\n"));
|
||||||
} else {
|
return STATUS_UNSUCCESSFUL;
|
||||||
for(i=0; i<BMListLen; i++) {
|
|
||||||
if(BMList[i].slotNumber == ConfigInfo->SlotNumber &&
|
|
||||||
BMList[i].busNumber == ConfigInfo->SystemIoBusNumber) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i >= BMListLen) {
|
|
||||||
KdPrint2((PRINT_PREFIX "unexpected device arrival => SP_RETURN_NOT_FOUND\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "UniataFindFakeBusMasterController (WDM)\n"));
|
RtlInitUnicodeString(&devname, L"\\Device\\uniata_PCIIDE");
|
||||||
|
status = IoCreateDevice(SavedDriverObject, sizeof(PCIIDE_DEVICE_EXTENSION),
|
||||||
|
/*NULL*/ &devname, FILE_DEVICE_UNKNOWN,
|
||||||
|
0, FALSE, &(BMList[i].PciIdeDevObj));
|
||||||
|
|
||||||
if (!deviceExtension) {
|
if(!NT_SUCCESS(status)) {
|
||||||
KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n"));
|
KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
|
||||||
return SP_RETURN_ERROR;
|
return status;
|
||||||
}
|
|
||||||
RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
|
|
||||||
|
|
||||||
vendorStrPtr = vendorString;
|
|
||||||
deviceStrPtr = deviceString;
|
|
||||||
|
|
||||||
slotNumber = BMList[i].slotNumber;
|
|
||||||
SystemIoBusNumber = BMList[i].busNumber;
|
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "AdapterInterfaceType=%#x\n",ConfigInfo->AdapterInterfaceType));
|
|
||||||
KdPrint2((PRINT_PREFIX "IoBusNumber=%#x\n",ConfigInfo->SystemIoBusNumber));
|
|
||||||
KdPrint2((PRINT_PREFIX "slotNumber=%#x\n",slotNumber));
|
|
||||||
|
|
||||||
// this buffer must be global and already filled for UNIATA_CORE build
|
|
||||||
busDataRead = HalGetBusData(
|
|
||||||
//busDataRead = ScsiPortGetBusData(HwDeviceExtension,
|
|
||||||
PCIConfiguration,
|
|
||||||
SystemIoBusNumber,
|
|
||||||
slotNumber,
|
|
||||||
&pciData,
|
|
||||||
PCI_COMMON_HDR_LENGTH);
|
|
||||||
|
|
||||||
if (busDataRead < PCI_COMMON_HDR_LENGTH) {
|
|
||||||
KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
|
|
||||||
goto exit_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "busDataRead\n"));
|
resourceList = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool,
|
||||||
if (pciData.VendorID == PCI_INVALID_VENDORID) {
|
sizeof(CM_RESOURCE_LIST));
|
||||||
KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n"));
|
|
||||||
goto exit_error;
|
if (!resourceList) {
|
||||||
|
KdPrint2((PRINT_PREFIX "!resourceList\n"));
|
||||||
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
del_do:
|
||||||
|
IoDeleteDevice(BMList[i].PciIdeDevObj);
|
||||||
|
BMList[i].PciIdeDevObj = NULL;
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
VendorID = pciData.VendorID;
|
RtlZeroMemory(
|
||||||
DeviceID = pciData.DeviceID;
|
resourceList,
|
||||||
BaseClass = pciData.BaseClass;
|
sizeof(CM_RESOURCE_LIST));
|
||||||
SubClass = pciData.SubClass;
|
|
||||||
RevID = pciData.RevisionID;
|
|
||||||
dev_id = VendorID | (DeviceID << 16);
|
|
||||||
slotData.u.AsULONG = slotNumber;
|
|
||||||
KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
|
||||||
|
|
||||||
deviceExtension->slotNumber = slotNumber;
|
// IoReportDetectedDevice() should be used for WDM OSes
|
||||||
deviceExtension->SystemIoBusNumber = SystemIoBusNumber;
|
|
||||||
deviceExtension->DevID = dev_id;
|
|
||||||
deviceExtension->RevID = RevID;
|
|
||||||
deviceExtension->NumberChannels = IDE_DEFAULT_MAX_CHAN; // default
|
|
||||||
deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
|
|
||||||
deviceExtension->DevIndex = i;
|
|
||||||
|
|
||||||
_snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
|
resourceList->Count = 1;
|
||||||
"UATA%8.8x/%1.1x@%8.8x", dev_id, 0xff, slotNumber);
|
resourceList->List[0].InterfaceType = PCIBus;
|
||||||
|
resourceList->List[0].BusNumber = BMList[i].busNumber;
|
||||||
|
// we do not report IO ranges since they are used/claimed by ISA part(s)
|
||||||
|
resourceList->List[0].PartialResourceList.Count = 0;
|
||||||
|
|
||||||
if(BaseClass != PCI_DEV_CLASS_STORAGE) {
|
RtlInitUnicodeString(&devname, L"PCIIDE");
|
||||||
KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
|
status = HalAssignSlotResources(&SavedRegPath,
|
||||||
goto exit_notfound;
|
&devname,
|
||||||
|
SavedDriverObject,
|
||||||
|
BMList[i].PciIdeDevObj,
|
||||||
|
PCIBus,
|
||||||
|
BMList[i].busNumber,
|
||||||
|
BMList[i].slotNumber,
|
||||||
|
&resourceList);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
KdPrint2((PRINT_PREFIX "HalAssignSlotResources failed %#x\n", status));
|
||||||
|
ExFreePool(resourceList);
|
||||||
|
goto del_do;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "Storage Class\n"));
|
KdPrint2((PRINT_PREFIX "ok %#x\n", status));
|
||||||
|
BMList[i].ChanInitOk |= 0x80;
|
||||||
|
|
||||||
// look for known chipsets
|
return status;
|
||||||
if(VendorID != BMList[i].nVendorId ||
|
} // end UniataClaimLegacyPCIIDE()
|
||||||
DeviceID != BMList[i].nDeviceId) {
|
|
||||||
KdPrint2((PRINT_PREFIX "device not suitable\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((BMList[i].RaidFlags & UNIATA_RAID_CONTROLLER) &&
|
|
||||||
SkipRaids) {
|
|
||||||
KdPrint2((PRINT_PREFIX "RAID support disabled\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!UniataCheckPCISubclass(FALSE, BMList[i].RaidFlags, SubClass)) {
|
|
||||||
KdPrint2((PRINT_PREFIX "Subclass not supported\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigInfo->AlignmentMask = 0x00000003;
|
|
||||||
|
|
||||||
status = UniataChipDetect(HwDeviceExtension, &pciData, i, ConfigInfo, &simplexOnly);
|
|
||||||
switch(status) {
|
|
||||||
case STATUS_SUCCESS:
|
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
case STATUS_NOT_FOUND:
|
|
||||||
found = FALSE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
KdPrint2((PRINT_PREFIX "FAILED => SP_RETURN_ERROR\n"));
|
|
||||||
goto exit_error;
|
|
||||||
}
|
|
||||||
KdPrint2((PRINT_PREFIX "ForceSimplex = %d\n", simplexOnly));
|
|
||||||
KdPrint2((PRINT_PREFIX "HwFlags = %x\n (0)", deviceExtension->HwFlags));
|
|
||||||
switch(dev_id) {
|
|
||||||
/* additional checks for some supported chipsets */
|
|
||||||
case 0xc6931080:
|
|
||||||
if (SubClass != PCI_DEV_SUBCLASS_IDE) {
|
|
||||||
KdPrint2((PRINT_PREFIX "0xc6931080, SubClass != PCI_DEV_SUBCLASS_IDE => found = FALSE\n"));
|
|
||||||
found = FALSE;
|
|
||||||
} else {
|
|
||||||
found = FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* unknown chipsets, try generic DMA if it seems possible */
|
|
||||||
default:
|
|
||||||
if (found)
|
|
||||||
break;
|
|
||||||
KdPrint2((PRINT_PREFIX "Default device\n"));
|
|
||||||
if(Ata_is_supported_dev(&pciData)) {
|
|
||||||
KdPrint2((PRINT_PREFIX "Ata_is_supported_dev\n"));
|
|
||||||
found = TRUE;
|
|
||||||
} else {
|
|
||||||
KdPrint2((PRINT_PREFIX "!Ata_is_supported_dev => found = FALSE\n"));
|
|
||||||
found = FALSE;
|
|
||||||
}
|
|
||||||
deviceExtension->UnknownDev = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags));
|
|
||||||
if(!found) {
|
|
||||||
KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags));
|
|
||||||
KdPrint2((PRINT_PREFIX "found suitable device\n"));
|
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/***********************************************************/
|
|
||||||
/***********************************************************/
|
|
||||||
|
|
||||||
deviceExtension->UseDpc = TRUE;
|
|
||||||
KdPrint2((PRINT_PREFIX "HwFlags = %x\n (3)", deviceExtension->HwFlags));
|
|
||||||
if(deviceExtension->HwFlags & UNIATA_NO_DPC) {
|
|
||||||
/* CMD 649, ROSB SWK33, ICH4 */
|
|
||||||
KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: UNIATA_NO_DPC (0)\n"));
|
|
||||||
deviceExtension->UseDpc = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
MasterDev = IsMasterDev(&pciData);
|
|
||||||
|
|
||||||
if(MasterDev) {
|
|
||||||
KdPrint2((PRINT_PREFIX "MasterDev\n"));
|
|
||||||
deviceExtension->MasterDev = TRUE;
|
|
||||||
deviceExtension->NumberChannels = 1;
|
|
||||||
} else {
|
|
||||||
KdPrint2((PRINT_PREFIX "!MasterDev => SP_RETURN_NOT_FOUND\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deviceExtension->AltRegMap) {
|
|
||||||
KdPrint2((PRINT_PREFIX " Non-standard registers layout => SP_RETURN_NOT_FOUND\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
if(IsBusMaster(&pciData)) {
|
|
||||||
KdPrint2((PRINT_PREFIX " !BusMaster => SP_RETURN_NOT_FOUND\n"));
|
|
||||||
goto exit_notfound;
|
|
||||||
}
|
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE\n"));
|
|
||||||
BaseIoAddressBM_0 = (PIDE_BUSMASTER_REGISTERS)
|
|
||||||
(AtapiGetIoRange(HwDeviceExtension, ConfigInfo, &pciData, SystemIoBusNumber,
|
|
||||||
4, 0, 0x10/*ATA_BMIOSIZE*/)/* - bm_offset*/); //range id
|
|
||||||
if(BaseIoAddressBM_0) {
|
|
||||||
UniataInitMapBM(deviceExtension,
|
|
||||||
BaseIoAddressBM_0,
|
|
||||||
(*ConfigInfo->AccessRanges)[4].RangeInMemory ? TRUE : FALSE);
|
|
||||||
deviceExtension->BusMaster = DMA_MODE_BM;
|
|
||||||
deviceExtension->BaseIoAddressBM_0.Addr = (ULONGIO_PTR)BaseIoAddressBM_0;
|
|
||||||
if((*ConfigInfo->AccessRanges)[4].RangeInMemory) {
|
|
||||||
deviceExtension->BaseIoAddressBM_0.MemIo = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
KdPrint2((PRINT_PREFIX " BusMasterAddress (base): %#x\n", BaseIoAddressBM_0));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the Cypress chip is a mess, it contains two ATA functions, but
|
|
||||||
* both channels are visible on the first one.
|
|
||||||
* simply ignore the second function for now, as the right
|
|
||||||
* solution (ignoring the second channel on the first function)
|
|
||||||
* doesn't work with the crappy ATA interrupt setup on the alpha.
|
|
||||||
*/
|
|
||||||
if (dev_id == 0xc6931080 && slotData.u.bits.FunctionNumber > 1) {
|
|
||||||
KdPrint2((PRINT_PREFIX "dev_id == 0xc6931080 && FunctionNumber > 1 => exit_findbm\n"));
|
|
||||||
goto exit_findbm;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indicate number of buses.
|
|
||||||
ConfigInfo->NumberOfBuses = 0;
|
|
||||||
if(!ConfigInfo->InitiatorBusId[0]) {
|
|
||||||
ConfigInfo->InitiatorBusId[0] = (CHAR)(IoGetConfigurationInformation()->ScsiPortCount);
|
|
||||||
KdPrint2((PRINT_PREFIX "set ConfigInfo->InitiatorBusId[0] = %#x\n", ConfigInfo->InitiatorBusId[0]));
|
|
||||||
}
|
|
||||||
// Indicate four devices can be attached to the adapter
|
|
||||||
ConfigInfo->MaximumNumberOfTargets = 0;
|
|
||||||
|
|
||||||
ConfigInfo->MultipleRequestPerLu = FALSE;
|
|
||||||
ConfigInfo->AutoRequestSense = FALSE;
|
|
||||||
ConfigInfo->TaggedQueuing = FALSE;
|
|
||||||
|
|
||||||
if((WinVer_Id() >= WinVer_NT) ||
|
|
||||||
(ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4))) {
|
|
||||||
_ConfigInfo->nt4.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
|
|
||||||
_ConfigInfo->nt4.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
|
|
||||||
_ConfigInfo->nt4.SrbExtensionSize = sizeof(ATA_REQ);
|
|
||||||
}
|
|
||||||
if((WinVer_Id() > WinVer_2k) ||
|
|
||||||
(ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
|
|
||||||
_ConfigInfo->w2k.Dma64BitAddresses = 0;
|
|
||||||
_ConfigInfo->w2k.ResetTargetSupported = FALSE;
|
|
||||||
_ConfigInfo->w2k.MaximumNumberOfLogicalUnits = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the Interrupe Mode for later use
|
|
||||||
deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
|
|
||||||
deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel;
|
|
||||||
deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector;
|
|
||||||
deviceExtension->Channel = 0;
|
|
||||||
deviceExtension->DevIndex = i;
|
|
||||||
deviceExtension->OrigAdapterInterfaceType
|
|
||||||
= ConfigInfo->AdapterInterfaceType;
|
|
||||||
deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask;
|
|
||||||
deviceExtension->AdapterInterfaceType = PCIBus;
|
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n"));
|
|
||||||
ConfigInfo->MapBuffers = TRUE;
|
|
||||||
#ifdef USE_OWN_DMA
|
|
||||||
ConfigInfo->NeedPhysicalAddresses = FALSE;
|
|
||||||
#else
|
|
||||||
ConfigInfo->NeedPhysicalAddresses = TRUE;
|
|
||||||
#endif //USE_OWN_DMA
|
|
||||||
|
|
||||||
exit_findbm:
|
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "return SP_RETURN_FOUND\n"));
|
|
||||||
//PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
|
|
||||||
|
|
||||||
return SP_RETURN_FOUND;
|
|
||||||
|
|
||||||
exit_error:
|
|
||||||
UniataFreeLunExt(deviceExtension);
|
|
||||||
return SP_RETURN_ERROR;
|
|
||||||
|
|
||||||
exit_notfound:
|
|
||||||
UniataFreeLunExt(deviceExtension);
|
|
||||||
return SP_RETURN_NOT_FOUND;
|
|
||||||
|
|
||||||
} // end UniataFindFakeBusMasterController()
|
|
||||||
|
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
@ -2148,11 +1909,6 @@ UniataConnectIntr2(
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "Init ISR:\n"));
|
KdPrint2((PRINT_PREFIX "Init ISR:\n"));
|
||||||
|
|
||||||
if(BMList[i].Isr2DevObj) {
|
|
||||||
KdPrint2((PRINT_PREFIX "Already initialized %#x\n", BMList[i].Isr2DevObj));
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev
|
if(!deviceExtension->MasterDev && (deviceExtension->NumberChannels > 1) && // do not touch MasterDev
|
||||||
!deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers
|
!deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers
|
||||||
!BMList[i].Isr2DevObj*/ // handle re-init under w2k+
|
!BMList[i].Isr2DevObj*/ // handle re-init under w2k+
|
||||||
|
@ -2172,6 +1928,11 @@ UniataConnectIntr2(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(BMList[i].Isr2DevObj) {
|
||||||
|
KdPrint2((PRINT_PREFIX "Already initialized [%d] %#x\n", i, BMList[i].Isr2DevObj));
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX "Create DO\n"));
|
KdPrint2((PRINT_PREFIX "Create DO\n"));
|
||||||
|
|
||||||
devname.Length =
|
devname.Length =
|
||||||
|
@ -2188,7 +1949,7 @@ UniataConnectIntr2(
|
||||||
0, FALSE, &(BMList[i].Isr2DevObj));
|
0, FALSE, &(BMList[i].Isr2DevObj));
|
||||||
|
|
||||||
if(!NT_SUCCESS(status)) {
|
if(!NT_SUCCESS(status)) {
|
||||||
KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n"));
|
KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2907,6 +2668,10 @@ CheckDevice(
|
||||||
}
|
}
|
||||||
LunExt = chan->lun[deviceNumber];
|
LunExt = chan->lun[deviceNumber];
|
||||||
|
|
||||||
|
if(ResetDev) {
|
||||||
|
LunExt->PowerState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
|
if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
|
||||||
KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
|
KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
|
||||||
if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
|
if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
|
||||||
|
|
|
@ -619,7 +619,26 @@ UniataAhciInit(
|
||||||
UniataDumpAhciRegs(deviceExtension);
|
UniataDumpAhciRegs(deviceExtension);
|
||||||
#endif //DBG
|
#endif //DBG
|
||||||
|
|
||||||
/* reset AHCI controller */
|
/* disable AHCI interrupts, for MSI compatibility issue
|
||||||
|
see http://www.intel.com/Assets/PDF/specupdate/307014.pdf
|
||||||
|
26. AHCI Reset and MSI Request
|
||||||
|
*/
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX " get GHC\n"));
|
||||||
|
/* enable AHCI mode */
|
||||||
|
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||||
|
if(!(GHC & AHCI_GHC_AE)) {
|
||||||
|
KdPrint2((PRINT_PREFIX " enable AHCI mode, disable intr, GHC %#x\n", GHC));
|
||||||
|
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||||
|
(GHC | AHCI_GHC_AE) & ~AHCI_GHC_IE);
|
||||||
|
} else {
|
||||||
|
KdPrint2((PRINT_PREFIX " disable intr, GHC %#x\n", GHC));
|
||||||
|
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||||
|
GHC & ~AHCI_GHC_IE);
|
||||||
|
}
|
||||||
|
AtapiStallExecution(100);
|
||||||
|
|
||||||
|
/* read GHC again and reset AHCI controller */
|
||||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||||
KdPrint2((PRINT_PREFIX " reset AHCI controller, GHC %#x\n", GHC));
|
KdPrint2((PRINT_PREFIX " reset AHCI controller, GHC %#x\n", GHC));
|
||||||
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||||
|
@ -638,12 +657,14 @@ UniataAhciInit(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable AHCI mode */
|
/* re-enable AHCI mode */
|
||||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||||
KdPrint2((PRINT_PREFIX " enable AHCI mode, GHC %#x\n", GHC));
|
if(!(GHC & AHCI_GHC_AE)) {
|
||||||
|
KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC));
|
||||||
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||||
GHC | AHCI_GHC_AE);
|
GHC | AHCI_GHC_AE);
|
||||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||||
|
}
|
||||||
KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
|
KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
|
||||||
if(!(GHC & AHCI_GHC_AE)) {
|
if(!(GHC & AHCI_GHC_AE)) {
|
||||||
KdPrint2((PRINT_PREFIX " Can't enable AHCI mode\n"));
|
KdPrint2((PRINT_PREFIX " Can't enable AHCI mode\n"));
|
||||||
|
@ -652,7 +673,6 @@ UniataAhciInit(
|
||||||
|
|
||||||
deviceExtension->AHCI_CAP =
|
deviceExtension->AHCI_CAP =
|
||||||
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
||||||
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
|
|
||||||
KdPrint2((PRINT_PREFIX " AHCI CAP %#x\n", CAP));
|
KdPrint2((PRINT_PREFIX " AHCI CAP %#x\n", CAP));
|
||||||
if(CAP & AHCI_CAP_S64A) {
|
if(CAP & AHCI_CAP_S64A) {
|
||||||
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
|
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
|
||||||
|
@ -689,6 +709,8 @@ UniataAhciInit(
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX " chan %d, offs %#x\n", c, offs));
|
KdPrint2((PRINT_PREFIX " chan %d, offs %#x\n", c, offs));
|
||||||
|
|
||||||
|
chan->MaxTransferMode = deviceExtension->MaxTransferMode;
|
||||||
|
|
||||||
AtapiSetupLunPtrs(chan, deviceExtension, c);
|
AtapiSetupLunPtrs(chan, deviceExtension, c);
|
||||||
|
|
||||||
chan->BaseIoAHCI_Port = deviceExtension->BaseIoAHCI_0;
|
chan->BaseIoAHCI_Port = deviceExtension->BaseIoAHCI_0;
|
||||||
|
@ -719,6 +741,11 @@ UniataAhciInit(
|
||||||
|
|
||||||
AtapiDmaAlloc(HwDeviceExtension, NULL, c);
|
AtapiDmaAlloc(HwDeviceExtension, NULL, c);
|
||||||
|
|
||||||
|
if(!UniataAhciChanImplemented(deviceExtension, c)) {
|
||||||
|
KdPrint2((PRINT_PREFIX " chan %d not implemented\n", c));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
UniataAhciResume(chan);
|
UniataAhciResume(chan);
|
||||||
|
|
||||||
chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
||||||
|
@ -727,6 +754,35 @@ UniataAhciInit(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} // end UniataAhciInit()
|
} // end UniataAhciInit()
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
UniAtaAhciValidateVersion(
|
||||||
|
IN PHW_DEVICE_EXTENSION deviceExtension,
|
||||||
|
IN ULONG version,
|
||||||
|
IN BOOLEAN Strict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch(version) {
|
||||||
|
case 0x00000000:
|
||||||
|
case 0xffffffff:
|
||||||
|
KdPrint((" wrong AHCI revision %#x\n", version));
|
||||||
|
return FALSE;
|
||||||
|
case 0x00000905:
|
||||||
|
case 0x00010000:
|
||||||
|
case 0x00010100:
|
||||||
|
case 0x00010200:
|
||||||
|
case 0x00010300:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
KdPrint2((PRINT_PREFIX " Unknown AHCI revision\n"));
|
||||||
|
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"CheckAhciRevision", Strict)) {
|
||||||
|
KdPrint((" AHCI revision excluded\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
} // end UniAtaAhciValidateVersion()
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataAhciDetect(
|
UniataAhciDetect(
|
||||||
|
@ -743,12 +799,13 @@ UniataAhciDetect(
|
||||||
ULONG PI;
|
ULONG PI;
|
||||||
ULONG CAP;
|
ULONG CAP;
|
||||||
ULONG CAP2;
|
ULONG CAP2;
|
||||||
ULONG GHC;
|
ULONG GHC, GHC0;
|
||||||
ULONG BOHC;
|
ULONG BOHC;
|
||||||
ULONG NumberChannels;
|
ULONG NumberChannels;
|
||||||
ULONG v_Mn, v_Mj;
|
ULONG v_Mn, v_Mj;
|
||||||
ULONG BaseMemAddress;
|
ULONG BaseMemAddress;
|
||||||
BOOLEAN MemIo;
|
BOOLEAN MemIo = FALSE;
|
||||||
|
BOOLEAN found = FALSE;
|
||||||
|
|
||||||
KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
|
KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
|
||||||
|
|
||||||
|
@ -762,7 +819,7 @@ UniataAhciDetect(
|
||||||
KdPrint2((PRINT_PREFIX " AHCI init failed - no IoRange\n"));
|
KdPrint2((PRINT_PREFIX " AHCI init failed - no IoRange\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
|
if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
|
||||||
KdPrint2((PRINT_PREFIX "MemIo\n"));
|
KdPrint2((PRINT_PREFIX "MemIo\n"));
|
||||||
MemIo = TRUE;
|
MemIo = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -779,12 +836,29 @@ UniataAhciDetect(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable AHCI mode */
|
/* check AHCI mode. Save state and try enable */
|
||||||
|
GHC0 =
|
||||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||||
KdPrint2((PRINT_PREFIX " check AHCI mode, GHC %#x\n", GHC));
|
KdPrint2((PRINT_PREFIX " check AHCI mode, GHC %#x\n", GHC));
|
||||||
|
|
||||||
|
version = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_VS);
|
||||||
|
|
||||||
|
if(!(GHC & AHCI_GHC_AE)) {
|
||||||
|
KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE), check revision %#x\n", version));
|
||||||
|
if(!UniAtaAhciValidateVersion(deviceExtension, version, FALSE)) {
|
||||||
|
KdPrint2((PRINT_PREFIX " Non-AHCI\n"));
|
||||||
|
goto exit_detect;
|
||||||
|
}
|
||||||
|
KdPrint2((PRINT_PREFIX " try enable\n"));
|
||||||
|
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||||
|
(GHC | AHCI_GHC_AE) & ~AHCI_GHC_IE);
|
||||||
|
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX " re-check AHCI mode, GHC %#x\n", GHC));
|
||||||
if(!(GHC & AHCI_GHC_AE)) {
|
if(!(GHC & AHCI_GHC_AE)) {
|
||||||
KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE)\n"));
|
KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE)\n"));
|
||||||
return FALSE;
|
goto exit_detect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
||||||
|
@ -792,7 +866,7 @@ UniataAhciDetect(
|
||||||
KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x\n", CAP, CAP2));
|
KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x\n", CAP, CAP2));
|
||||||
if(CAP & AHCI_CAP_S64A) {
|
if(CAP & AHCI_CAP_S64A) {
|
||||||
KdPrint2((PRINT_PREFIX " 64bit"));
|
KdPrint2((PRINT_PREFIX " 64bit"));
|
||||||
//deviceExtension->Host64 = TRUE;
|
//deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
|
||||||
}
|
}
|
||||||
if(CAP2 & AHCI_CAP2_BOH) {
|
if(CAP2 & AHCI_CAP2_BOH) {
|
||||||
BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
|
BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
|
||||||
|
@ -811,6 +885,7 @@ UniataAhciDetect(
|
||||||
|
|
||||||
/* get the number of HW channels */
|
/* get the number of HW channels */
|
||||||
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
|
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
|
||||||
|
deviceExtension->AHCI_PI = PI;
|
||||||
KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
|
KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
|
||||||
for(i=PI, n=0; i; n++, i=i>>1);
|
for(i=PI, n=0; i; n++, i=i>>1);
|
||||||
NumberChannels =
|
NumberChannels =
|
||||||
|
@ -834,10 +909,10 @@ UniataAhciDetect(
|
||||||
|
|
||||||
if(!NumberChannels) {
|
if(!NumberChannels) {
|
||||||
KdPrint2((PRINT_PREFIX " Non-AHCI - NumberChannels=0\n"));
|
KdPrint2((PRINT_PREFIX " Non-AHCI - NumberChannels=0\n"));
|
||||||
return FALSE;
|
found = FALSE;
|
||||||
|
goto exit_detect;
|
||||||
}
|
}
|
||||||
|
|
||||||
version = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_VS);
|
|
||||||
v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
|
v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
|
||||||
v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
|
v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
|
||||||
|
|
||||||
|
@ -862,19 +937,8 @@ UniataAhciDetect(
|
||||||
deviceExtension->NumberLuns = 1;
|
deviceExtension->NumberLuns = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(version) {
|
if(!UniAtaAhciValidateVersion(deviceExtension, version, TRUE)) {
|
||||||
case 0x00000905:
|
goto exit_detect;
|
||||||
case 0x00010000:
|
|
||||||
case 0x00010100:
|
|
||||||
case 0x00010200:
|
|
||||||
case 0x00010300:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
KdPrint2((PRINT_PREFIX " Unknown AHCI revision\n"));
|
|
||||||
if(AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"CheckAhciRevision", 1)) {
|
|
||||||
KdPrint((" AHCI revision excluded\n"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
|
deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
|
||||||
|
@ -887,7 +951,13 @@ UniataAhciDetect(
|
||||||
deviceExtension->BusMaster = DMA_MODE_AHCI;
|
deviceExtension->BusMaster = DMA_MODE_AHCI;
|
||||||
deviceExtension->MaxTransferMode = max(deviceExtension->MaxTransferMode, ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1) );
|
deviceExtension->MaxTransferMode = max(deviceExtension->MaxTransferMode, ATA_SA150+(((CAP & AHCI_CAP_ISS_MASK) >> 20)-1) );
|
||||||
|
|
||||||
return TRUE;
|
found = TRUE;
|
||||||
|
|
||||||
|
exit_detect:
|
||||||
|
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC, GHC0);
|
||||||
|
KdPrint((" AHCI detect status %d\n", found));
|
||||||
|
|
||||||
|
return found;
|
||||||
} // end UniataAhciDetect()
|
} // end UniataAhciDetect()
|
||||||
|
|
||||||
UCHAR
|
UCHAR
|
||||||
|
@ -974,6 +1044,31 @@ UniataAhciStatus(
|
||||||
|
|
||||||
} // end UniataAhciStatus()
|
} // end UniataAhciStatus()
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
UniataAhciSnapAtaRegs(
|
||||||
|
IN PHW_CHANNEL chan,
|
||||||
|
IN ULONG DeviceNumber,
|
||||||
|
IN OUT PIDEREGS_EX regs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG TFD, SIG;
|
||||||
|
|
||||||
|
regs->bDriveHeadReg = IDE_DRIVE_SELECT_1;
|
||||||
|
TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
|
||||||
|
regs->bCommandReg = (UCHAR)(TFD & 0xff);
|
||||||
|
regs->bFeaturesReg = (UCHAR)((TFD >> 8) & 0xff);
|
||||||
|
|
||||||
|
SIG = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
|
||||||
|
regs->bSectorCountReg = (UCHAR)(SIG & 0xff);
|
||||||
|
regs->bSectorNumberReg = (UCHAR)((SIG >> 8) & 0xff);
|
||||||
|
regs->bCylLowReg = (UCHAR)((SIG >> 16) & 0xff);
|
||||||
|
regs->bCylHighReg = (UCHAR)((SIG >> 24) & 0xff);
|
||||||
|
regs->bOpFlags = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
} // end UniataAhciSnapAtaRegs()
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataAhciSetupFIS_H2D(
|
UniataAhciSetupFIS_H2D(
|
||||||
|
@ -1083,6 +1178,99 @@ UniataAhciSetupFIS_H2D(
|
||||||
return 20;
|
return 20;
|
||||||
} // end UniataAhciSetupFIS_H2D()
|
} // end UniataAhciSetupFIS_H2D()
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
UniataAhciSetupFIS_H2D_Direct(
|
||||||
|
IN PHW_DEVICE_EXTENSION deviceExtension,
|
||||||
|
IN ULONG DeviceNumber,
|
||||||
|
IN ULONG lChannel,
|
||||||
|
OUT PUCHAR fis,
|
||||||
|
IN PIDEREGS_EX regs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//ULONG i;
|
||||||
|
//PUCHAR plba;
|
||||||
|
BOOLEAN need48;
|
||||||
|
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||||
|
UCHAR command;
|
||||||
|
|
||||||
|
command = regs->bCommandReg;
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX " AHCI setup FIS Direct %x, ch %d, dev %d\n", fis, lChannel, DeviceNumber));
|
||||||
|
//i = 0;
|
||||||
|
//plba = (PUCHAR)&lba;
|
||||||
|
|
||||||
|
RtlZeroMemory(fis, 20);
|
||||||
|
|
||||||
|
fis[0] = AHCI_FIS_TYPE_ATA_H2D; /* host to device */
|
||||||
|
fis[1] = 0x80 | ((UCHAR)DeviceNumber & 0x0f); /* command FIS (note PM goes here) */
|
||||||
|
fis[IDX_AHCI_o_DriveSelect] = IDE_DRIVE_SELECT_1 |
|
||||||
|
((AtaCommandFlags[command] & (ATA_CMD_FLAG_LBAIOsupp | ATA_CMD_FLAG_48)) ? IDE_USE_LBA : 0);
|
||||||
|
fis[IDX_AHCI_o_Control] = IDE_DC_A_4BIT;
|
||||||
|
|
||||||
|
// IDE_COMMAND_ATAPI_IDENTIFY should be processed as regular ATA command,
|
||||||
|
// the rest of ATAPI requests are processed via IDE_COMMAND_ATAPI_PACKET
|
||||||
|
if(/*(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
|
||||||
|
*/
|
||||||
|
command == IDE_COMMAND_ATAPI_PACKET) {
|
||||||
|
/* fis[IDX_AHCI_o_Command] = IDE_COMMAND_ATAPI_PACKET;
|
||||||
|
if(feature & ATA_F_DMA) {
|
||||||
|
fis[IDX_AHCI_o_Feature] = (UCHAR)(feature & 0xff);
|
||||||
|
} else {
|
||||||
|
fis[IDX_AHCI_o_CylinderLow] = (UCHAR)(count & 0xff);
|
||||||
|
fis[IDX_AHCI_o_CylinderHigh] = (UCHAR)(count>>8) & 0xff;
|
||||||
|
}*/
|
||||||
|
return 0;
|
||||||
|
//fis[IDX_AHCI_o_Control] |= IDE_DC_A_4BIT;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
need48 = (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) &&
|
||||||
|
chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48;
|
||||||
|
|
||||||
|
/* translate command into 48bit version */
|
||||||
|
if(need48) {
|
||||||
|
if(AtaCommandFlags[command] & ATA_CMD_FLAG_48supp) {
|
||||||
|
command = AtaCommands48[command];
|
||||||
|
} else {
|
||||||
|
KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fis[IDX_AHCI_o_Command] = command;
|
||||||
|
fis[IDX_AHCI_o_Feature] = regs->bFeaturesReg;
|
||||||
|
|
||||||
|
fis[IDX_AHCI_o_BlockNumber] = regs->bSectorNumberReg;
|
||||||
|
fis[IDX_AHCI_o_CylinderLow] = regs->bCylLowReg;
|
||||||
|
fis[IDX_AHCI_o_CylinderHigh] = regs->bCylHighReg;
|
||||||
|
|
||||||
|
fis[IDX_AHCI_o_BlockCount] = regs->bSectorCountReg;
|
||||||
|
|
||||||
|
if(need48) {
|
||||||
|
//i++;
|
||||||
|
fis[IDX_AHCI_o_Control] |= IDE_DC_USE_HOB;
|
||||||
|
|
||||||
|
fis[IDX_AHCI_o_BlockNumberExp] = regs->bSectorNumberRegH;
|
||||||
|
fis[IDX_AHCI_o_CylinderLowExp] = regs->bCylLowRegH;
|
||||||
|
fis[IDX_AHCI_o_CylinderHighExp] = regs->bCylHighRegH;
|
||||||
|
|
||||||
|
fis[IDX_AHCI_o_BlockCountExp] = regs->bSectorCountRegH;
|
||||||
|
|
||||||
|
fis[IDX_AHCI_o_FeatureExp] = regs->bFeaturesRegH;
|
||||||
|
|
||||||
|
chan->ChannelCtrlFlags |= CTRFLAGS_LBA48;
|
||||||
|
} else {
|
||||||
|
//fis[IDX_AHCI_o_DriveSelect] |= /*IDE_DRIVE_1 |*/ (plba[3] & 0x0f);
|
||||||
|
chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
|
||||||
|
}
|
||||||
|
fis[IDX_AHCI_o_DriveSelect] |= regs->bDriveHeadReg & 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
KdDump(fis, 20);
|
||||||
|
|
||||||
|
return 20;
|
||||||
|
} // end UniataAhciSetupFIS_H2D_Direct()
|
||||||
|
|
||||||
UCHAR
|
UCHAR
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataAhciWaitCommandReady(
|
UniataAhciWaitCommandReady(
|
||||||
|
@ -1304,6 +1492,116 @@ UniataAhciSendPIOCommand(
|
||||||
|
|
||||||
} // end UniataAhciSendPIOCommand()
|
} // end UniataAhciSendPIOCommand()
|
||||||
|
|
||||||
|
UCHAR
|
||||||
|
NTAPI
|
||||||
|
UniataAhciSendPIOCommandDirect(
|
||||||
|
IN PVOID HwDeviceExtension,
|
||||||
|
IN ULONG lChannel,
|
||||||
|
IN ULONG DeviceNumber,
|
||||||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||||||
|
IN PIDEREGS_EX regs,
|
||||||
|
IN ULONG wait_flags,
|
||||||
|
IN ULONG timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||||
|
PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
|
||||||
|
UCHAR statusByte;
|
||||||
|
PATA_REQ AtaReq;
|
||||||
|
ULONG fis_size;
|
||||||
|
//ULONG tag=0;
|
||||||
|
//PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
|
||||||
|
PIDE_AHCI_CMD AHCI_CMD = NULL;
|
||||||
|
USHORT ahci_flags=0;
|
||||||
|
// USHORT bcount=0;
|
||||||
|
|
||||||
|
//PIDE_AHCI_CMD_LIST AHCI_CL = &(chan->AhciCtlBlock->cmd_list[tag]);
|
||||||
|
|
||||||
|
KdPrint2((PRINT_PREFIX "UniataAhciSendPIOCommand: cntrlr %#x:%#x dev %#x, buff %#x, len %#x, WF %#x \n",
|
||||||
|
deviceExtension->DevIndex, lChannel, DeviceNumber, Srb->DataBuffer, Srb->DataTransferLength, wait_flags ));
|
||||||
|
|
||||||
|
// if(Srb->DataTransferLength/DEV_BSIZE != bcount) {
|
||||||
|
// KdPrint((" length/DEV_BSIZE != bcount\n"));
|
||||||
|
// }
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
//UniataDumpAhciPortRegs(chan);
|
||||||
|
#endif // DBG
|
||||||
|
|
||||||
|
if(!Srb) {
|
||||||
|
KdPrint((" !Srb\n"));
|
||||||
|
return IDE_STATUS_WRONG;
|
||||||
|
//UniataAhciSetupCmdPtr(AtaReq); // must be called before DMA setup
|
||||||
|
//should be already called on init
|
||||||
|
}
|
||||||
|
AtaReq = (PATA_REQ)(Srb->SrbExtension);
|
||||||
|
//KdPrint((" Srb %#x, AtaReq %#x\n", Srb, AtaReq));
|
||||||
|
|
||||||
|
AHCI_CMD = AtaReq->ahci.ahci_cmd_ptr;
|
||||||
|
if(!AHCI_CMD) {
|
||||||
|
KdPrint((" !AHCI_CMD\n"));
|
||||||
|
return IDE_STATUS_WRONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Srb->DataTransferLength) {
|
||||||
|
if(Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
|
||||||
|
ahci_flags |= ATA_AHCI_CMD_WRITE;
|
||||||
|
AtaReq->Flags &= ~REQ_FLAG_READ;
|
||||||
|
} else {
|
||||||
|
AtaReq->Flags |= REQ_FLAG_READ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fis_size = UniataAhciSetupFIS_H2D_Direct(deviceExtension, DeviceNumber, lChannel,
|
||||||
|
&(AHCI_CMD->cfis[0]),
|
||||||
|
regs);
|
||||||
|
|
||||||
|
if(!fis_size) {
|
||||||
|
KdPrint2(("!fis_size\n"));
|
||||||
|
return IDE_STATUS_WRONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
//KdPrint2(("UniAtaAhciAdjustIoFlags(command, ahci_flags, fis_size, DeviceNumber)\n"));
|
||||||
|
ahci_flags = UniAtaAhciAdjustIoFlags(regs->bCommandReg, ahci_flags, fis_size, DeviceNumber);
|
||||||
|
KdPrint2(("ahci_flags %#x\n", ahci_flags));
|
||||||
|
|
||||||
|
if(Srb->DataTransferLength) {
|
||||||
|
if(!AtapiDmaSetup(HwDeviceExtension,
|
||||||
|
DeviceNumber,
|
||||||
|
lChannel, // logical channel,
|
||||||
|
Srb,
|
||||||
|
(PUCHAR)(Srb->DataBuffer),
|
||||||
|
Srb->DataTransferLength)) {
|
||||||
|
KdPrint2((" can't setup buffer\n"));
|
||||||
|
return IDE_STATUS_WRONG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AtaReq->ahci.io_cmd_flags = ahci_flags;
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
//UniataDumpAhciPortRegs(chan);
|
||||||
|
#endif // DBG
|
||||||
|
|
||||||
|
UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
//UniataDumpAhciPortRegs(chan);
|
||||||
|
#endif // DBG
|
||||||
|
|
||||||
|
if(wait_flags == ATA_IMMEDIATE) {
|
||||||
|
statusByte = 0;
|
||||||
|
KdPrint2((" return imemdiately\n"));
|
||||||
|
} else {
|
||||||
|
statusByte = UniataAhciWaitCommandReady(chan, timeout);
|
||||||
|
UniataAhciStatus(HwDeviceExtension, lChannel, DeviceNumber);
|
||||||
|
UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusByte;
|
||||||
|
|
||||||
|
} // end UniataAhciSendPIOCommandDirect()
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataAhciAbortOperation(
|
UniataAhciAbortOperation(
|
||||||
|
|
|
@ -147,6 +147,14 @@ UniataAhciStatus(
|
||||||
IN ULONG DeviceNumber
|
IN ULONG DeviceNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
UniataAhciSnapAtaRegs(
|
||||||
|
IN PHW_CHANNEL chan,
|
||||||
|
IN ULONG DeviceNumber,
|
||||||
|
IN OUT PIDEREGS_EX regs
|
||||||
|
);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataAhciSetupFIS_H2D(
|
UniataAhciSetupFIS_H2D(
|
||||||
|
@ -195,6 +203,18 @@ UniataAhciSendPIOCommand(
|
||||||
IN ULONG timeout
|
IN ULONG timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
UCHAR
|
||||||
|
NTAPI
|
||||||
|
UniataAhciSendPIOCommandDirect(
|
||||||
|
IN PVOID HwDeviceExtension,
|
||||||
|
IN ULONG lChannel,
|
||||||
|
IN ULONG DeviceNumber,
|
||||||
|
IN PSCSI_REQUEST_BLOCK Srb,
|
||||||
|
IN PIDEREGS_EX regs,
|
||||||
|
IN ULONG wait_flags,
|
||||||
|
IN ULONG timeout
|
||||||
|
);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
UniataAhciAbortOperation(
|
UniataAhciAbortOperation(
|
||||||
|
@ -387,4 +407,8 @@ BuildAhciInternalSrb (
|
||||||
IN ULONG Length = 0
|
IN ULONG Length = 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#define UniataAhciChanImplemented(deviceExtension, c) \
|
||||||
|
(((deviceExtension)->AHCI_PI) & (1 << c))
|
||||||
|
|
||||||
|
|
||||||
#endif //__UNIATA_SATA__H__
|
#endif //__UNIATA_SATA__H__
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/* The definitions look so crappy, because the code doesn't care
|
/* The definitions look so crappy, because the code doesn't care
|
||||||
whether the source is an array or an integer */
|
whether the source is an array or an integer */
|
||||||
#define MOV_DD_SWP(a,b) ((a) = RtlUlongByteSwap(*(PULONG)&(b)))
|
#define MOV_DD_SWP(a,b) ( ((PULONG)&(a))[0] = RtlUlongByteSwap(*(PULONG)&(b)))
|
||||||
#define MOV_DW_SWP(a,b) ( ((PUSHORT)&(a))[0] = RtlUshortByteSwap(*(PUSHORT)&(b)))
|
#define MOV_DW_SWP(a,b) ( ((PUSHORT)&(a))[0] = RtlUshortByteSwap(*(PUSHORT)&(b)))
|
||||||
#define MOV_SWP_DW2DD(a,b) ((a) = RtlUshortByteSwap(*(PUSHORT)&(b)))
|
#define MOV_SWP_DW2DD(a,b) ((a) = RtlUshortByteSwap(*(PUSHORT)&(b)))
|
||||||
#define MOV_QD_SWP(a,b) { ((PULONG)&(a))[0] = RtlUlongByteSwap( ((PULONG)&(b))[1]); ((PULONG)&(a))[1] = RtlUlongByteSwap( ((PULONG)&(b))[0]); }
|
#define MOV_QD_SWP(a,b) { ((PULONG)&(a))[0] = RtlUlongByteSwap( ((PULONG)&(b))[1]); ((PULONG)&(a))[1] = RtlUlongByteSwap( ((PULONG)&(b))[0]); }
|
||||||
|
|
|
@ -392,13 +392,22 @@ typedef union _CDB {
|
||||||
UCHAR Immediate: 1;
|
UCHAR Immediate: 1;
|
||||||
UCHAR Reserved1 : 4;
|
UCHAR Reserved1 : 4;
|
||||||
UCHAR Lun : 3;
|
UCHAR Lun : 3;
|
||||||
UCHAR Reserved2[2];
|
UCHAR Reserved2;
|
||||||
|
UCHAR FormatLayerNumber : 2;
|
||||||
|
UCHAR Reserved2_2 : 6;
|
||||||
UCHAR Start : 1;
|
UCHAR Start : 1;
|
||||||
UCHAR LoadEject : 1;
|
UCHAR LoadEject : 1;
|
||||||
UCHAR Reserved3 : 6;
|
UCHAR FL : 1;
|
||||||
|
UCHAR Reserved3 : 1;
|
||||||
|
UCHAR PowerConditions : 4;
|
||||||
UCHAR Control;
|
UCHAR Control;
|
||||||
} START_STOP, *PSTART_STOP;
|
} START_STOP, *PSTART_STOP;
|
||||||
|
|
||||||
|
#define StartStop_Power_NoChg 0x00
|
||||||
|
#define StartStop_Power_Idle 0x02
|
||||||
|
#define StartStop_Power_Standby 0x03
|
||||||
|
#define StartStop_Power_Sleep 0x05
|
||||||
|
|
||||||
struct _MEDIA_REMOVAL {
|
struct _MEDIA_REMOVAL {
|
||||||
UCHAR OperationCode;
|
UCHAR OperationCode;
|
||||||
UCHAR Reserved1 : 5;
|
UCHAR Reserved1 : 5;
|
||||||
|
@ -685,6 +694,14 @@ typedef union _CDB {
|
||||||
UCHAR Control;
|
UCHAR Control;
|
||||||
} SET_READ_AHEAD, *PSET_READ_AHEAD;
|
} SET_READ_AHEAD, *PSET_READ_AHEAD;
|
||||||
|
|
||||||
|
struct _REPORT_LUNS {
|
||||||
|
UCHAR OperationCode; // 0xA0 - SCSIOP_REPORT_LUNS
|
||||||
|
UCHAR Reserved1[5];
|
||||||
|
UCHAR AllocationLength[4];
|
||||||
|
UCHAR Reserved2[1];
|
||||||
|
UCHAR Control;
|
||||||
|
} REPORT_LUNS, *PREPORT_LUNS;
|
||||||
|
|
||||||
#define SendOpc_DoOpc 0x01
|
#define SendOpc_DoOpc 0x01
|
||||||
|
|
||||||
struct _SEND_OPC_INFO {
|
struct _SEND_OPC_INFO {
|
||||||
|
@ -901,6 +918,7 @@ typedef union _CDB {
|
||||||
|
|
||||||
#define SCSIOP_SA_READ_CAPACITY16 0x10
|
#define SCSIOP_SA_READ_CAPACITY16 0x10
|
||||||
|
|
||||||
|
#define SCSIOP_REPORT_LUNS 0xA0
|
||||||
#define SCSIOP_BLANK 0xA1
|
#define SCSIOP_BLANK 0xA1
|
||||||
#define SCSIOP_SEND_KEY 0xA3
|
#define SCSIOP_SEND_KEY 0xA3
|
||||||
#define SCSIOP_REPORT_KEY 0xA4
|
#define SCSIOP_REPORT_KEY 0xA4
|
||||||
|
@ -1393,6 +1411,9 @@ typedef struct _SENSE_DATA {
|
||||||
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE ((FILE_DEVICE_SCSI << 16) + 0x0507)
|
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE ((FILE_DEVICE_SCSI << 16) + 0x0507)
|
||||||
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES ((FILE_DEVICE_SCSI << 16) + 0x0508)
|
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES ((FILE_DEVICE_SCSI << 16) + 0x0508)
|
||||||
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS ((FILE_DEVICE_SCSI << 16) + 0x0509)
|
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS ((FILE_DEVICE_SCSI << 16) + 0x0509)
|
||||||
|
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE ((FILE_DEVICE_SCSI << 16) + 0x050a)
|
||||||
|
#define IOCTL_SCSI_MINIPORT_READ_SMART_LOG ((FILE_DEVICE_SCSI << 16) + 0x050b)
|
||||||
|
#define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG ((FILE_DEVICE_SCSI << 16) + 0x050c)
|
||||||
|
|
||||||
// Read Capacity Data - returned in Big Endian format
|
// Read Capacity Data - returned in Big Endian format
|
||||||
|
|
||||||
|
@ -2902,6 +2923,12 @@ typedef struct _DVD_RPC_KEY {
|
||||||
UCHAR Reserved2[1];
|
UCHAR Reserved2[1];
|
||||||
} DVD_RPC_KEY, * PDVD_RPC_KEY;
|
} DVD_RPC_KEY, * PDVD_RPC_KEY;
|
||||||
|
|
||||||
|
typedef struct _REPORT_LUNS_INFO_HDR {
|
||||||
|
UCHAR ListLength[4];
|
||||||
|
UCHAR Reserved[4];
|
||||||
|
} REPORT_LUNS_INFO_HDR, *PREPORT_LUNS_INFO_HDR;
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#endif //__CDRW_DEVICE_H__
|
#endif //__CDRW_DEVICE_H__
|
||||||
|
|
|
@ -251,4 +251,7 @@
|
||||||
156.use http://www.winimage.com/readfi15.zip for performance checks
|
156.use http://www.winimage.com/readfi15.zip for performance checks
|
||||||
157.use IOCTL_SCSI_MINIPORT_IDENTIFY in atactl.exe to determine ...
|
157.use IOCTL_SCSI_MINIPORT_IDENTIFY in atactl.exe to determine ...
|
||||||
PIO/DMA when no uniata.sys is installed (+++)
|
PIO/DMA when no uniata.sys is installed (+++)
|
||||||
158.
|
158.implement .INF generator
|
||||||
|
159.fix bug with invalid INF section under XP+ (43e2)
|
||||||
|
160.add INF handler for SCSI\NET\VEN_UNIATA&PROD_MANAGEMENT_PORT
|
||||||
|
161.
|
|
@ -204,8 +204,14 @@ typedef struct _ATA_PASS_THROUGH_DIRECT {
|
||||||
ULONG TimeOutValue;
|
ULONG TimeOutValue;
|
||||||
ULONG ReservedAsUlong;
|
ULONG ReservedAsUlong;
|
||||||
PVOID DataBuffer;
|
PVOID DataBuffer;
|
||||||
|
union {
|
||||||
UCHAR PreviousTaskFile[8];
|
UCHAR PreviousTaskFile[8];
|
||||||
|
IDEREGS Regs;
|
||||||
|
};
|
||||||
|
union {
|
||||||
UCHAR CurrentTaskFile[8];
|
UCHAR CurrentTaskFile[8];
|
||||||
|
IDEREGS RegsH;
|
||||||
|
};
|
||||||
} ATA_PASS_THROUGH_DIRECT, *PATA_PASS_THROUGH_DIRECT;
|
} ATA_PASS_THROUGH_DIRECT, *PATA_PASS_THROUGH_DIRECT;
|
||||||
|
|
||||||
#define ATA_FLAGS_DRDY_REQUIRED 0x01 // Wait for DRDY status from the device before sending the command to the device.
|
#define ATA_FLAGS_DRDY_REQUIRED 0x01 // Wait for DRDY status from the device before sending the command to the device.
|
||||||
|
@ -214,6 +220,8 @@ typedef struct _ATA_PASS_THROUGH_DIRECT {
|
||||||
#define ATA_FLAGS_48BIT_COMMAND 0x08 // The ATA command to be send uses the 48 bit LBA feature set.
|
#define ATA_FLAGS_48BIT_COMMAND 0x08 // The ATA command to be send uses the 48 bit LBA feature set.
|
||||||
// When this flag is set, the contents of the PreviousTaskFile member in the
|
// When this flag is set, the contents of the PreviousTaskFile member in the
|
||||||
// ATA_PASS_THROUGH_DIRECT structure should be valid.
|
// ATA_PASS_THROUGH_DIRECT structure should be valid.
|
||||||
|
#define ATA_FLAGS_USE_DMA 0x10 // Set the transfer mode to DMA.
|
||||||
|
#define ATA_FLAGS_NO_MULTIPLE 0x20 // Read single sector only.
|
||||||
|
|
||||||
#endif //ATA_FLAGS_DRDY_REQUIRED
|
#endif //ATA_FLAGS_DRDY_REQUIRED
|
||||||
|
|
||||||
|
@ -221,13 +229,19 @@ typedef struct _ATA_PASS_THROUGH_DIRECT {
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
typedef struct _IDEREGS_EX {
|
typedef struct _IDEREGS_EX {
|
||||||
UCHAR bFeaturesReg; // Used for specifying SMART "commands".
|
union {
|
||||||
|
UCHAR bFeaturesReg; // Used for specifying SMART "commands" on input.
|
||||||
|
UCHAR bErrorReg; // Error on output.
|
||||||
|
};
|
||||||
UCHAR bSectorCountReg; // IDE sector count register
|
UCHAR bSectorCountReg; // IDE sector count register
|
||||||
UCHAR bSectorNumberReg; // IDE sector number register
|
UCHAR bSectorNumberReg; // IDE sector number register
|
||||||
UCHAR bCylLowReg; // IDE low order cylinder value
|
UCHAR bCylLowReg; // IDE low order cylinder value
|
||||||
UCHAR bCylHighReg; // IDE high order cylinder value
|
UCHAR bCylHighReg; // IDE high order cylinder value
|
||||||
UCHAR bDriveHeadReg; // IDE drive/head register
|
UCHAR bDriveHeadReg; // IDE drive/head register
|
||||||
|
union {
|
||||||
UCHAR bCommandReg; // Actual IDE command.
|
UCHAR bCommandReg; // Actual IDE command.
|
||||||
|
UCHAR bStatusReg; // Status register.
|
||||||
|
};
|
||||||
UCHAR bOpFlags; // 00 - send
|
UCHAR bOpFlags; // 00 - send
|
||||||
// 01 - read regs
|
// 01 - read regs
|
||||||
// 08 - lba48
|
// 08 - lba48
|
||||||
|
@ -236,9 +250,12 @@ typedef struct _IDEREGS_EX {
|
||||||
#define UNIATA_SPTI_EX_SND 0x00
|
#define UNIATA_SPTI_EX_SND 0x00
|
||||||
#define UNIATA_SPTI_EX_RCV 0x01
|
#define UNIATA_SPTI_EX_RCV 0x01
|
||||||
#define UNIATA_SPTI_EX_LBA48 0x08
|
#define UNIATA_SPTI_EX_LBA48 0x08
|
||||||
#define UNIATA_SPTI_EX_SPEC_TO 0x10
|
//#define UNIATA_SPTI_EX_SPEC_TO 0x10
|
||||||
//#define UNIATA_SPTI_EX_FREEZE_TO 0x20 // do not reset device on timeout and keep interrupts disabled
|
//#define UNIATA_SPTI_EX_FREEZE_TO 0x20 // do not reset device on timeout and keep interrupts disabled
|
||||||
#define UNIATA_SPTI_EX_USE_DMA 0x20 // Force DMA transfer mode
|
#define UNIATA_SPTI_EX_USE_DMA 0x10 // Force DMA transfer mode
|
||||||
|
|
||||||
|
// use 'invalid' combination to specify special TO options
|
||||||
|
#define UNIATA_SPTI_EX_SPEC_TO (ATA_FLAGS_DATA_OUT | ATA_FLAGS_DATA_IN)
|
||||||
|
|
||||||
UCHAR bFeaturesRegH; // feature (high part for LBA48 mode)
|
UCHAR bFeaturesRegH; // feature (high part for LBA48 mode)
|
||||||
UCHAR bSectorCountRegH; // IDE sector count register (high part for LBA48 mode)
|
UCHAR bSectorCountRegH; // IDE sector count register (high part for LBA48 mode)
|
||||||
|
@ -288,6 +305,19 @@ typedef struct _UNIATA_CTL {
|
||||||
};
|
};
|
||||||
} UNIATA_CTL, *PUNIATA_CTL;
|
} UNIATA_CTL, *PUNIATA_CTL;
|
||||||
|
|
||||||
|
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
|
||||||
|
SCSI_PASS_THROUGH spt;
|
||||||
|
ULONG Filler; // realign buffers to double word boundary
|
||||||
|
UCHAR ucSenseBuf[32];
|
||||||
|
UCHAR ucDataBuf[512]; // recommended minimum
|
||||||
|
} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
|
||||||
|
|
||||||
|
typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER {
|
||||||
|
SCSI_PASS_THROUGH_DIRECT sptd;
|
||||||
|
ULONG Filler; // realign buffer to double word boundary
|
||||||
|
UCHAR ucSenseBuf[32];
|
||||||
|
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
||||||
|
|
||||||
#endif //UNIATA_CORE
|
#endif //UNIATA_CORE
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#define UNIATA_VER_STR "42i2"
|
#define UNIATA_VER_STR "43f5"
|
||||||
#define UNIATA_VER_DOT 0.42.9.2
|
#define UNIATA_VER_DOT 0.43.6.5
|
||||||
#define UNIATA_VER_MJ 0
|
#define UNIATA_VER_MJ 0
|
||||||
#define UNIATA_VER_MN 42
|
#define UNIATA_VER_MN 43
|
||||||
#define UNIATA_VER_SUB_MJ 9
|
#define UNIATA_VER_SUB_MJ 6
|
||||||
#define UNIATA_VER_SUB_MN 2
|
#define UNIATA_VER_SUB_MN 5
|
||||||
#define UNIATA_VER_DOT_COMMA 0,42,9,2
|
#define UNIATA_VER_DOT_COMMA 0,43,6,5
|
||||||
#define UNIATA_VER_DOT_STR "0.42.9.2"
|
#define UNIATA_VER_DOT_STR "0.43.6.5"
|
||||||
#define UNIATA_VER_YEAR 2012
|
#define UNIATA_VER_YEAR 2012
|
||||||
#define UNIATA_VER_YEAR_STR "2012"
|
#define UNIATA_VER_YEAR_STR "2012"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue