143 #define RESET_COMPLETE_CURRENT 0x00 144 #define RESET_COMPLETE_ALL 0x01 145 #define RESET_COMPLETE_NONE 0x02 155 #ifdef UNIATA_USE_XXableInterrupts 156 #define RETTYPE_XXableInterrupts BOOLEAN 157 #define RETVAL_XXableInterrupts TRUE 159 #define RETTYPE_XXableInterrupts VOID 160 #define RETVAL_XXableInterrupts 205 #define ITEMS_TO_QUERY 2 // always 1 greater than what is searched 230 #undef ITEMS_TO_QUERY 261 #define AtapiWritePortN_template(_type, _Type, sz) \ 264 AtapiWritePort##sz( \ 265 IN PHW_CHANNEL chan, \ 266 IN ULONGIO_PTR _port, \ 271 if(_port >= IDX_MAX_REG) { \ 272 res = (PIORES)(_port); \ 275 res = &chan->RegTranslation[_port]; \ 277 KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \ 281 KdPrint(("PROC io write request @ ch %x, res* %x\n", chan, _port)); \ 285 ScsiPortWritePort##_Type((_type*)(ULONGIO_PTR)(res->Addr), data); \ 288 ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr), data); \ 297 #define AtapiWritePortExN_template(_type, _Type, sz) \ 300 AtapiWritePortEx##sz( \ 301 IN PHW_CHANNEL chan, \ 302 IN ULONGIO_PTR _port, \ 308 if(_port >= IDX_MAX_REG) { \ 309 res = (PIORES)(_port); \ 312 res = &chan->RegTranslation[_port]; \ 314 KdPrint(("invalid io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \ 318 KdPrint(("PROC io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \ 322 ScsiPortWritePort##_Type((_type*)(ULONGIO_PTR)(res->Addr+offs), data); \ 325 ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr+offs), data); \ 334 #define AtapiReadPortN_template(_type, _Type, sz) \ 338 IN PHW_CHANNEL chan, \ 339 IN ULONGIO_PTR _port \ 343 if(_port >= IDX_MAX_REG) { \ 344 res = (PIORES)(_port); \ 347 res = &chan->RegTranslation[_port]; \ 349 KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \ 350 return (_type)(-1); \ 353 KdPrint(("PROC io read request @ ch %x, res* %x\n", chan, _port)); \ 358 return ScsiPortReadPort##_Type((_type*)(ULONGIO_PTR)(res->Addr)); \ 361 return ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr)); \ 369 #define AtapiReadPortExN_template(_type, _Type, sz) \ 372 AtapiReadPortEx##sz( \ 373 IN PHW_CHANNEL chan, \ 374 IN ULONGIO_PTR _port, \ 379 if(_port >= IDX_MAX_REG) { \ 380 res = (PIORES)(_port); \ 383 res = &chan->RegTranslation[_port]; \ 385 KdPrint(("invalid io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \ 386 return (_type)(-1); \ 389 KdPrint(("PROC io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \ 393 return ScsiPortReadPort##_Type((_type*)(ULONGIO_PTR)(res->Addr+offs)); \ 396 return ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr+offs)); \ 404 #define AtapiReadPortBufferN_template(_type, _Type, sz) \ 407 AtapiReadBuffer##sz( \ 408 IN PHW_CHANNEL chan, \ 409 IN ULONGIO_PTR _port, \ 419 (*((_type*)Buffer)) = AtapiReadPort##sz(chan, _port); \ 421 Buffer = ((_type*)Buffer)+1; \ 422 UniataNanoSleep(Timing); \ 427 if(_port >= IDX_MAX_REG) { \ 428 res = (PIORES)(_port); \ 431 res = &chan->RegTranslation[_port]; \ 433 KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \ 438 ScsiPortReadPortBuffer##_Type((_type*)(ULONGIO_PTR)(res->Addr), (_type*)Buffer, Count); \ 442 (*((_type*)Buffer)) = ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr)); \ 444 Buffer = ((_type*)Buffer)+1; \ 449 #define AtapiWritePortBufferN_template(_type, _Type, sz) \ 452 AtapiWriteBuffer##sz( \ 453 IN PHW_CHANNEL chan, \ 454 IN ULONGIO_PTR _port, \ 464 AtapiWritePort##sz(chan, _port, *((_type*)Buffer)); \ 465 Buffer = ((_type*)Buffer)+1; \ 467 UniataNanoSleep(Timing); \ 472 if(_port >= IDX_MAX_REG) { \ 473 res = (PIORES)(_port); \ 476 res = &chan->RegTranslation[_port]; \ 478 KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \ 483 ScsiPortWritePortBuffer##_Type((_type*)(ULONGIO_PTR)(res->Addr), (_type*)Buffer, Count); \ 487 ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr), *((_type*)Buffer)); \ 489 Buffer = ((_type*)Buffer)+1; \ 512 for (
i = 0;
i < 0x10000;
i++) {
682 for (
i=0;
i<2000;
i++) {
733 for (
i=0;
i<20000;
i++) {
758 for (
i=0;
i<1000;
i++) {
779 for (
i=0;
i<2;
i++) {
801 UCHAR dma_status = 0;
803 UCHAR statusByte0, statusByte2;
817 for (
i = 0;
i < 1000;
i++) {
832 statusByte0 = statusByte2;
871 chan->last_devsel = -1;
878 if(chan && chan->DeviceExtension) {
879 dma_status =
GetDmaStatus(chan->DeviceExtension, chan->lChannel);
911 chan->last_devsel = -1;
933 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
938 KdPrint2((
PRINT_PREFIX "AtaCommand48: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x count %#x feature %#x\n",
1037 switch (wait_flags) {
1055 for (
i=0;
i<30 * 1000;
i++) {
1058 statusByte =
UniataIsIdle(deviceExtension, statusByte);
1176 if (
ident->PioTimingsValid) {
1184 if (
ident->PioCycleTimingMode == 2)
1186 if (
ident->PioCycleTimingMode == 1)
1188 if (
ident->PioCycleTimingMode == 0)
1197 if (
ident->MultiWordDMASupport & 0x04)
1199 if (
ident->MultiWordDMASupport & 0x02)
1201 if (
ident->MultiWordDMASupport & 0x01)
1210 if (!
ident->UdmaModesValid)
1212 if (
ident->UltraDMASupport & 0x40)
1214 if (
ident->UltraDMASupport & 0x20)
1216 if (
ident->UltraDMASupport & 0x10)
1218 if (
ident->UltraDMASupport & 0x08)
1220 if (
ident->UltraDMASupport & 0x04)
1222 if (
ident->UltraDMASupport & 0x02)
1224 if (
ident->UltraDMASupport & 0x01)
1232 if(!
ident->SataCapabilities ||
1233 ident->SataCapabilities == 0xffff) {
1259 ULONG MiniportTimerValue;
1271 chan = &(deviceExtension->
chan[lChannel]);
1283 HwScsiTimer(HwDeviceExtension);
1298 chan = &deviceExtension->
chan[lChannel];
1311 if(!MiniportTimerValue)
1312 MiniportTimerValue = 1;
1347 KdPrint2((
PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
1351 time.QuadPart += MiniportTimerValue*10;
1357 chan = prev_chan =
NULL;
1360 chan = &(deviceExtension->
chan[
i]);
1366 chan = &(deviceExtension->
chan[lChannel]);
1378 MiniportTimerValue = 1;
1383 KdPrint2((
PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
1386 MiniportTimerValue);
1390 #endif //UNIATA_CORE 1400 UCHAR statusByteAlt;
1408 " Reg_%#x (%#x) = %#x\n",
1410 chan->RegTranslation[
IDX_IO1+
j].Addr,
1413 if(!chan->RegTranslation[
IDX_BM_IO].Addr) {
1419 " BM_%#x (%#x) = %#x\n",
1436 if(chan->DeviceExtension->HwFlags &
UNIATA_AHCI) {
1442 UCHAR statusByteAlt;
1493 ULONG waitCount = 50000;
1648 for (;
j < 4*2;
j++) {
1922 (NumOfSectors < deviceExtension->FullIdentifyData.UserAddressableSectors)) {
1931 NumOfSectors = cylinders *
1959 goto skip_lba_staff;
1977 NativeNumOfSectors = cylinders *
1983 if(NativeNumOfSectors > NumOfSectors) {
1985 NumOfSectors = NativeNumOfSectors;
1991 ULONG hNativeNumOfSectors;
2009 NativeNumOfSectors |=
2011 hNativeNumOfSectors=
2014 ((
PULONG)&NativeNumOfSectors)[1] = hNativeNumOfSectors;
2022 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2042 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2044 NativeNumOfSectors = 0;
2049 NativeNumOfSectors > NumOfSectors) {
2057 NumOfSectors = NativeNumOfSectors;
2063 if(NumOfSectors < 0x2100000 /*&& NumOfSectors > 31*1000*1000*/) {
2082 if(NativeNumOfSectors > NumOfSectors) {
2090 NumOfSectors = NativeNumOfSectors;
2126 tmp_cylinders = NumOfSectors / (255*63);
2127 if(tmp_cylinders < 0xffff) {
2152 cylinders = NumOfSectors / (255*63);
2186 cylinders = tmp_cylinders;
2321 statusByte =
UniataIsIdle(deviceExtension, statusByte);
2325 errorByte, statusByte));
2389 ULONG ChannelCtrlFlags;
2390 UCHAR dma_status = 0;
2394 ULONG VendorID = deviceExtension->
DevID & 0xffff;
2416 for (;
j < numberChannels;
j++) {
2419 chan = &(deviceExtension->
chan[
j]);
2423 KdPrint2((
PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x, sptr %#x, flags %#x\n", CompleteType, MaxLuns, chan, &chan, ChannelCtrlFlags));
2434 LunExt = chan->
lun[
i];
2452 CurSrb = AtaReq->
Srb;
2475 senseBuffer->
Valid = 1;
2478 KdPrint2((
PRINT_PREFIX "AtapiResetController: report SCSI_SENSE_UNIT_ATTENTION + SCSI_ADSENSE_BUS_RESET\n"));
2546 #endif //UNIATA_CORE 2556 for (
i = 0;
i < MaxLuns;
i++) {
2557 chan->
lun[
i]->PowerState = 0;
2564 UniataDumpAhciPortRegs(chan);
2603 mask = 1 << chan->
lun[0]->SATA_lun_map;
2605 mask |= (1 << chan->
lun[1]->SATA_lun_map);
2621 if (((tmp16 >> pshift) &
mask) ==
mask) {
2649 offs = (ChipFlags &
NV4OFF) ? 0x0440 : 0x0010;
2653 if(ChipFlags &
NVQ) {
2665 if(ChipFlags &
NVQ) {
2684 offset = ((Channel & 1) << 7) + ((Channel & 2) << 8);
2750 for (
i = 0;
i < MaxLuns;
i++) {
2797 statusByte =
UniataIsIdle(deviceExtension, statusByte);
2800 "no drive, status %#x\n",
2841 "AtapiResetController: Status after soft reset %#x\n",
2875 KdPrint2((
PRINT_PREFIX "AtapiResetController: deviceExtension->chan[%d].DisableIntr %d -> 1\n",
2914 UCHAR errorByte = 0;
2925 errorByte = AtaReq->
ahci.in_error;
2932 "MapError: Error register is %#x\n",
2937 switch (errorByte >> 4) {
2941 "ATAPI: No sense information\n"));
2949 "ATAPI: Recovered error\n"));
2957 "ATAPI: Device not ready\n"));
2965 "ATAPI: Media error\n"));
2973 "ATAPI: Hardware error\n"));
2981 "ATAPI: Illegal request\n"));
2989 "ATAPI: Unit attention\n"));
2997 "ATAPI: Data protect\n"));
3005 "ATAPI: Blank check\n"));
3012 "Atapi: Command Aborted\n"));
3020 "ATAPI: Invalid sense information\n"));
3035 "IDE: Media change\n"));
3039 if (
Srb->SenseInfoBuffer) {
3044 senseBuffer->
Valid = 1;
3055 "IDE: Command abort\n"));
3059 if (
Srb->SenseInfoBuffer) {
3064 senseBuffer->
Valid = 1;
3078 "IDE: End of media\n"));
3082 if (
Srb->SenseInfoBuffer) {
3087 senseBuffer->
Valid = 1;
3104 "IDE: Illegal length\n"));
3107 if (
Srb->SenseInfoBuffer) {
3112 senseBuffer->
Valid = 1;
3125 "IDE: Bad block\n"));
3128 if (
Srb->SenseInfoBuffer) {
3133 senseBuffer->
Valid = 1;
3145 "IDE: Id not found\n"));
3149 if (
Srb->SenseInfoBuffer) {
3154 senseBuffer->
Valid = 1;
3168 "IDE: Media change\n"));
3172 if (
Srb->SenseInfoBuffer) {
3177 senseBuffer->
Valid = 1;
3189 "IDE: Data error\n"));
3198 if (
Srb->SenseInfoBuffer) {
3203 senseBuffer->
Valid = 1;
3217 "MapError: ErrorCount >= MAX_ERRORS\n"));
3224 "MapError: Disabling 32-bit PIO and Multi-sector IOs\n"));
3228 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
3274 Srb->ScsiStatus = scsiStatus;
3323 for (
c = 0;
c < numberChannels;
c++) {
3338 UCHAR statusByte, errorByte;
3339 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3342 ULONG PreferedMode = 0xffffffff;
3356 LunExt = chan->
lun[
i];
3372 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3383 KdPrint2((
PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
3387 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3395 KdPrint2((
PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
3404 "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
3414 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3421 "AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
3429 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3438 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3444 "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
3452 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3465 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3471 "AtapiHwInitialize: Enable APM on Device %d failed\n",
3476 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3481 if(LunExt->
IdentifyData.FeaturesSupport.AutoAcoustic) {
3485 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3491 "AtapiHwInitialize: Enable Acoustic Mgmt on Device %d failed\n",
3496 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3504 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3510 "AtapiHwInitialize: standby timer on Device %d failed\n",
3525 for (
j = 0;
j < 26;
j += 2) {
3534 if (vendorId[12] ==
'C') {
3546 if((PreferedMode == 0xffffffff) || (PreferedMode > chan->
MaxTransferMode)) {
3604 }
while (waitCount--);
3632 if (MechanismStatus) {
3633 LunExt->
DiscsPresent = MechanismStatus->NumberAvailableSlots;
3667 ULONG stringLength = 0;
3668 ULONG keyWordLength = 0;
3690 if (keyWordLength > stringLength) {
3702 while (*cptr ==
' ' || *cptr ==
'\t') {
3706 if (*cptr ==
'\0') {
3712 while ((*cptr == *kptr) ||
3713 (*cptr >=
'A' && *cptr <=
'Z' && *cptr + (
'a' -
'A') == *kptr) ||
3714 (*cptr >=
'a' && *cptr <=
'z' && *cptr - (
'a' -
'A') == *kptr)) {
3718 if (*cptr ==
'\0') {
3724 if (*kptr ==
'\0') {
3727 while (*cptr ==
' ' || *cptr ==
'\t') {
3736 if (*cptr++ ==
';') {
3737 goto ContinueSearch;
3746 while ((*cptr ==
' ') || (*cptr ==
'\t')) {
3750 if (*cptr ==
'\0') {
3758 goto ContinueSearch;
3762 if ((*cptr ==
'0') && ((*(cptr + 1) ==
'x') || (*(cptr + 1) ==
'X'))) {
3767 if (*(cptr +
index) ==
' ' ||
3768 *(cptr +
index) ==
'\t' ||
3769 *(cptr +
index) ==
';') {
3773 if ((*(cptr +
index) >=
'0') && (*(cptr +
index) <=
'9')) {
3776 if ((*(cptr +
index) >=
'a') && (*(cptr +
index) <=
'f')) {
3778 }
else if ((*(cptr +
index) >=
'A') && (*(cptr +
index) <=
'F')) {
3791 if (*(cptr +
index) ==
' ' ||
3792 *(cptr +
index) ==
'\t' ||
3793 *(cptr +
index) ==
';') {
3797 if ((*(cptr +
index) >=
'0') && (*(cptr +
index) <=
'9')) {
3812 if (*cptr++ ==
';') {
3813 goto ContinueSearch;
3853 goto ReturnCallback;
3862 goto ReturnEnableIntr;
3903 goto ReturnCallback;
3908 if(CrNtInterlockedExchangeAdd(&(chan->
DisableIntr), 0)) {
3911 #ifdef UNIATA_USE_XXableInterrupts 3925 #endif // UNIATA_USE_XXableInterrupts 3941 chan = &(deviceExtension->
chan[
c]);
3968 #endif //UNIATA_CORE 4014 checked |= ~deviceExtension->
AHCI_PI;
4047 if((checked>>
c) & 0x01)
4054 checked |= (
ULONG)1 <<
c;
4058 if(CrNtInterlockedExchangeAdd(&(deviceExtension->
chan[
c].
DisableIntr), 0)) {
4148 IN PVOID Isr2HwDeviceExtension
4180 checked |= ~deviceExtension->
AHCI_PI;
4195 if((checked>>
c) & 0x01)
4198 checked |= (
ULONG)1 <<
c;
4200 if(CrNtInterlockedExchangeAdd(&(deviceExtension->
chan[
c].
DisableIntr), 0)) {
4298 chan = &(deviceExtension->
chan[
c]);
4346 #endif //UNIATA_CORE 4370 chan = &(deviceExtension->
chan[
c]);
4422 chan = &(deviceExtension->
chan[
c]);
4451 chan->ExpectingInterrupt = Expecting;
4453 chan->DeviceExtension->ExpectingInterrupt++;
4455 if(chan->DeviceExtension->ExpectingInterrupt) {
4456 chan->DeviceExtension->ExpectingInterrupt--;
4475 ULONG VendorID = deviceExtension->
DevID & 0xffff;
4479 ULONG pr_status = 0;
4480 UCHAR dma_status = 0;
4483 UCHAR statusByte = 0;
4493 UCHAR interruptReason;
4500 Channel = (
UCHAR)(deviceExtension->
Channel + lChannel);
4510 return OurInterrupt;
4535 return OurInterrupt;
4570 ((Channel) ? 0x00004000 : 0x00000400))) {
4586 ULONG stat_reg = (ChipFlags &
PRG2) ? 0x60 : 0x6c;
4590 if(
status & (1 << (Channel+1))) {
4602 if(pr_status & (0x11 << Channel)) {
4607 if(!(
status & (0x01 << Channel))) {
4628 ULONG offs = (ChipFlags &
NV4OFF) ? 0x0440 : 0x0010;
4632 if(ChipFlags &
NVQ) {
4642 if(((pr_status & (0x0cUL <<
shift)) == (0x04UL <<
shift)) ) {
4646 if((pr_status & (0x08UL <<
shift)) &&
4647 !((pr_status & (0x04UL <<
shift) &&
4652 if(!(pr_status & (0x01UL <<
shift))) {
4675 if(reg32 == 0xffffffff) {