mirror of
https://github.com/reactos/reactos.git
synced 2024-11-24 03:53:31 +08:00
[UNIATA]: Sync to 0.43f5.
[ATACTL]: Sync to 0.43f5. svn path=/trunk/; revision=57265
This commit is contained in:
parent
583fb33611
commit
deaba45849
@ -39,6 +39,13 @@ char* g_bb_list = NULL;
|
||||
int gRadix = 16;
|
||||
PADAPTERINFO g_AdapterInfo = NULL;
|
||||
|
||||
BOOLEAN
|
||||
ata_power_mode(
|
||||
int bus_id,
|
||||
int dev_id,
|
||||
int power_mode
|
||||
);
|
||||
|
||||
void print_help() {
|
||||
printf("Usage:\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"
|
||||
" for %d seconds if no lock timeout specified.\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"
|
||||
" ba (A)ssign (B)ad-block list\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_RESET 0x05
|
||||
#define CMD_ATA_BBLK 0x06
|
||||
#define CMD_ATA_POWER 0x07
|
||||
|
||||
HANDLE
|
||||
ata_open_dev(
|
||||
@ -304,6 +318,76 @@ ata_send_ioctl(
|
||||
return TRUE;
|
||||
} // 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;
|
||||
UCHAR g_inquiry_buffer[2048];
|
||||
|
||||
@ -535,9 +619,10 @@ ata_check_unit(
|
||||
GETTRANSFERMODE IoMode;
|
||||
PSENDCMDOUTPARAMS pout;
|
||||
PIDENTIFY_DATA ident;
|
||||
PINQUIRYDATA scsi_ident;
|
||||
char buff[sizeof(SENDCMDOUTPARAMS)+/*sizeof(IDENTIFY_DATA)*/2048];
|
||||
char mode_str[12];
|
||||
ULONG bus_id = (dev_id >> 24) & 0xff;
|
||||
//ULONG bus_id = (dev_id >> 24) & 0xff;
|
||||
BOOLEAN found = FALSE;
|
||||
SENDCMDINPARAMS pin;
|
||||
int io_mode = -1;
|
||||
@ -546,7 +631,7 @@ ata_check_unit(
|
||||
char lun_str[10];
|
||||
HKEY hKey2;
|
||||
ULONGLONG max_lba = -1;
|
||||
USHORT chs[3];
|
||||
USHORT chs[3] = { 0 };
|
||||
|
||||
if(dev_id != -1) {
|
||||
dev_id &= 0x00ffffff;
|
||||
@ -594,7 +679,7 @@ ata_check_unit(
|
||||
} else {
|
||||
mode_str[0] = 0;
|
||||
}
|
||||
printf(" b%u [%s]\n",
|
||||
printf(" b%lu [%s]\n",
|
||||
i,
|
||||
mode_str
|
||||
);
|
||||
@ -617,7 +702,8 @@ ata_check_unit(
|
||||
|
||||
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
|
||||
goto next_dev;
|
||||
}
|
||||
@ -685,29 +771,27 @@ ata_check_unit(
|
||||
|
||||
}
|
||||
|
||||
if(status) {
|
||||
if(!g_extended) {
|
||||
printf(" b%u:d%d%s %24.24s %4.4s ",
|
||||
i,
|
||||
inquiryData->TargetId,
|
||||
lun_str,
|
||||
/*(inquiryData->DeviceClaimed) ? "Y" : "N",*/
|
||||
(g_extended ? (PUCHAR)"" : &inquiryData->InquiryData[8]),
|
||||
(g_extended ? (PUCHAR)"" : &inquiryData->InquiryData[8+24])
|
||||
);
|
||||
} else {
|
||||
printf(" b%u:d%d%s ",
|
||||
i,
|
||||
inquiryData->TargetId,
|
||||
lun_str
|
||||
);
|
||||
}
|
||||
if(io_mode == -1) {
|
||||
io_mode = ata_cur_mode_from_ident(ident);
|
||||
}
|
||||
if(!g_extended) {
|
||||
printf(" b%lu:d%d%s %24.24s %4.4s ",
|
||||
i,
|
||||
inquiryData->TargetId,
|
||||
lun_str,
|
||||
/*(inquiryData->DeviceClaimed) ? "Y" : "N",*/
|
||||
(g_extended ? (PUCHAR)"" : &scsi_ident->VendorId[0]),
|
||||
(g_extended ? (PUCHAR)"" : &scsi_ident->ProductRevisionLevel[0])
|
||||
);
|
||||
} else {
|
||||
goto next_dev;
|
||||
printf(" b%lu:d%d%s ",
|
||||
i,
|
||||
inquiryData->TargetId,
|
||||
lun_str
|
||||
);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
if(io_mode == -1) {
|
||||
io_mode = ata_cur_mode_from_ident(ident, IDENT_MODE_ACTIVE);
|
||||
}
|
||||
}
|
||||
if(io_mode != -1) {
|
||||
ata_mode_to_str(mode_str, io_mode);
|
||||
@ -725,100 +809,139 @@ ata_check_unit(
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if(status && g_extended) {
|
||||
if(g_extended) {
|
||||
if(status) {
|
||||
|
||||
BOOLEAN BlockMode_valid = TRUE;
|
||||
BOOLEAN print_geom = FALSE;
|
||||
BOOLEAN BlockMode_valid = TRUE;
|
||||
BOOLEAN print_geom = FALSE;
|
||||
|
||||
switch(ident->DeviceType) {
|
||||
case ATAPI_TYPE_DIRECT:
|
||||
if(ident->Removable) {
|
||||
printf(" Floppy ");
|
||||
} else {
|
||||
switch(ident->DeviceType) {
|
||||
case ATAPI_TYPE_DIRECT:
|
||||
if(ident->Removable) {
|
||||
printf(" Floppy ");
|
||||
} else {
|
||||
printf(" Hard Drive ");
|
||||
}
|
||||
break;
|
||||
case ATAPI_TYPE_TAPE:
|
||||
printf(" Tape Drive ");
|
||||
break;
|
||||
case ATAPI_TYPE_CDROM:
|
||||
printf(" CD/DVD Drive ");
|
||||
BlockMode_valid = FALSE;
|
||||
break;
|
||||
case ATAPI_TYPE_OPTICAL:
|
||||
printf(" Optical Drive ");
|
||||
BlockMode_valid = FALSE;
|
||||
break;
|
||||
default:
|
||||
printf(" Hard Drive ");
|
||||
print_geom = TRUE;
|
||||
//MOV_DD_SWP(max_lba, ident->UserAddressableSectors);
|
||||
max_lba = ident->UserAddressableSectors;
|
||||
if(ident->FeaturesSupport.Address48) {
|
||||
max_lba = ident->UserAddressableSectors48;
|
||||
}
|
||||
//MOV_DW_SWP(chs[0], ident->NumberOfCylinders);
|
||||
//MOV_DW_SWP(chs[1], ident->NumberOfHeads);
|
||||
//MOV_DW_SWP(chs[2], ident->SectorsPerTrack);
|
||||
chs[0] = ident->NumberOfCylinders;
|
||||
chs[1] = ident->NumberOfHeads;
|
||||
chs[2] = ident->SectorsPerTrack;
|
||||
if(!max_lba) {
|
||||
max_lba = (ULONG)(chs[0])*(ULONG)(chs[1])*(ULONG)(chs[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ATAPI_TYPE_TAPE:
|
||||
printf(" Tape Drive ");
|
||||
break;
|
||||
case ATAPI_TYPE_CDROM:
|
||||
printf(" CD/DVD Drive ");
|
||||
BlockMode_valid = FALSE;
|
||||
break;
|
||||
case ATAPI_TYPE_OPTICAL:
|
||||
printf(" Optical Drive ");
|
||||
BlockMode_valid = FALSE;
|
||||
break;
|
||||
default:
|
||||
printf(" Hard Drive ");
|
||||
print_geom = 1;
|
||||
//MOV_DD_SWP(max_lba, ident->UserAddressableSectors);
|
||||
max_lba = ident->UserAddressableSectors;
|
||||
if(ident->FeaturesSupport.Address48) {
|
||||
max_lba = ident->UserAddressableSectors48;
|
||||
if(io_mode != -1) {
|
||||
printf(" %.12s\n", mode_str);
|
||||
}
|
||||
//MOV_DW_SWP(chs[0], ident->NumberOfCylinders);
|
||||
//MOV_DW_SWP(chs[1], ident->NumberOfHeads);
|
||||
//MOV_DW_SWP(chs[2], ident->SectorsPerTrack);
|
||||
chs[0] = ident->NumberOfCylinders;
|
||||
chs[1] = ident->NumberOfHeads;
|
||||
chs[2] = ident->SectorsPerTrack;
|
||||
if(!max_lba) {
|
||||
max_lba = (ULONG)(chs[0])*(ULONG)(chs[1])*(ULONG)(chs[2]);
|
||||
for (j = 0; j < 40; j += 2) {
|
||||
MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->ModelNumber)[j]);
|
||||
}
|
||||
}
|
||||
if(io_mode != -1) {
|
||||
printf(" %.12s\n", mode_str);
|
||||
}
|
||||
for (j = 0; j < 40; j += 2) {
|
||||
MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->ModelNumber)[j]);
|
||||
}
|
||||
printf(" Mod: %40.40s\n", SerNum);
|
||||
for (j = 0; j < 8; j += 2) {
|
||||
MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->FirmwareRevision)[j]);
|
||||
}
|
||||
printf(" Rev: %8.8s\n", SerNum);
|
||||
for (j = 0; j < 20; j += 2) {
|
||||
MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->SerialNumber)[j]);
|
||||
}
|
||||
printf(" S/N: %20.20s\n", SerNum);
|
||||
printf(" Mod: %40.40s\n", SerNum);
|
||||
for (j = 0; j < 8; j += 2) {
|
||||
MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->FirmwareRevision)[j]);
|
||||
}
|
||||
printf(" Rev: %8.8s\n", SerNum);
|
||||
for (j = 0; j < 20; j += 2) {
|
||||
MOV_DW_SWP(SerNum[j], ((PUCHAR)ident->SerialNumber)[j]);
|
||||
}
|
||||
printf(" S/N: %20.20s\n", SerNum);
|
||||
|
||||
if(BlockMode_valid) {
|
||||
if(ident->MaximumBlockTransfer) {
|
||||
printf(" Multi-block mode: %u block%s\n", ident->MaximumBlockTransfer, ident->MaximumBlockTransfer == 1 ? "" : "s");
|
||||
} else {
|
||||
printf(" Multi-block mode: N/A\n");
|
||||
if(BlockMode_valid) {
|
||||
if(ident->MaximumBlockTransfer) {
|
||||
printf(" Multi-block mode: %u block%s\n", ident->MaximumBlockTransfer, ident->MaximumBlockTransfer == 1 ? "" : "s");
|
||||
} else {
|
||||
printf(" Multi-block mode: N/A\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(print_geom) {
|
||||
printf(" C/H/S: %u/%u/%u \n", chs[0], chs[1], chs[2]);
|
||||
printf(" LBA: %I64u \n", max_lba);
|
||||
if(max_lba < 2) {
|
||||
printf(" Size: %u kb\n", max_lba/2);
|
||||
} else
|
||||
if(max_lba < 2*1024*1024) {
|
||||
printf(" Size: %u Mb\n", max_lba/2048);
|
||||
} else
|
||||
if(max_lba < (ULONG)2*1024*1024*1024) {
|
||||
printf(" Size: %u.%u (%u) Gb\n", (ULONG)(max_lba/2048/1024),
|
||||
(ULONG)(((max_lba/2048)%1024)/10),
|
||||
(ULONG)(max_lba*512/1000/1000/1000)
|
||||
);
|
||||
} else {
|
||||
printf(" Size: %u.%u (%u) Tb\n", (ULONG)(max_lba/2048/1024/1024),
|
||||
(ULONG)((max_lba/2048/1024)%1024)/10,
|
||||
(ULONG)(max_lba*512/1000/1000/1000)
|
||||
);
|
||||
if(print_geom) {
|
||||
printf(" C/H/S: %u/%u/%u \n", chs[0], chs[1], chs[2]);
|
||||
printf(" LBA: %I64u \n", max_lba);
|
||||
if(max_lba < 2) {
|
||||
printf(" Size: %lu kb\n", (ULONG)(max_lba/2));
|
||||
} else
|
||||
if(max_lba < 2*1024*1024) {
|
||||
printf(" Size: %lu Mb\n", (ULONG)(max_lba/2048));
|
||||
} else
|
||||
if(max_lba < (ULONG)2*1024*1024*1024) {
|
||||
printf(" Size: %lu.%lu (%lu) Gb\n", (ULONG)(max_lba/2048/1024),
|
||||
(ULONG)(((max_lba/2048)%1024)/10),
|
||||
(ULONG)(max_lba*512/1000/1000/1000)
|
||||
);
|
||||
} else {
|
||||
printf(" Size: %lu.%lu (%lu) Tb\n", (ULONG)(max_lba/2048/1024/1024),
|
||||
(ULONG)((max_lba/2048/1024)%1024)/10,
|
||||
(ULONG)(max_lba*512/1000/1000/1000)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
len = 0;
|
||||
if(hKey2 = ata_get_bblist_regh(ident, DevSerial, TRUE)) {
|
||||
if(RegQueryValueEx(hKey2, DevSerial, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
|
||||
printf(" !!! Assigned bad-block list !!!\n");
|
||||
len = 0;
|
||||
if((hKey2 = ata_get_bblist_regh(ident, DevSerial, TRUE))) {
|
||||
if(RegQueryValueEx(hKey2, DevSerial, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
|
||||
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));
|
||||
}
|
||||
@ -887,7 +1010,7 @@ ata_adapter_info(
|
||||
} else {
|
||||
if(AdapterInfo->AdapterInterfaceType == PCIBus) {
|
||||
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->AdapterInterfaceType == AdapterInfo->OrigAdapterInterfaceType ? "" : " (ISA-Bridged)");
|
||||
printf(" VendorId/DevId/Rev: %#04x/%#04x/%#02x\n",
|
||||
@ -901,7 +1024,7 @@ ata_adapter_info(
|
||||
if(AdapterInfo->AdapterInterfaceType == Isa) {
|
||||
printf(" ISA Bus\n");
|
||||
}
|
||||
printf(" IRQ: %d\n", AdapterInfo->BusInterruptLevel);
|
||||
printf(" IRQ: %ld\n", AdapterInfo->BusInterruptLevel);
|
||||
}
|
||||
}
|
||||
ata_close_dev(h);
|
||||
@ -1060,7 +1183,8 @@ ata_hide(
|
||||
int bus_id,
|
||||
int dev_id,
|
||||
int lock,
|
||||
int persistent_hide
|
||||
int persistent_hide,
|
||||
int power_mode
|
||||
)
|
||||
{
|
||||
char dev_name[64];
|
||||
@ -1073,6 +1197,11 @@ ata_hide(
|
||||
if(dev_id == -1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(power_mode) {
|
||||
ata_power_mode(bus_id, dev_id, power_mode);
|
||||
}
|
||||
|
||||
if(lock < 0) {
|
||||
lock = DEFAULT_REMOVAL_LOCK_TIMEOUT;
|
||||
}
|
||||
@ -1261,7 +1390,7 @@ ata_bblk(
|
||||
}
|
||||
|
||||
len = GetFileSize(hf, NULL);
|
||||
if(!len || len == -1)
|
||||
if(!len || len == INVALID_FILE_SIZE)
|
||||
goto exit;
|
||||
bblist = (char*)GlobalAlloc(GMEM_FIXED, len*8);
|
||||
}
|
||||
@ -1310,7 +1439,7 @@ ata_bblk(
|
||||
j++;
|
||||
BB_Msg[sizeof(BB_Msg)-1] = 0;
|
||||
k=0;
|
||||
while(a = BB_Msg[k]) {
|
||||
while((a = BB_Msg[k])) {
|
||||
if(a == ' ' || a == '\t' || a == '\r') {
|
||||
k++;
|
||||
continue;
|
||||
@ -1329,7 +1458,7 @@ ata_bblk(
|
||||
continue;
|
||||
}
|
||||
k0 = k;
|
||||
while(a = BB_Msg[k]) {
|
||||
while((a = BB_Msg[k])) {
|
||||
if(a == ' ' || a == '\t' || a == '\r') {
|
||||
BB_Msg[k] = '\t';
|
||||
}
|
||||
@ -1480,6 +1609,52 @@ exit:
|
||||
return retval;
|
||||
} // 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
|
||||
ata_num_to_x_dev(
|
||||
char a
|
||||
@ -1496,7 +1671,7 @@ main (
|
||||
char* argv[]
|
||||
)
|
||||
{
|
||||
ULONG Flags = 0;
|
||||
//ULONG Flags = 0;
|
||||
int i, j;
|
||||
char a;
|
||||
int bus_id = -1;
|
||||
@ -1507,6 +1682,7 @@ main (
|
||||
int mode=-1;
|
||||
int list_bb=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"
|
||||
"Version 0." UNIATA_VER_STR ", Copyright (c) Alexander A. Telyatnikov, 2003-2012\n"
|
||||
@ -1516,7 +1692,7 @@ main (
|
||||
if(!argv[i])
|
||||
continue;
|
||||
if((a = argv[i][0]) != '-') {
|
||||
for(j=0; a = argv[i][j]; j++) {
|
||||
for(j=0; (a = argv[i][j]); j++) {
|
||||
switch(a) {
|
||||
case 'a' :
|
||||
case 's' :
|
||||
@ -1630,10 +1806,47 @@ main (
|
||||
g_bb_list=argv[i];
|
||||
j = strlen(argv[i])-1;
|
||||
break;
|
||||
case 'd' :
|
||||
case 'p' :
|
||||
if(cmd && (cmd != CMD_ATA_FIND) && (cmd != CMD_ATA_HIDE)) {
|
||||
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++;
|
||||
if(!argv[i]) {
|
||||
print_help();
|
||||
@ -1699,10 +1912,13 @@ main (
|
||||
ata_scan(bus_id, dev_id, lock, persistent_hide);
|
||||
} else
|
||||
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
|
||||
if(cmd == CMD_ATA_BBLK) {
|
||||
ata_bblk(bus_id, dev_id, list_bb);
|
||||
} else
|
||||
if(cmd == CMD_ATA_POWER) {
|
||||
ata_power_mode(bus_id, dev_id, power_mode);
|
||||
} else {
|
||||
print_help();
|
||||
}
|
||||
|
@ -387,7 +387,9 @@ typedef struct _MODE_PARAMETER_HEADER_10 {
|
||||
#define IDE_COMMAND_DOOR_LOCK 0xDE
|
||||
#define IDE_COMMAND_DOOR_UNLOCK 0xDF
|
||||
#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_IDLE 0xE3
|
||||
#define IDE_COMMAND_READ_PM 0xE4 // SATA PM
|
||||
#define IDE_COMMAND_SLEEP 0xE6 // flush, spin down and deactivate interface
|
||||
#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_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
|
||||
//
|
||||
@ -920,6 +941,7 @@ typedef struct _IDENTIFY_DATA {
|
||||
union {
|
||||
USHORT Integrity; // 255
|
||||
struct {
|
||||
#define ATA_ChecksumValid 0xA5
|
||||
USHORT ChecksumValid:8;
|
||||
USHORT Checksum:8;
|
||||
};
|
||||
@ -1538,12 +1560,17 @@ ata_is_sata(
|
||||
return (ident->SataCapabilities && ident->SataCapabilities != 0xffff);
|
||||
} // end ata_is_sata()
|
||||
|
||||
#define IDENT_MODE_MAX FALSE
|
||||
#define IDENT_MODE_ACTIVE TRUE
|
||||
|
||||
__inline
|
||||
LONG
|
||||
ata_cur_mode_from_ident(
|
||||
PIDENTIFY_DATA ident
|
||||
PIDENTIFY_DATA ident,
|
||||
BOOLEAN Active
|
||||
)
|
||||
{
|
||||
USHORT mode;
|
||||
if(ata_is_sata(ident)) {
|
||||
if(ident->SataCapabilities & ATA_SATA_GEN3) {
|
||||
return ATA_SA600;
|
||||
@ -1558,22 +1585,24 @@ ata_cur_mode_from_ident(
|
||||
}
|
||||
|
||||
if (ident->UdmaModesValid) {
|
||||
if (ident->UltraDMAActive & 0x40)
|
||||
mode = Active ? ident->UltraDMAActive : ident->UltraDMASupport;
|
||||
if (mode & 0x40)
|
||||
return ATA_UDMA0+6;
|
||||
if (ident->UltraDMAActive & 0x20)
|
||||
if (mode & 0x20)
|
||||
return ATA_UDMA0+5;
|
||||
if (ident->UltraDMAActive & 0x10)
|
||||
if (mode & 0x10)
|
||||
return ATA_UDMA0+4;
|
||||
if (ident->UltraDMAActive & 0x08)
|
||||
if (mode & 0x08)
|
||||
return ATA_UDMA0+3;
|
||||
if (ident->UltraDMAActive & 0x04)
|
||||
if (mode & 0x04)
|
||||
return ATA_UDMA0+2;
|
||||
if (ident->UltraDMAActive & 0x02)
|
||||
if (mode & 0x02)
|
||||
return ATA_UDMA0+1;
|
||||
if (ident->UltraDMAActive & 0x01)
|
||||
if (mode & 0x01)
|
||||
return ATA_UDMA0+0;
|
||||
}
|
||||
|
||||
mode = Active ? ident->MultiWordDMAActive : ident->MultiWordDMASupport;
|
||||
if (ident->MultiWordDMAActive & 0x04)
|
||||
return ATA_WDMA0+2;
|
||||
if (ident->MultiWordDMAActive & 0x02)
|
||||
@ -1581,6 +1610,7 @@ ata_cur_mode_from_ident(
|
||||
if (ident->MultiWordDMAActive & 0x01)
|
||||
return ATA_WDMA0+0;
|
||||
|
||||
mode = Active ? ident->SingleWordDMAActive : ident->SingleWordDMASupport;
|
||||
if (ident->SingleWordDMAActive & 0x04)
|
||||
return ATA_SDMA0+2;
|
||||
if (ident->SingleWordDMAActive & 0x02)
|
||||
@ -1589,13 +1619,15 @@ ata_cur_mode_from_ident(
|
||||
return ATA_SDMA0+0;
|
||||
|
||||
if (ident->PioTimingsValid) {
|
||||
if (ident->AdvancedPIOModes & AdvancedPIOModes_5)
|
||||
mode = ident->AdvancedPIOModes;
|
||||
if (mode & AdvancedPIOModes_5)
|
||||
return ATA_PIO0+5;
|
||||
if (ident->AdvancedPIOModes & AdvancedPIOModes_4)
|
||||
if (mode & AdvancedPIOModes_4)
|
||||
return ATA_PIO0+4;
|
||||
if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
|
||||
if (mode & AdvancedPIOModes_3)
|
||||
return ATA_PIO0+3;
|
||||
}
|
||||
}
|
||||
mode = ident->PioCycleTimingMode;
|
||||
if (ident->PioCycleTimingMode == 2)
|
||||
return ATA_PIO0+2;
|
||||
if (ident->PioCycleTimingMode == 1)
|
||||
|
@ -50,11 +50,12 @@ Revision History:
|
||||
#ifndef __IDE_BUSMASTER_DEVICES_H__
|
||||
#define __IDE_BUSMASTER_DEVICES_H__
|
||||
|
||||
#ifdef USER_MODE
|
||||
/*#ifdef USER_MODE
|
||||
#define PVEN_STR PCSTR
|
||||
#else // USER_MODE
|
||||
#define PVEN_STR PCHAR
|
||||
#endif // USER_MODE
|
||||
#endif // USER_MODE*/
|
||||
#define PVEN_STR PCSTR
|
||||
|
||||
typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||
PVEN_STR VendorId;
|
||||
@ -76,15 +77,18 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||
CHAR MasterDev;
|
||||
BOOLEAN Known;
|
||||
#ifndef USER_MODE
|
||||
CHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary
|
||||
UCHAR ChanInitOk; // 0x01 - primary, 0x02 - secondary, 0x80 - PciIde claimed
|
||||
BOOLEAN Isr2Enable;
|
||||
PDEVICE_OBJECT Isr2DevObj;
|
||||
union {
|
||||
PDEVICE_OBJECT Isr2DevObj;
|
||||
PDEVICE_OBJECT PciIdeDevObj;
|
||||
};
|
||||
KIRQL Isr2Irql;
|
||||
KAFFINITY Isr2Affinity;
|
||||
ULONG Isr2Vector;
|
||||
PKINTERRUPT Isr2InterruptObject;
|
||||
CHAR AltInitMasterDev; // 0xff - uninitialized, 0x00 - normal, 0x01 - change ISA to PCI
|
||||
CHAR NeedAltInit; // 0x01 - try change ISA to PCI
|
||||
CHAR NeedAltInit; // 0x01 - try change ISA to PCI
|
||||
#endif
|
||||
|
||||
}BUSMASTER_CONTROLLER_INFORMATION, *PBUSMASTER_CONTROLLER_INFORMATION;
|
||||
@ -634,7 +638,8 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
|
||||
#define ICH5 0x0200
|
||||
#define I6CH 0x0400
|
||||
#define I6CH2 0x0800
|
||||
#define I1CH 0x1000
|
||||
//#define I1CH 0x1000 // obsolete
|
||||
#define ICH7 0x1000
|
||||
|
||||
#define NV4OFF 0x0100
|
||||
#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( 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( 84ca, 8086, 0x00, ATA_UDMA2, "Intel PIIX4" , 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( 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( 27c0, 8086, 0x00, ATA_SA300, "Intel ICH7 S1" , UNIATA_SATA ),
|
||||
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" , ICH7 | UNIATA_SATA ),
|
||||
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( 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( 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( 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 ),
|
||||
@ -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( 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( 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( 2926, 8086, 0x00, ATA_SA300, "Intel ICH9" , I6CH2 | UNIATA_SATA ),
|
||||
@ -779,10 +784,10 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
|
||||
PCI_DEV_HW_SPEC_BM( 2923, 8086, 0x00, ATA_SA300, "Intel ICH9" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
PCI_DEV_HW_SPEC_BM( 2925, 8086, 0x00, ATA_SA300, "Intel ICH9" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
|
||||
PCI_DEV_HW_SPEC_BM( 2928, 8086, 0x00, ATA_SA300, "Intel ICH9M" , I6CH2 | UNIATA_SATA ),
|
||||
PCI_DEV_HW_SPEC_BM( 2929, 8086, 0x00, ATA_SA300, "Intel ICH9M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
PCI_DEV_HW_SPEC_BM( 292a, 8086, 0x00, ATA_SA300, "Intel ICH9M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
PCI_DEV_HW_SPEC_BM( 292d, 8086, 0x00, ATA_SA300, "Intel ICH9M" , I6CH2 | UNIATA_SATA ),
|
||||
PCI_DEV_HW_SPEC_BM( 2928, 8086, 0x00, ATA_SA300, "Intel ICH9M" , I6CH2 | UNIATA_SATA ),
|
||||
PCI_DEV_HW_SPEC_BM( 2929, 8086, 0x00, ATA_SA300, "Intel ICH9M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
PCI_DEV_HW_SPEC_BM( 292a, 8086, 0x00, ATA_SA300, "Intel ICH9M" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
PCI_DEV_HW_SPEC_BM( 292d, 8086, 0x00, ATA_SA300, "Intel ICH9M" , I6CH2 | UNIATA_SATA ),
|
||||
|
||||
PCI_DEV_HW_SPEC_BM( 3a20, 8086, 0x00, ATA_SA300, "Intel ICH10" , I6CH | UNIATA_SATA ),
|
||||
PCI_DEV_HW_SPEC_BM( 3a26, 8086, 0x00, ATA_SA300, "Intel ICH10" , 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( 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( 2360, 197b, 0x00, ATA_SA300, "JMB360" , UNIATA_SATA | UNIATA_AHCI ),
|
||||
|
@ -562,9 +562,9 @@ typedef struct _IDE_AHCI_PORT_REGISTERS {
|
||||
ULONG Reg; // signature
|
||||
struct {
|
||||
UCHAR SectorCount;
|
||||
UCHAR LbaLow;
|
||||
UCHAR LbaMid;
|
||||
UCHAR LbaHigh;
|
||||
UCHAR LbaLow; // IDX_IO1_i_BlockNumber
|
||||
UCHAR LbaMid; // IDX_IO1_i_CylinderLow
|
||||
UCHAR LbaHigh; // IDX_IO1_i_CylinderHigh
|
||||
};
|
||||
} SIG; // 0x100 + 0x80*c + 0x0024
|
||||
union {
|
||||
@ -1060,6 +1060,7 @@ typedef struct _HW_CHANNEL {
|
||||
#define CTRFLAGS_DSC_BSY 0x0080
|
||||
#define CTRFLAGS_NO_SLAVE 0x0100
|
||||
//#define CTRFLAGS_PATA 0x0200
|
||||
//#define CTRFLAGS_NOT_PRESENT 0x0200
|
||||
#define CTRFLAGS_AHCI_PM 0x0400
|
||||
#define CTRFLAGS_AHCI_PM2 0x0800
|
||||
|
||||
@ -1086,7 +1087,7 @@ typedef struct _HW_LU_EXTENSION {
|
||||
BOOLEAN DWordIO; // Indicates use of 32-bit PIO
|
||||
UCHAR ReturningMediaStatus;
|
||||
UCHAR MaximumBlockXfer;
|
||||
UCHAR Padding0[1]; // padding
|
||||
UCHAR PowerState;
|
||||
|
||||
UCHAR TransferMode; // current transfer mode
|
||||
UCHAR LimitedTransferMode; // user-defined or IDE cable limitation
|
||||
@ -1117,8 +1118,10 @@ typedef struct _HW_LU_EXTENSION {
|
||||
BOOLEAN opt_ReadCacheEnable;
|
||||
BOOLEAN opt_WriteCacheEnable;
|
||||
UCHAR opt_ReadOnly;
|
||||
// padding
|
||||
BOOLEAN opt_reserved[1];
|
||||
UCHAR opt_AdvPowerMode;
|
||||
UCHAR opt_AcousticMode;
|
||||
UCHAR opt_StandbyTimer;
|
||||
UCHAR opt_Padding[2]; // padding
|
||||
|
||||
struct _SBadBlockListItem* bbListDescr;
|
||||
struct _SBadBlockRange* arrBadBlocks;
|
||||
@ -1216,6 +1219,9 @@ typedef struct _HW_DEVICE_EXTENSION {
|
||||
BOOLEAN MasterDev;
|
||||
BOOLEAN Host64;
|
||||
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];
|
||||
|
||||
LONG ReCheckIntr;
|
||||
@ -1238,6 +1244,7 @@ typedef struct _HW_DEVICE_EXTENSION {
|
||||
IORES BaseIoAHCI_0;
|
||||
//PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
|
||||
ULONG AHCI_CAP;
|
||||
ULONG AHCI_PI;
|
||||
PATA_REQ AhciInternalAtaReq0;
|
||||
PSCSI_REQUEST_BLOCK AhciInternalSrb0;
|
||||
|
||||
@ -1260,6 +1267,9 @@ typedef struct _ISR2_DEVICE_EXTENSION {
|
||||
ULONG DevIndex;
|
||||
} 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_LBA48 0x02
|
||||
|
||||
@ -1268,6 +1278,7 @@ extern PBUSMASTER_CONTROLLER_INFORMATION BMList;
|
||||
extern ULONG BMListLen;
|
||||
extern ULONG IsaCount;
|
||||
extern ULONG MCACount;
|
||||
extern UNICODE_STRING SavedRegPath;
|
||||
|
||||
//extern const CHAR retry_Wdma[MAX_RETRIES+1];
|
||||
//extern const CHAR retry_Udma[MAX_RETRIES+1];
|
||||
@ -1322,14 +1333,10 @@ UniataFindBusMasterController(
|
||||
OUT PBOOLEAN Again
|
||||
);
|
||||
|
||||
extern ULONG NTAPI
|
||||
UniataFindFakeBusMasterController(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID Context,
|
||||
IN PVOID BusInformation,
|
||||
IN PCHAR ArgumentString,
|
||||
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
||||
OUT PBOOLEAN Again
|
||||
extern NTSTATUS
|
||||
NTAPI
|
||||
UniataClaimLegacyPCIIDE(
|
||||
ULONG i
|
||||
);
|
||||
|
||||
extern NTSTATUS
|
||||
@ -1508,6 +1515,14 @@ AtapiGetIoRange(
|
||||
IN ULONG length //range id
|
||||
);
|
||||
|
||||
extern USHORT
|
||||
NTAPI
|
||||
UniataEnableIoPCI(
|
||||
IN ULONG busNumber,
|
||||
IN ULONG slotNumber,
|
||||
IN OUT PPCI_COMMON_CONFIG pciData
|
||||
);
|
||||
|
||||
/****************** 1 *****************/
|
||||
#define GetPciConfig1(offs, op) { \
|
||||
ScsiPortGetBusDataByOffset(HwDeviceExtension, \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -944,19 +944,19 @@ AtapiDmaInit(
|
||||
}
|
||||
|
||||
// Limit transfer mode (controller limitation)
|
||||
if((LONG)deviceExtension->MaxTransferMode >= ATA_UDMA) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: deviceExtension->MaxTransferMode >= ATA_UDMA\n"));
|
||||
udmamode = min( udmamode, (CHAR)(deviceExtension->MaxTransferMode - ATA_UDMA));
|
||||
if((LONG)chan->MaxTransferMode >= ATA_UDMA) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: chan->MaxTransferMode >= ATA_UDMA\n"));
|
||||
udmamode = min( udmamode, (CHAR)(chan->MaxTransferMode - ATA_UDMA));
|
||||
} else
|
||||
if((LONG)deviceExtension->MaxTransferMode >= ATA_WDMA) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: deviceExtension->MaxTransferMode >= ATA_WDMA\n"));
|
||||
if((LONG)chan->MaxTransferMode >= ATA_WDMA) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: chan->MaxTransferMode >= ATA_WDMA\n"));
|
||||
udmamode = -1;
|
||||
wdmamode = min( wdmamode, (CHAR)(deviceExtension->MaxTransferMode - ATA_WDMA));
|
||||
wdmamode = min( wdmamode, (CHAR)(chan->MaxTransferMode - ATA_WDMA));
|
||||
} else
|
||||
if((LONG)deviceExtension->MaxTransferMode >= ATA_PIO0) {
|
||||
if((LONG)chan->MaxTransferMode >= ATA_PIO0) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: NO DMA\n"));
|
||||
wdmamode = udmamode = -1;
|
||||
apiomode = min( apiomode, (CHAR)(deviceExtension->MaxTransferMode - ATA_PIO0));
|
||||
apiomode = min( apiomode, (CHAR)(chan->MaxTransferMode - ATA_PIO0));
|
||||
} else {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: PIO0\n"));
|
||||
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)) {
|
||||
/****************/
|
||||
/* SATA Generic */
|
||||
/****************/
|
||||
|
||||
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 */
|
||||
/* ATAPI may not have SataCapabilities set in IDENTIFY DATA */
|
||||
if(ata_is_sata(&(LunExt->IdentifyData))) {
|
||||
@ -1024,7 +1026,7 @@ AtapiDmaInit(
|
||||
|
||||
} else {
|
||||
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"));
|
||||
udmamode = 2;
|
||||
apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO0));
|
||||
@ -1054,7 +1056,7 @@ AtapiDmaInit(
|
||||
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))) {
|
||||
KdPrint2((PRINT_PREFIX "AtapiDmaInit: SATA beyond adapter or Controller compat mode\n"));
|
||||
} else {
|
||||
@ -1384,6 +1386,7 @@ set_new_acard:
|
||||
UCHAR new44 = 0;
|
||||
UCHAR intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
|
||||
0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
|
||||
UCHAR intel_utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
|
||||
|
||||
if(deviceExtension->DevID == ATA_I82371FB) {
|
||||
if (wdmamode >= 2 && apiomode >= 4) {
|
||||
@ -1466,17 +1469,24 @@ set_new_acard:
|
||||
for(i=udmamode; i>=0; 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));
|
||||
if(!(ChipFlags & ICH4_FIX)) {
|
||||
SetPciConfig2(0x4a, (reg4a & ~(0x3 << (dev<<2))) |
|
||||
(0x01 + !(i & 0x01)) );
|
||||
if(deviceExtension->MaxTransferMode == ATA_UDMA3) {
|
||||
// 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);
|
||||
} else {
|
||||
reg54 &= ~(0x1 << dev);
|
||||
}
|
||||
/* Set UDMA reference clock (133 MHz). */
|
||||
if(i >= 5) {
|
||||
reg54 |= (0x1000 << dev);
|
||||
} else {
|
||||
|
@ -178,6 +178,7 @@ UniataChipDetectChannels(
|
||||
KdPrint2((PRINT_PREFIX "New ITE PATA 1 chan\n"));
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case ATA_INTEL_ID:
|
||||
/* New Intel PATA controllers */
|
||||
if(g_opt_VirtualMachine != VM_VBOX &&
|
||||
@ -193,6 +194,7 @@ UniataChipDetectChannels(
|
||||
KdPrint2((PRINT_PREFIX "New Intel PATA 1 chan\n"));
|
||||
}
|
||||
break;
|
||||
#endif // this code is removed from newer FreeBSD
|
||||
case ATA_JMICRON_ID:
|
||||
/* New JMicron PATA controllers */
|
||||
if(deviceExtension->DevID == ATA_JMB361 ||
|
||||
@ -1418,6 +1420,11 @@ generic_cable80(
|
||||
ULONG slotNumber = deviceExtension->slotNumber;
|
||||
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;
|
||||
PHW_CHANNEL chan;
|
||||
ULONG c; // logical channel (for Compatible Mode controllers)
|
||||
@ -1468,6 +1475,27 @@ UniAtaReadLunConfig(
|
||||
tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, DeviceNumber, L"PreferedTransferMode", 0xffffffff);
|
||||
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);
|
||||
if(tmp32 <= 2) {
|
||||
LunExt->opt_ReadOnly = (UCHAR)tmp32;
|
||||
@ -1623,6 +1651,7 @@ AtapiChipInit(
|
||||
ULONG tmp32;
|
||||
ULONG c; // logical channel (for Compatible Mode controllers)
|
||||
BOOLEAN CheckCable = FALSE;
|
||||
BOOLEAN GlobalInit = FALSE;
|
||||
//ULONG BaseIoAddress;
|
||||
|
||||
switch(channel) {
|
||||
@ -1631,6 +1660,7 @@ AtapiChipInit(
|
||||
/* FALLTHROUGH */
|
||||
case CHAN_NOT_SPECIFIED:
|
||||
c = CHAN_NOT_SPECIFIED;
|
||||
GlobalInit = TRUE;
|
||||
break;
|
||||
default:
|
||||
//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) {
|
||||
// case ATA_ACARD_ID:
|
||||
// break;
|
||||
@ -1778,8 +1829,16 @@ AtapiChipInit(
|
||||
KdPrint2((PRINT_PREFIX "Base init\n"));
|
||||
/* force all ports active "the legacy way" */
|
||||
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 */
|
||||
ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
|
||||
ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
|
||||
|
||||
} else {
|
||||
|
||||
@ -1867,7 +1926,7 @@ AtapiChipInit(
|
||||
|
||||
break;
|
||||
}
|
||||
if(deviceExtension->MaxTransferMode < ATA_UDMA2)
|
||||
if(deviceExtension->MaxTransferMode <= ATA_UDMA2)
|
||||
break;
|
||||
// check 80-pin cable
|
||||
if(c == CHAN_NOT_SPECIFIED) {
|
||||
@ -1875,7 +1934,12 @@ AtapiChipInit(
|
||||
} else {
|
||||
chan = &deviceExtension->chan[c];
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -2179,7 +2243,7 @@ AtapiChipInit(
|
||||
// no init for SATA
|
||||
if(ChipFlags & (UNIATA_SATA | VIASATA)) {
|
||||
/* 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
|
||||
@ -2238,6 +2302,8 @@ AtapiChipInit(
|
||||
// no init for SATA
|
||||
if(ChipFlags & (UNIATA_SATA | VIASATA)) {
|
||||
if((ChipFlags & VIABAR) && (c >= 2)) {
|
||||
// this is PATA channel
|
||||
chan->MaxTransferMode = ATA_UDMA5;
|
||||
break;
|
||||
}
|
||||
UniataSataWritePort4(chan, IDX_SATA_SError, 0xffffffff, 0);
|
||||
|
@ -83,6 +83,50 @@ AtapiDoNothing(VOID)
|
||||
|
||||
#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
|
||||
*/
|
||||
@ -329,7 +373,6 @@ UniataEnumBusMasterController__(
|
||||
SubVendorID = pciData.u.type0.SubVendorID;
|
||||
SubSystemID = pciData.u.type0.SubSystemID;
|
||||
|
||||
|
||||
//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
|
||||
@ -367,6 +410,14 @@ UniataEnumBusMasterController__(
|
||||
found = 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) {
|
||||
deviceExtension->slotNumber = slotData.u.AsULONG;
|
||||
deviceExtension->SystemIoBusNumber = busNumber;
|
||||
@ -426,36 +477,7 @@ UniataEnumBusMasterController__(
|
||||
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
||||
|
||||
if(!pass && known) {
|
||||
// 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, 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));
|
||||
UniataEnableIoPCI(busNumber, slotData.u.AsULONG, &pciData);
|
||||
}
|
||||
// validate Mem/Io ranges
|
||||
no_ranges = TRUE;
|
||||
@ -1175,37 +1197,7 @@ UniataFindBusMasterController(
|
||||
deviceExtension->BusMaster = DMA_MODE_NONE;
|
||||
|
||||
if(WinVer_WDM_Model && !deviceExtension->UnknownDev) {
|
||||
ULONG i;
|
||||
// Enable Busmastering, IO-space and Mem-space
|
||||
KdPrint2((PRINT_PREFIX "Enabling Mem/Io spaces and busmastering...\n"));
|
||||
KdPrint2((PRINT_PREFIX "Initial pciData.Command = %#x\n", pciData.Command));
|
||||
for(i=0; i<3; i++) {
|
||||
switch(i) {
|
||||
case 0:
|
||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_IO_SPACE\n"));
|
||||
pciData.Command |= PCI_ENABLE_IO_SPACE;
|
||||
break;
|
||||
case 1:
|
||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_MEMORY_SPACE\n"));
|
||||
pciData.Command |= PCI_ENABLE_MEMORY_SPACE;
|
||||
break;
|
||||
case 2:
|
||||
KdPrint2((PRINT_PREFIX "PCI_ENABLE_BUS_MASTER\n"));
|
||||
pciData.Command |= PCI_ENABLE_BUS_MASTER;
|
||||
break;
|
||||
}
|
||||
HalSetBusDataByOffset( PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG,
|
||||
&(pciData.Command),
|
||||
offsetof(PCI_COMMON_CONFIG, Command),
|
||||
sizeof(pciData.Command));
|
||||
KdPrint2((PRINT_PREFIX "InterruptLine = %#x\n", pciData.u.type0.InterruptLine));
|
||||
|
||||
// reread config space
|
||||
busDataRead = HalGetBusData(PCIConfiguration, SystemIoBusNumber, slotData.u.AsULONG,
|
||||
&pciData, PCI_COMMON_HDR_LENGTH);
|
||||
KdPrint2((PRINT_PREFIX "New pciData.Command = %#x\n", pciData.Command));
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX "Final pciData.Command = %#x\n", pciData.Command));
|
||||
UniataEnableIoPCI(ConfigInfo->SystemIoBusNumber, slotData.u.AsULONG, &pciData);
|
||||
}
|
||||
// validate Mem/Io ranges
|
||||
//no_ranges = TRUE;
|
||||
@ -1364,6 +1356,7 @@ UniataFindBusMasterController(
|
||||
KdPrint2((PRINT_PREFIX "!MasterDev\n"));
|
||||
ConfigInfo->SlotNumber = slotNumber;
|
||||
ConfigInfo->SystemIoBusNumber = SystemIoBusNumber;
|
||||
ConfigInfo->InterruptMode = LevelSensitive;
|
||||
|
||||
/* primary and secondary channels share the same interrupt */
|
||||
if(!ConfigInfo->BusInterruptVector ||
|
||||
@ -1394,8 +1387,13 @@ UniataFindBusMasterController(
|
||||
}
|
||||
if((WinVer_Id() > WinVer_2k) ||
|
||||
(ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
|
||||
KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k\n"));
|
||||
_ConfigInfo->w2k.Dma64BitAddresses = 0;
|
||||
KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k: 64bit %d\n",
|
||||
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.MaximumNumberOfLogicalUnits = (UCHAR)deviceExtension->NumberLuns;
|
||||
}
|
||||
@ -1411,20 +1409,32 @@ UniataFindBusMasterController(
|
||||
deviceExtension->AlignmentMask = ConfigInfo->AlignmentMask;
|
||||
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;
|
||||
|
||||
if(deviceExtension->BusMaster) {
|
||||
|
||||
KdPrint2((PRINT_PREFIX "Reconstruct ConfigInfo\n"));
|
||||
ConfigInfo->MapBuffers = TRUE;
|
||||
#ifdef USE_OWN_DMA
|
||||
ConfigInfo->NeedPhysicalAddresses = FALSE;
|
||||
#else
|
||||
ConfigInfo->NeedPhysicalAddresses = TRUE;
|
||||
#endif //USE_OWN_DMA
|
||||
if(!MasterDev) {
|
||||
//#ifdef USE_OWN_DMA
|
||||
// KdPrint2((PRINT_PREFIX "!MasterDev, own DMA\n"));
|
||||
//#else
|
||||
KdPrint2((PRINT_PREFIX "set Dma32BitAddresses\n"));
|
||||
ConfigInfo->Dma32BitAddresses = TRUE;
|
||||
//#endif //USE_OWN_DMA
|
||||
}
|
||||
|
||||
// thanks to Vitaliy Vorobyov aka deathsoft@yandex.ru for
|
||||
@ -1451,9 +1461,10 @@ UniataFindBusMasterController(
|
||||
ConfigInfo->Master = TRUE;
|
||||
ConfigInfo->DmaWidth = Width16Bits;
|
||||
#endif //USE_OWN_DMA
|
||||
ConfigInfo->CachesData = 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));
|
||||
|
||||
@ -1486,14 +1497,6 @@ UniataFindBusMasterController(
|
||||
(*ConfigInfo->AccessRanges)[channel * 2 + 1].RangeStart =
|
||||
ScsiPortConvertUlongToPhysicalAddress((channel ? IO_WD2 : IO_WD1) + ATA_ALTOFFSET);
|
||||
(*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
|
||||
if(AltInit &&
|
||||
!(*ConfigInfo->AccessRanges)[channel * 2 + 0].RangeStart.QuadPart &&
|
||||
@ -1552,8 +1555,8 @@ UniataFindBusMasterController(
|
||||
|
||||
// Get the system physical address for this IO range.
|
||||
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
||||
PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
||||
SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
||||
MasterDev ? ConfigInfo->AdapterInterfaceType : PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
||||
MasterDev ? ConfigInfo->SystemIoBusNumber : SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
||||
IoBasePort1,
|
||||
ATA_IOSIZE,
|
||||
TRUE);
|
||||
@ -1577,8 +1580,8 @@ UniataFindBusMasterController(
|
||||
|
||||
// Get the system physical address for the second IO range.
|
||||
ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
|
||||
PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
||||
SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
||||
MasterDev ? ConfigInfo->AdapterInterfaceType : PCIBus /*ConfigInfo->AdapterInterfaceType*/,
|
||||
MasterDev ? ConfigInfo->SystemIoBusNumber : SystemIoBusNumber /*ConfigInfo->SystemIoBusNumber*/,
|
||||
IoBasePort2,
|
||||
ATA_ALTIOSIZE,
|
||||
TRUE);
|
||||
@ -1744,12 +1747,12 @@ exit_findbm:
|
||||
KdPrint2((PRINT_PREFIX "MasterDev=%#x, NumberChannels=%#x, Isr2DevObj=%#x\n",
|
||||
MasterDev, deviceExtension->NumberChannels, BMList[i].Isr2DevObj));
|
||||
|
||||
if(WinVer_WDM_Model && MasterDev) {
|
||||
KdPrint2((PRINT_PREFIX "do not tell system, that we know about this:\n"));
|
||||
if(BaseIoAddressBM_0) {
|
||||
if(/*WinVer_WDM_Model &&*/ MasterDev) {
|
||||
KdPrint2((PRINT_PREFIX "do not tell system, that we know about PCI IO ranges\n"));
|
||||
/* if(BaseIoAddressBM_0) {
|
||||
ScsiPortFreeDeviceBase(HwDeviceExtension,
|
||||
BaseIoAddressBM_0);
|
||||
}
|
||||
}*/
|
||||
(*ConfigInfo->AccessRanges)[4].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
||||
(*ConfigInfo->AccessRanges)[4].RangeLength = 0;
|
||||
(*ConfigInfo->AccessRanges)[5].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
|
||||
@ -1761,6 +1764,17 @@ exit_findbm:
|
||||
found = FALSE;
|
||||
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
|
||||
|
||||
@ -1790,331 +1804,78 @@ exit_notfound:
|
||||
/*
|
||||
This is for claiming PCI Busmaster in compatible mode under WDM OSes
|
||||
*/
|
||||
ULONG
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
UniataFindFakeBusMasterController(
|
||||
IN PVOID HwDeviceExtension,
|
||||
IN PVOID Context,
|
||||
IN PVOID BusInformation,
|
||||
IN PCHAR ArgumentString,
|
||||
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
||||
OUT PBOOLEAN Again
|
||||
UniataClaimLegacyPCIIDE(
|
||||
ULONG i
|
||||
)
|
||||
{
|
||||
PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
//PHW_CHANNEL chan = NULL;
|
||||
// this buffer must be global for UNIATA_CORE build
|
||||
PCI_COMMON_CONFIG pciData;
|
||||
|
||||
ULONG slotNumber;
|
||||
ULONG busDataRead;
|
||||
ULONG SystemIoBusNumber;
|
||||
|
||||
UCHAR vendorString[5];
|
||||
UCHAR deviceString[5];
|
||||
PUCHAR vendorStrPtr;
|
||||
PUCHAR deviceStrPtr;
|
||||
|
||||
UCHAR BaseClass;
|
||||
UCHAR SubClass;
|
||||
ULONG VendorID;
|
||||
ULONG DeviceID;
|
||||
ULONG RevID;
|
||||
ULONG dev_id;
|
||||
PCI_SLOT_NUMBER slotData;
|
||||
|
||||
ULONG i;
|
||||
// PUCHAR ioSpace;
|
||||
// UCHAR statusByte;
|
||||
|
||||
// UCHAR tmp8;
|
||||
// ULONG irq;
|
||||
|
||||
BOOLEAN found = FALSE;
|
||||
BOOLEAN MasterDev;
|
||||
BOOLEAN simplexOnly = FALSE;
|
||||
//BOOLEAN skip_find_dev = FALSE;
|
||||
//BOOLEAN AltInit = FALSE;
|
||||
|
||||
PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0 = NULL;
|
||||
|
||||
NTSTATUS status;
|
||||
PPORT_CONFIGURATION_INFORMATION_COMMON _ConfigInfo =
|
||||
(PPORT_CONFIGURATION_INFORMATION_COMMON)ConfigInfo;
|
||||
PCM_RESOURCE_LIST resourceList;
|
||||
UNICODE_STRING devname;
|
||||
|
||||
*Again = FALSE;
|
||||
KdPrint2((PRINT_PREFIX "UniataClaimLegacyPCIIDE:\n"));
|
||||
|
||||
if(InDriverEntry) {
|
||||
i = (ULONG)Context;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
if(BMList[i].PciIdeDevObj) {
|
||||
KdPrint2((PRINT_PREFIX "Already initialized\n"));
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
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) {
|
||||
KdPrint2((PRINT_PREFIX "!deviceExtension => SP_RETURN_ERROR\n"));
|
||||
return SP_RETURN_ERROR;
|
||||
}
|
||||
RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
|
||||
|
||||
vendorStrPtr = vendorString;
|
||||
deviceStrPtr = deviceString;
|
||||
|
||||
slotNumber = BMList[i].slotNumber;
|
||||
SystemIoBusNumber = BMList[i].busNumber;
|
||||
|
||||
KdPrint2((PRINT_PREFIX "AdapterInterfaceType=%#x\n",ConfigInfo->AdapterInterfaceType));
|
||||
KdPrint2((PRINT_PREFIX "IoBusNumber=%#x\n",ConfigInfo->SystemIoBusNumber));
|
||||
KdPrint2((PRINT_PREFIX "slotNumber=%#x\n",slotNumber));
|
||||
|
||||
// this buffer must be global and already filled for UNIATA_CORE build
|
||||
busDataRead = HalGetBusData(
|
||||
//busDataRead = ScsiPortGetBusData(HwDeviceExtension,
|
||||
PCIConfiguration,
|
||||
SystemIoBusNumber,
|
||||
slotNumber,
|
||||
&pciData,
|
||||
PCI_COMMON_HDR_LENGTH);
|
||||
|
||||
if (busDataRead < PCI_COMMON_HDR_LENGTH) {
|
||||
KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
|
||||
goto exit_error;
|
||||
if(!NT_SUCCESS(status)) {
|
||||
KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
KdPrint2((PRINT_PREFIX "busDataRead\n"));
|
||||
if (pciData.VendorID == PCI_INVALID_VENDORID) {
|
||||
KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n"));
|
||||
goto exit_error;
|
||||
resourceList = (PCM_RESOURCE_LIST) ExAllocatePool(PagedPool,
|
||||
sizeof(CM_RESOURCE_LIST));
|
||||
|
||||
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;
|
||||
DeviceID = pciData.DeviceID;
|
||||
BaseClass = pciData.BaseClass;
|
||||
SubClass = pciData.SubClass;
|
||||
RevID = pciData.RevisionID;
|
||||
dev_id = VendorID | (DeviceID << 16);
|
||||
slotData.u.AsULONG = slotNumber;
|
||||
KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
|
||||
RtlZeroMemory(
|
||||
resourceList,
|
||||
sizeof(CM_RESOURCE_LIST));
|
||||
|
||||
deviceExtension->slotNumber = slotNumber;
|
||||
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;
|
||||
// IoReportDetectedDevice() should be used for WDM OSes
|
||||
|
||||
_snprintf(deviceExtension->Signature, sizeof(deviceExtension->Signature),
|
||||
"UATA%8.8x/%1.1x@%8.8x", dev_id, 0xff, slotNumber);
|
||||
resourceList->Count = 1;
|
||||
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) {
|
||||
KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
|
||||
goto exit_notfound;
|
||||
RtlInitUnicodeString(&devname, L"PCIIDE");
|
||||
status = HalAssignSlotResources(&SavedRegPath,
|
||||
&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
|
||||
if(VendorID != BMList[i].nVendorId ||
|
||||
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()
|
||||
return status;
|
||||
} // end UniataClaimLegacyPCIIDE()
|
||||
|
||||
|
||||
/*++
|
||||
@ -2148,11 +1909,6 @@ UniataConnectIntr2(
|
||||
|
||||
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
|
||||
!deviceExtension->simplexOnly && /* // this is unnecessary on simplex controllers
|
||||
!BMList[i].Isr2DevObj*/ // handle re-init under w2k+
|
||||
@ -2172,6 +1928,11 @@ UniataConnectIntr2(
|
||||
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"));
|
||||
|
||||
devname.Length =
|
||||
@ -2188,7 +1949,7 @@ UniataConnectIntr2(
|
||||
0, FALSE, &(BMList[i].Isr2DevObj));
|
||||
|
||||
if(!NT_SUCCESS(status)) {
|
||||
KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n"));
|
||||
KdPrint2((PRINT_PREFIX "IoCreateDevice failed %#x\n", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -2907,6 +2668,10 @@ CheckDevice(
|
||||
}
|
||||
LunExt = chan->lun[deviceNumber];
|
||||
|
||||
if(ResetDev) {
|
||||
LunExt->PowerState = 0;
|
||||
}
|
||||
|
||||
if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
|
||||
KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
|
||||
if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
|
||||
|
@ -619,7 +619,26 @@ UniataAhciInit(
|
||||
UniataDumpAhciRegs(deviceExtension);
|
||||
#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);
|
||||
KdPrint2((PRINT_PREFIX " reset AHCI controller, GHC %#x\n", GHC));
|
||||
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||
@ -638,12 +657,14 @@ UniataAhciInit(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* enable AHCI mode */
|
||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||
KdPrint2((PRINT_PREFIX " enable AHCI mode, GHC %#x\n", GHC));
|
||||
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||
GHC | AHCI_GHC_AE);
|
||||
/* re-enable AHCI mode */
|
||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||
if(!(GHC & AHCI_GHC_AE)) {
|
||||
KdPrint2((PRINT_PREFIX " re-enable AHCI mode, GHC %#x\n", GHC));
|
||||
UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
|
||||
GHC | AHCI_GHC_AE);
|
||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
|
||||
}
|
||||
KdPrint2((PRINT_PREFIX " AHCI GHC %#x\n", GHC));
|
||||
if(!(GHC & AHCI_GHC_AE)) {
|
||||
KdPrint2((PRINT_PREFIX " Can't enable AHCI mode\n"));
|
||||
@ -652,7 +673,6 @@ UniataAhciInit(
|
||||
|
||||
deviceExtension->AHCI_CAP =
|
||||
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
||||
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
|
||||
KdPrint2((PRINT_PREFIX " AHCI CAP %#x\n", CAP));
|
||||
if(CAP & AHCI_CAP_S64A) {
|
||||
KdPrint2((PRINT_PREFIX " AHCI 64bit\n"));
|
||||
@ -689,6 +709,8 @@ UniataAhciInit(
|
||||
|
||||
KdPrint2((PRINT_PREFIX " chan %d, offs %#x\n", c, offs));
|
||||
|
||||
chan->MaxTransferMode = deviceExtension->MaxTransferMode;
|
||||
|
||||
AtapiSetupLunPtrs(chan, deviceExtension, c);
|
||||
|
||||
chan->BaseIoAHCI_Port = deviceExtension->BaseIoAHCI_0;
|
||||
@ -719,6 +741,11 @@ UniataAhciInit(
|
||||
|
||||
AtapiDmaAlloc(HwDeviceExtension, NULL, c);
|
||||
|
||||
if(!UniataAhciChanImplemented(deviceExtension, c)) {
|
||||
KdPrint2((PRINT_PREFIX " chan %d not implemented\n", c));
|
||||
continue;
|
||||
}
|
||||
|
||||
UniataAhciResume(chan);
|
||||
|
||||
chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
|
||||
@ -727,6 +754,35 @@ UniataAhciInit(
|
||||
return TRUE;
|
||||
} // 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
|
||||
NTAPI
|
||||
UniataAhciDetect(
|
||||
@ -743,12 +799,13 @@ UniataAhciDetect(
|
||||
ULONG PI;
|
||||
ULONG CAP;
|
||||
ULONG CAP2;
|
||||
ULONG GHC;
|
||||
ULONG GHC, GHC0;
|
||||
ULONG BOHC;
|
||||
ULONG NumberChannels;
|
||||
ULONG v_Mn, v_Mj;
|
||||
ULONG BaseMemAddress;
|
||||
BOOLEAN MemIo;
|
||||
BOOLEAN MemIo = FALSE;
|
||||
BOOLEAN found = FALSE;
|
||||
|
||||
KdPrint2((PRINT_PREFIX " UniataAhciDetect:\n"));
|
||||
|
||||
@ -762,7 +819,7 @@ UniataAhciDetect(
|
||||
KdPrint2((PRINT_PREFIX " AHCI init failed - no IoRange\n"));
|
||||
return FALSE;
|
||||
}
|
||||
if(BaseMemAddress && (*ConfigInfo->AccessRanges)[5].RangeInMemory) {
|
||||
if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
|
||||
KdPrint2((PRINT_PREFIX "MemIo\n"));
|
||||
MemIo = TRUE;
|
||||
}
|
||||
@ -779,12 +836,29 @@ UniataAhciDetect(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* enable AHCI mode */
|
||||
/* check AHCI mode. Save state and try enable */
|
||||
GHC0 =
|
||||
GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_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)\n"));
|
||||
return FALSE;
|
||||
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)) {
|
||||
KdPrint2((PRINT_PREFIX " Non-AHCI GHC (!AE)\n"));
|
||||
goto exit_detect;
|
||||
}
|
||||
}
|
||||
|
||||
CAP = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP);
|
||||
@ -792,7 +866,7 @@ UniataAhciDetect(
|
||||
KdPrint2((PRINT_PREFIX " AHCI CAP %#x, CAP2 %#x\n", CAP, CAP2));
|
||||
if(CAP & AHCI_CAP_S64A) {
|
||||
KdPrint2((PRINT_PREFIX " 64bit"));
|
||||
//deviceExtension->Host64 = TRUE;
|
||||
//deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
|
||||
}
|
||||
if(CAP2 & AHCI_CAP2_BOH) {
|
||||
BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
|
||||
@ -811,6 +885,7 @@ UniataAhciDetect(
|
||||
|
||||
/* get the number of HW channels */
|
||||
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
|
||||
deviceExtension->AHCI_PI = PI;
|
||||
KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));
|
||||
for(i=PI, n=0; i; n++, i=i>>1);
|
||||
NumberChannels =
|
||||
@ -834,10 +909,10 @@ UniataAhciDetect(
|
||||
|
||||
if(!NumberChannels) {
|
||||
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_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
|
||||
|
||||
@ -862,19 +937,8 @@ UniataAhciDetect(
|
||||
deviceExtension->NumberLuns = 1;
|
||||
}
|
||||
|
||||
switch(version) {
|
||||
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", 1)) {
|
||||
KdPrint((" AHCI revision excluded\n"));
|
||||
return FALSE;
|
||||
}
|
||||
if(!UniAtaAhciValidateVersion(deviceExtension, version, TRUE)) {
|
||||
goto exit_detect;
|
||||
}
|
||||
|
||||
deviceExtension->HwFlags |= UNIATA_SATA | UNIATA_AHCI;
|
||||
@ -887,7 +951,13 @@ UniataAhciDetect(
|
||||
deviceExtension->BusMaster = DMA_MODE_AHCI;
|
||||
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()
|
||||
|
||||
UCHAR
|
||||
@ -974,6 +1044,31 @@ 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
|
||||
NTAPI
|
||||
UniataAhciSetupFIS_H2D(
|
||||
@ -1083,6 +1178,99 @@ UniataAhciSetupFIS_H2D(
|
||||
return 20;
|
||||
} // 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
|
||||
NTAPI
|
||||
UniataAhciWaitCommandReady(
|
||||
@ -1304,6 +1492,116 @@ 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
|
||||
NTAPI
|
||||
UniataAhciAbortOperation(
|
||||
|
@ -147,6 +147,14 @@ UniataAhciStatus(
|
||||
IN ULONG DeviceNumber
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
UniataAhciSnapAtaRegs(
|
||||
IN PHW_CHANNEL chan,
|
||||
IN ULONG DeviceNumber,
|
||||
IN OUT PIDEREGS_EX regs
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
UniataAhciSetupFIS_H2D(
|
||||
@ -195,6 +203,18 @@ UniataAhciSendPIOCommand(
|
||||
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
|
||||
NTAPI
|
||||
UniataAhciAbortOperation(
|
||||
@ -387,4 +407,8 @@ BuildAhciInternalSrb (
|
||||
IN ULONG Length = 0
|
||||
);
|
||||
|
||||
#define UniataAhciChanImplemented(deviceExtension, c) \
|
||||
(((deviceExtension)->AHCI_PI) & (1 << c))
|
||||
|
||||
|
||||
#endif //__UNIATA_SATA__H__
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
/* The definitions look so crappy, because the code doesn't care
|
||||
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_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]); }
|
||||
|
@ -392,13 +392,22 @@ typedef union _CDB {
|
||||
UCHAR Immediate: 1;
|
||||
UCHAR Reserved1 : 4;
|
||||
UCHAR Lun : 3;
|
||||
UCHAR Reserved2[2];
|
||||
UCHAR Reserved2;
|
||||
UCHAR FormatLayerNumber : 2;
|
||||
UCHAR Reserved2_2 : 6;
|
||||
UCHAR Start : 1;
|
||||
UCHAR LoadEject : 1;
|
||||
UCHAR Reserved3 : 6;
|
||||
UCHAR FL : 1;
|
||||
UCHAR Reserved3 : 1;
|
||||
UCHAR PowerConditions : 4;
|
||||
UCHAR Control;
|
||||
} 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 {
|
||||
UCHAR OperationCode;
|
||||
UCHAR Reserved1 : 5;
|
||||
@ -685,6 +694,14 @@ typedef union _CDB {
|
||||
UCHAR Control;
|
||||
} 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
|
||||
|
||||
struct _SEND_OPC_INFO {
|
||||
@ -901,6 +918,7 @@ typedef union _CDB {
|
||||
|
||||
#define SCSIOP_SA_READ_CAPACITY16 0x10
|
||||
|
||||
#define SCSIOP_REPORT_LUNS 0xA0
|
||||
#define SCSIOP_BLANK 0xA1
|
||||
#define SCSIOP_SEND_KEY 0xA3
|
||||
#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_SAVE_ATTRIBUTE_VALUES ((FILE_DEVICE_SCSI << 16) + 0x0508)
|
||||
#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
|
||||
|
||||
@ -2902,6 +2923,12 @@ typedef struct _DVD_RPC_KEY {
|
||||
UCHAR Reserved2[1];
|
||||
} 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)
|
||||
|
||||
#endif //__CDRW_DEVICE_H__
|
||||
|
@ -251,4 +251,7 @@
|
||||
156.use http://www.winimage.com/readfi15.zip for performance checks
|
||||
157.use IOCTL_SCSI_MINIPORT_IDENTIFY in atactl.exe to determine ...
|
||||
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 ReservedAsUlong;
|
||||
PVOID DataBuffer;
|
||||
UCHAR PreviousTaskFile[8];
|
||||
UCHAR CurrentTaskFile[8];
|
||||
union {
|
||||
UCHAR PreviousTaskFile[8];
|
||||
IDEREGS Regs;
|
||||
};
|
||||
union {
|
||||
UCHAR CurrentTaskFile[8];
|
||||
IDEREGS RegsH;
|
||||
};
|
||||
} 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.
|
||||
@ -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.
|
||||
// When this flag is set, the contents of the PreviousTaskFile member in the
|
||||
// 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
|
||||
|
||||
@ -221,13 +229,19 @@ typedef struct _ATA_PASS_THROUGH_DIRECT {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
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 bSectorNumberReg; // IDE sector number register
|
||||
UCHAR bCylLowReg; // IDE low order cylinder value
|
||||
UCHAR bCylHighReg; // IDE high order cylinder value
|
||||
UCHAR bDriveHeadReg; // IDE drive/head register
|
||||
union {
|
||||
UCHAR bCommandReg; // Actual IDE command.
|
||||
UCHAR bStatusReg; // Status register.
|
||||
};
|
||||
UCHAR bOpFlags; // 00 - send
|
||||
// 01 - read regs
|
||||
// 08 - lba48
|
||||
@ -236,9 +250,12 @@ typedef struct _IDEREGS_EX {
|
||||
#define UNIATA_SPTI_EX_SND 0x00
|
||||
#define UNIATA_SPTI_EX_RCV 0x01
|
||||
#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_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 bSectorCountRegH; // IDE sector count register (high part for LBA48 mode)
|
||||
@ -288,6 +305,19 @@ typedef struct _UNIATA_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
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,10 +1,10 @@
|
||||
#define UNIATA_VER_STR "42i2"
|
||||
#define UNIATA_VER_DOT 0.42.9.2
|
||||
#define UNIATA_VER_STR "43f5"
|
||||
#define UNIATA_VER_DOT 0.43.6.5
|
||||
#define UNIATA_VER_MJ 0
|
||||
#define UNIATA_VER_MN 42
|
||||
#define UNIATA_VER_SUB_MJ 9
|
||||
#define UNIATA_VER_SUB_MN 2
|
||||
#define UNIATA_VER_DOT_COMMA 0,42,9,2
|
||||
#define UNIATA_VER_DOT_STR "0.42.9.2"
|
||||
#define UNIATA_VER_MN 43
|
||||
#define UNIATA_VER_SUB_MJ 6
|
||||
#define UNIATA_VER_SUB_MN 5
|
||||
#define UNIATA_VER_DOT_COMMA 0,43,6,5
|
||||
#define UNIATA_VER_DOT_STR "0.43.6.5"
|
||||
#define UNIATA_VER_YEAR 2012
|
||||
#define UNIATA_VER_YEAR_STR "2012"
|
||||
|
Loading…
Reference in New Issue
Block a user