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
261#define AtapiWritePortN_template(_type, _Type, 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) \
300AtapiWritePortEx##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) \
372AtapiReadPortEx##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) \
407AtapiReadBuffer##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) \
452AtapiWriteBuffer##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++) {
576FillDeviceIdentificationString(
581 ULONG IdentifierLen, FirstWordLen;
588#define IDENTIFIER_LETTER(Identifier, i) (((PUCHAR)Identifier)[(i) ^ 1])
590 for (IdentifierLen = 20; IdentifierLen > 0 && IDENTIFIER_LETTER(IdentifyData->ModelNumber, IdentifierLen - 1) ==
' '; IdentifierLen--)
594 for (FirstWordLen = 0; IDENTIFIER_LETTER(IdentifyData->ModelNumber, FirstWordLen) !=
' ' && FirstWordLen < IdentifierLen; FirstWordLen++)
596 if (FirstWordLen <= 8)
598 for (
i = 0;
i < FirstWordLen;
i++)
599 InquiryData->VendorId[
i] = IDENTIFIER_LETTER(IdentifyData->ModelNumber,
i);
600 for (
i = FirstWordLen + 1;
i < IdentifierLen;
i++)
601 InquiryData->ProductId[
i - FirstWordLen - 1] = IDENTIFIER_LETTER(IdentifyData->ModelNumber,
i);
606 if (IdentifierLen <= 16)
608 for (
i = 0;
i < IdentifierLen;
i++)
609 InquiryData->ProductId[
i] = IDENTIFIER_LETTER(IdentifyData->ModelNumber,
i);
614 for (
i = 0;
i < 24;
i += 2)
615 MOV_DW_SWP(InquiryData->DeviceIdentificationString[
i], ((
PUCHAR)IdentifyData->ModelNumber)[
i]);
728 for (
i=0;
i<2000;
i++) {
779 for (
i=0;
i<20000;
i++) {
804 for (
i=0;
i<1000;
i++) {
825 for (
i=0;
i<2;
i++) {
847 UCHAR dma_status = 0;
849 UCHAR statusByte0, statusByte2;
863 for (
i = 0;
i < 1000;
i++) {
878 statusByte0 = statusByte2;
917 chan->last_devsel = -1;
924 if(chan && chan->DeviceExtension) {
925 dma_status =
GetDmaStatus(chan->DeviceExtension, chan->lChannel);
957 chan->last_devsel = -1;
979 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
984 KdPrint2((
PRINT_PREFIX "AtaCommand48: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x count %#x feature %#x\n",
1083 switch (wait_flags) {
1101 for (
i=0;
i<30 * 1000;
i++) {
1104 statusByte =
UniataIsIdle(deviceExtension, statusByte);
1143 statusByte &= ~IDE_STATUS_ERROR;
1222 if (
ident->PioTimingsValid) {
1230 if (
ident->PioCycleTimingMode == 2)
1232 if (
ident->PioCycleTimingMode == 1)
1234 if (
ident->PioCycleTimingMode == 0)
1243 if (
ident->MultiWordDMASupport & 0x04)
1245 if (
ident->MultiWordDMASupport & 0x02)
1247 if (
ident->MultiWordDMASupport & 0x01)
1256 if (!
ident->UdmaModesValid)
1258 if (
ident->UltraDMASupport & 0x40)
1260 if (
ident->UltraDMASupport & 0x20)
1262 if (
ident->UltraDMASupport & 0x10)
1264 if (
ident->UltraDMASupport & 0x08)
1266 if (
ident->UltraDMASupport & 0x04)
1268 if (
ident->UltraDMASupport & 0x02)
1270 if (
ident->UltraDMASupport & 0x01)
1278 if(!
ident->SataCapabilities ||
1279 ident->SataCapabilities == 0xffff) {
1305 ULONG MiniportTimerValue;
1317 chan = &(deviceExtension->
chan[lChannel]);
1329 HwScsiTimer(HwDeviceExtension);
1344 chan = &deviceExtension->
chan[lChannel];
1357 if(!MiniportTimerValue)
1358 MiniportTimerValue = 1;
1393 KdPrint2((
PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
1397 time.QuadPart += MiniportTimerValue*10;
1403 chan = prev_chan =
NULL;
1406 chan = &(deviceExtension->
chan[
i]);
1412 chan = &(deviceExtension->
chan[lChannel]);
1424 MiniportTimerValue = 1;
1429 KdPrint2((
PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
1432 MiniportTimerValue);
1446 UCHAR statusByteAlt;
1454 " Reg_%#x (%#x) = %#x\n",
1456 chan->RegTranslation[
IDX_IO1+
j].Addr,
1459 if(!chan->RegTranslation[
IDX_BM_IO].Addr) {
1465 " BM_%#x (%#x) = %#x\n",
1482 if(chan->DeviceExtension->HwFlags &
UNIATA_AHCI) {
1488 UCHAR statusByteAlt;
1539 ULONG waitCount = 50000;
1648 statusByte =
UniataIsIdle(deviceExtension, statusByte) & ~IDE_STATUS_INDEX;
1694 for (;
j < 4*2;
j++) {
1968 (NumOfSectors < deviceExtension->FullIdentifyData.UserAddressableSectors)) {
1977 NumOfSectors = cylinders *
2005 goto skip_lba_staff;
2023 NativeNumOfSectors = cylinders *
2029 if(NativeNumOfSectors > NumOfSectors) {
2031 NumOfSectors = NativeNumOfSectors;
2037 ULONG hNativeNumOfSectors;
2055 NativeNumOfSectors |=
2057 hNativeNumOfSectors=
2060 ((
PULONG)&NativeNumOfSectors)[1] = hNativeNumOfSectors;
2068 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2088 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2090 NativeNumOfSectors = 0;
2095 NativeNumOfSectors > NumOfSectors) {
2103 NumOfSectors = NativeNumOfSectors;
2109 if(NumOfSectors < 0x2100000 /*&& NumOfSectors > 31*1000*1000*/) {
2128 if(NativeNumOfSectors > NumOfSectors) {
2136 NumOfSectors = NativeNumOfSectors;
2172 tmp_cylinders = NumOfSectors / (255*63);
2173 if(tmp_cylinders < 0xffff) {
2198 cylinders = NumOfSectors / (255*63);
2232 cylinders = tmp_cylinders;
2367 statusByte =
UniataIsIdle(deviceExtension, statusByte);
2371 errorByte, statusByte));
2435 ULONG ChannelCtrlFlags;
2436 UCHAR dma_status = 0;
2440 ULONG VendorID = deviceExtension->
DevID & 0xffff;
2462 for (;
j < numberChannels;
j++) {
2465 chan = &(deviceExtension->
chan[
j]);
2469 KdPrint2((
PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x, sptr %#x, flags %#x\n", CompleteType, MaxLuns, chan, &chan, ChannelCtrlFlags));
2480 LunExt = chan->
lun[
i];
2498 CurSrb = AtaReq->
Srb;
2521 senseBuffer->
Valid = 1;
2524 KdPrint2((
PRINT_PREFIX "AtapiResetController: report SCSI_SENSE_UNIT_ATTENTION + SCSI_ADSENSE_BUS_RESET\n"));
2602 for (
i = 0;
i < MaxLuns;
i++) {
2603 chan->
lun[
i]->PowerState = 0;
2610 UniataDumpAhciPortRegs(chan);
2649 mask = 1 << chan->
lun[0]->SATA_lun_map;
2651 mask |= (1 << chan->
lun[1]->SATA_lun_map);
2667 if (((tmp16 >> pshift) &
mask) ==
mask) {
2695 offs = (ChipFlags &
NV4OFF) ? 0x0440 : 0x0010;
2699 if(ChipFlags &
NVQ) {
2711 if(ChipFlags &
NVQ) {
2730 offset = ((Channel & 1) << 7) + ((Channel & 2) << 8);
2796 for (
i = 0;
i < MaxLuns;
i++) {
2843 statusByte =
UniataIsIdle(deviceExtension, statusByte);
2846 "no drive, status %#x\n",
2887 "AtapiResetController: Status after soft reset %#x\n",
2921 KdPrint2((
PRINT_PREFIX "AtapiResetController: deviceExtension->chan[%d].DisableIntr %d -> 1\n",
2960 UCHAR errorByte = 0;
2971 errorByte = AtaReq->
ahci.in_error;
2978 "MapError: Error register is %#x\n",
2983 switch (errorByte >> 4) {
2987 "ATAPI: No sense information\n"));
2995 "ATAPI: Recovered error\n"));
3003 "ATAPI: Device not ready\n"));
3011 "ATAPI: Media error\n"));
3019 "ATAPI: Hardware error\n"));
3027 "ATAPI: Illegal request\n"));
3035 "ATAPI: Unit attention\n"));
3043 "ATAPI: Data protect\n"));
3051 "ATAPI: Blank check\n"));
3058 "Atapi: Command Aborted\n"));
3066 "ATAPI: Invalid sense information\n"));
3081 "IDE: Media change\n"));
3090 senseBuffer->
Valid = 1;
3101 "IDE: Command abort\n"));
3110 senseBuffer->
Valid = 1;
3124 "IDE: End of media\n"));
3133 senseBuffer->
Valid = 1;
3150 "IDE: Illegal length\n"));
3158 senseBuffer->
Valid = 1;
3171 "IDE: Bad block\n"));
3179 senseBuffer->
Valid = 1;
3191 "IDE: Id not found\n"));
3200 senseBuffer->
Valid = 1;
3214 "IDE: Media change\n"));
3223 senseBuffer->
Valid = 1;
3235 "IDE: Data error\n"));
3249 senseBuffer->
Valid = 1;
3263 "MapError: ErrorCount >= MAX_ERRORS\n"));
3270 "MapError: Disabling 32-bit PIO and Multi-sector IOs\n"));
3274 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
3369 for (
c = 0;
c < numberChannels;
c++) {
3384 UCHAR statusByte, errorByte;
3385 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3388 ULONG PreferedMode = 0xffffffff;
3402 LunExt = chan->
lun[
i];
3418 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3429 KdPrint2((
PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
3433 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3441 KdPrint2((
PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
3450 "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
3460 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3467 "AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
3475 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3484 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3490 "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
3498 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3511 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3517 "AtapiHwInitialize: Enable APM on Device %d failed\n",
3522 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3527 if(LunExt->
IdentifyData.FeaturesSupport.AutoAcoustic) {
3531 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3537 "AtapiHwInitialize: Enable Acoustic Mgmt on Device %d failed\n",
3542 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3550 statusByte =
AtaCommand(deviceExtension,
i, lChannel,
3556 "AtapiHwInitialize: standby timer on Device %d failed\n",
3571 for (
j = 0;
j < 26;
j += 2) {
3580 if (vendorId[12] ==
'C') {
3592 if((PreferedMode == 0xffffffff) || (PreferedMode > chan->
MaxTransferMode)) {
3650 }
while (waitCount--);
3678 if (MechanismStatus) {
3679 LunExt->
DiscsPresent = MechanismStatus->NumberAvailableSlots;
3713 ULONG stringLength = 0;
3714 ULONG keyWordLength = 0;
3736 if (keyWordLength > stringLength) {
3748 while (*cptr ==
' ' || *cptr ==
'\t') {
3752 if (*cptr ==
'\0') {
3758 while ((*cptr == *kptr) ||
3759 (*cptr >=
'A' && *cptr <=
'Z' && *cptr + (
'a' -
'A') == *kptr) ||
3760 (*cptr >=
'a' && *cptr <=
'z' && *cptr - (
'a' -
'A') == *kptr)) {
3764 if (*cptr ==
'\0') {
3770 if (*kptr ==
'\0') {
3773 while (*cptr ==
' ' || *cptr ==
'\t') {
3782 if (*cptr++ ==
';') {
3783 goto ContinueSearch;
3792 while ((*cptr ==
' ') || (*cptr ==
'\t')) {
3796 if (*cptr ==
'\0') {
3804 goto ContinueSearch;
3808 if ((*cptr ==
'0') && ((*(cptr + 1) ==
'x') || (*(cptr + 1) ==
'X'))) {
3813 if (*(cptr +
index) ==
' ' ||
3814 *(cptr +
index) ==
'\t' ||
3815 *(cptr +
index) ==
';') {
3819 if ((*(cptr +
index) >=
'0') && (*(cptr +
index) <=
'9')) {
3822 if ((*(cptr +
index) >=
'a') && (*(cptr +
index) <=
'f')) {
3824 }
else if ((*(cptr +
index) >=
'A') && (*(cptr +
index) <=
'F')) {
3837 if (*(cptr +
index) ==
' ' ||
3838 *(cptr +
index) ==
'\t' ||
3839 *(cptr +
index) ==
';') {
3843 if ((*(cptr +
index) >=
'0') && (*(cptr +
index) <=
'9')) {
3858 if (*cptr++ ==
';') {
3859 goto ContinueSearch;
3899 goto ReturnCallback;
3908 goto ReturnEnableIntr;
3949 goto ReturnCallback;
3954 if(CrNtInterlockedExchangeAdd(&(chan->
DisableIntr), 0)) {
3957#ifdef UNIATA_USE_XXableInterrupts
3987 chan = &(deviceExtension->
chan[
c]);
4060 checked |= ~deviceExtension->AHCI_PI;
4093 if((checked>>
c) & 0x01)
4100 checked |= (
ULONG)1 <<
c;
4104 if(CrNtInterlockedExchangeAdd(&(deviceExtension->
chan[
c].
DisableIntr), 0)) {
4194 IN PVOID Isr2HwDeviceExtension
4226 checked |= ~deviceExtension->AHCI_PI;
4241 if((checked>>
c) & 0x01)
4244 checked |= (
ULONG)1 <<
c;
4246 if(CrNtInterlockedExchangeAdd(&(deviceExtension->
chan[
c].
DisableIntr), 0)) {
4344 chan = &(deviceExtension->
chan[
c]);