Annotation of ntddk/src/scsi/aha174x/aha174x.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1991  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     aha174x.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This is the port driver for the AHA174X SCSI adapter.
        !            12: 
        !            13: Authors:
        !            14: 
        !            15:     Mike Glass
        !            16: 
        !            17: Environment:
        !            18: 
        !            19:     kernel mode only
        !            20: 
        !            21: Notes:
        !            22: 
        !            23: Revision History:
        !            24: 
        !            25: --*/
        !            26: 
        !            27: #include "miniport.h"
        !            28: #include "aha174x.h"           // includes scsi.h
        !            29: 
        !            30: //
        !            31: // Device extension
        !            32: //
        !            33: 
        !            34: typedef struct _HW_DEVICE_EXTENSION {
        !            35: 
        !            36:     PEISA_CONTROLLER EisaController;
        !            37: 
        !            38:     UCHAR HostTargetId;
        !            39: 
        !            40:     PSCSI_REQUEST_BLOCK PendingSrb;
        !            41: 
        !            42:     UCHAR RequestCount[8][8];
        !            43: 
        !            44: } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
        !            45: 
        !            46: //
        !            47: // Define the maximum number of outstanding I/O requests per logical unit.
        !            48: //
        !            49: 
        !            50: #define MAX_QUEUE_DEPTH 2
        !            51: 
        !            52: 
        !            53: //
        !            54: // Function declarations
        !            55: //
        !            56: // Functions that start with 'Aha174x' are entry points
        !            57: // for the OS port driver.
        !            58: //
        !            59: 
        !            60: ULONG
        !            61: DriverEntry(
        !            62:     IN PVOID DriverObject,
        !            63:     IN PVOID Argument2
        !            64:     );
        !            65: 
        !            66: ULONG
        !            67: Aha174xEntry(
        !            68:     IN PVOID DriverObject,
        !            69:     IN PVOID Argument2
        !            70:     );
        !            71: 
        !            72: ULONG
        !            73: Aha174xConfiguration(
        !            74:     IN PVOID DeviceExtension,
        !            75:     IN PVOID Context,
        !            76:     IN PVOID BusInformation,
        !            77:     IN PCHAR ArgumentString,
        !            78:     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
        !            79:     OUT PBOOLEAN Again
        !            80:     );
        !            81: 
        !            82: BOOLEAN
        !            83: Aha174xInitialize(
        !            84:     IN PVOID DeviceExtension
        !            85:     );
        !            86: 
        !            87: BOOLEAN
        !            88: Aha174xStartIo(
        !            89:     IN PVOID DeviceExtension,
        !            90:     IN PSCSI_REQUEST_BLOCK Srb
        !            91:     );
        !            92: 
        !            93: BOOLEAN
        !            94: Aha174xInterrupt(
        !            95:     IN PVOID DeviceExtension
        !            96:     );
        !            97: 
        !            98: BOOLEAN
        !            99: Aha174xResetBus(
        !           100:     IN PVOID HwDeviceExtension,
        !           101:     IN ULONG PathId
        !           102:     );
        !           103: 
        !           104: //
        !           105: // This function is called from Aha174xStartIo.
        !           106: //
        !           107: 
        !           108: VOID
        !           109: A174xBuildEcb(
        !           110:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !           111:     IN PSCSI_REQUEST_BLOCK Srb
        !           112:     );
        !           113: 
        !           114: //
        !           115: // This function is called from A174xBuildEcb.
        !           116: //
        !           117: 
        !           118: VOID
        !           119: A174xBuildSgl(
        !           120:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !           121:     IN PSCSI_REQUEST_BLOCK Srb
        !           122:     );
        !           123: 
        !           124: VOID
        !           125: A174xBuildRequestSense(
        !           126:     IN PVOID HwDeviceExtension,
        !           127:     IN PSCSI_REQUEST_BLOCK Srb
        !           128:     );
        !           129: 
        !           130: BOOLEAN
        !           131: A174xSendCommand(
        !           132:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !           133:     IN UCHAR OperationCode,
        !           134:     IN ULONG Address
        !           135:     );
        !           136: 
        !           137: //
        !           138: // This function is called from Aha174xInterrupt.
        !           139: //
        !           140: 
        !           141: VOID
        !           142: A174xMapStatus(
        !           143:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !           144:     IN PSCSI_REQUEST_BLOCK Srb,
        !           145:     IN PSTATUS_BLOCK StatusBlock
        !           146:     );
        !           147: 
        !           148: 
        !           149: ULONG
        !           150: DriverEntry (
        !           151:     IN PVOID DriverObject,
        !           152:     IN PVOID Argument2
        !           153:     )
        !           154: 
        !           155: /*++
        !           156: 
        !           157: Routine Description:
        !           158: 
        !           159:     Installable driver initialization entry point for system.
        !           160: 
        !           161: Arguments:
        !           162: 
        !           163:     Driver Object
        !           164: 
        !           165: Return Value:
        !           166: 
        !           167:     Status from ScsiPortInitialize()
        !           168: 
        !           169: --*/
        !           170: 
        !           171: {
        !           172:     return Aha174xEntry(DriverObject, Argument2);
        !           173: 
        !           174: } // end DriverEntry()
        !           175: 
        !           176: 
        !           177: ULONG
        !           178: Aha174xEntry(
        !           179:     IN PVOID DriverObject,
        !           180:     IN PVOID Argument2
        !           181:     )
        !           182: 
        !           183: /*++
        !           184: 
        !           185: Routine Description:
        !           186: 
        !           187:     This routine is called from DriverEntry if this driver is installable
        !           188:     or directly from the system if the driver is built into the kernel.
        !           189:     It scans the EISA slots looking for an AHA174X that is configured
        !           190:     to the ENHANCED mode.
        !           191: 
        !           192: Arguments:
        !           193: 
        !           194:     Driver Object
        !           195: 
        !           196: Return Value:
        !           197: 
        !           198:     Status from ScsiPortInitialize()
        !           199: 
        !           200: --*/
        !           201: 
        !           202: {
        !           203:     HW_INITIALIZATION_DATA hwInitializationData;
        !           204:     ULONG i;
        !           205:     ULONG AdapterCount = 0;
        !           206: 
        !           207:     DebugPrint((1,"\n\nSCSI Aha174x MiniPort Driver\n"));
        !           208: 
        !           209:     //
        !           210:     // Zero out structure.
        !           211:     //
        !           212: 
        !           213:     for (i=0; i<sizeof(HW_INITIALIZATION_DATA); i++) {
        !           214:        ((PUCHAR)&hwInitializationData)[i] = 0;
        !           215:     }
        !           216: 
        !           217:     //
        !           218:     // Set size of hwInitializationData.
        !           219:     //
        !           220: 
        !           221:     hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
        !           222: 
        !           223:     //
        !           224:     // Set entry points.
        !           225:     //
        !           226: 
        !           227:     hwInitializationData.HwInitialize = Aha174xInitialize;
        !           228:     hwInitializationData.HwFindAdapter = Aha174xConfiguration;
        !           229:     hwInitializationData.HwStartIo = Aha174xStartIo;
        !           230:     hwInitializationData.HwInterrupt = Aha174xInterrupt;
        !           231:     hwInitializationData.HwResetBus = Aha174xResetBus;
        !           232: 
        !           233:     //
        !           234:     // Set number of access ranges and bus type.
        !           235:     //
        !           236: 
        !           237:     hwInitializationData.NumberOfAccessRanges = 2;
        !           238:     hwInitializationData.AdapterInterfaceType = Eisa;
        !           239: 
        !           240:     //
        !           241:     // Indicate no buffer mapping but will need physical addresses.
        !           242:     //
        !           243: 
        !           244:     hwInitializationData.NeedPhysicalAddresses = TRUE;
        !           245: 
        !           246:     //
        !           247:     // Indicate auto request sense is supported.
        !           248:     //
        !           249: 
        !           250:     hwInitializationData.MultipleRequestPerLu = TRUE;
        !           251:     hwInitializationData.AutoRequestSense = TRUE;
        !           252: 
        !           253:     //
        !           254:     // Specify size of extensions.
        !           255:     //
        !           256: 
        !           257:     hwInitializationData.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
        !           258: 
        !           259:     //
        !           260:     // Ask for SRB extensions for ECBs.
        !           261:     //
        !           262: 
        !           263:     hwInitializationData.SrbExtensionSize = sizeof(ECB);
        !           264: 
        !           265:     return ScsiPortInitialize(DriverObject, Argument2, &hwInitializationData, &AdapterCount);
        !           266: 
        !           267: } // end Aha174xEntry()
        !           268: 
        !           269: 
        !           270: ULONG
        !           271: Aha174xConfiguration(
        !           272:     IN PVOID HwDeviceExtension,
        !           273:     IN PVOID Context,
        !           274:     IN PVOID BusInformation,
        !           275:     IN PCHAR ArgumentString,
        !           276:     IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
        !           277:     OUT PBOOLEAN Again
        !           278:     )
        !           279: 
        !           280: /*++
        !           281: 
        !           282: Routine Description:
        !           283: 
        !           284:     This function is called by the OS-specific port driver after
        !           285:     the necessary storage has been allocated, to gather information
        !           286:     about the adapter's configuration.
        !           287: 
        !           288: Arguments:
        !           289: 
        !           290:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !           291:     ConfigInfo - Configuration information structure describing HBA
        !           292: 
        !           293: Return Value:
        !           294: 
        !           295:     TRUE if adapter present in system
        !           296: 
        !           297: --*/
        !           298: 
        !           299: {
        !           300:     PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
        !           301:     PEISA_CONTROLLER eisaController;
        !           302:     ULONG eisaSlotNumber;
        !           303:     PVOID eisaAddress;
        !           304:     UCHAR dataByte;
        !           305:     PULONG adapterCount = Context;
        !           306: 
        !           307:     //
        !           308:     // Check to see if adapter present in system.
        !           309:     //
        !           310: 
        !           311:     for (eisaSlotNumber=*adapterCount + 1; eisaSlotNumber<MAXIMUM_EISA_SLOTS; eisaSlotNumber++) {
        !           312: 
        !           313:         //
        !           314:         // Update the adapter count to indicate this slot has been checked.
        !           315:         //
        !           316: 
        !           317:         (*adapterCount)++;
        !           318: 
        !           319:         //
        !           320:         // Get the system address for this card.
        !           321:         // The card uses I/O space.
        !           322:         //
        !           323: 
        !           324:         eisaAddress = ScsiPortGetDeviceBase(deviceExtension,
        !           325:                                                ConfigInfo->AdapterInterfaceType,
        !           326:                                                ConfigInfo->SystemIoBusNumber,
        !           327:                                                ScsiPortConvertUlongToPhysicalAddress(0x1000 * eisaSlotNumber),
        !           328:                                                0x1000,
        !           329:                                                TRUE);
        !           330: 
        !           331:         eisaController =
        !           332:             (PEISA_CONTROLLER)((PUCHAR)eisaAddress + EISA_ADDRESS_BASE);
        !           333: 
        !           334:         if ((ScsiPortReadPortUchar(&eisaController->BoardId[0]) == 0x04) &&
        !           335:             (ScsiPortReadPortUchar(&eisaController->BoardId[1]) == 0x90) &&
        !           336:             (ScsiPortReadPortUchar(&eisaController->BoardId[2]) == 0x00)) {
        !           337: 
        !           338:             DebugPrint((1,"AHA174X: Adapter found at EISA slot %d\n",
        !           339:                 eisaSlotNumber));
        !           340: #ifdef MIPS
        !           341:            //
        !           342:            // Add code to configure the device if necessary.  This is only
        !           343:            // needed until we get an EISA configuration program.
        !           344:            //
        !           345: 
        !           346:            if (!(ScsiPortReadPortUchar(&eisaController->EBControl) & 0x1)) {
        !           347: 
        !           348:                //
        !           349:                // The card as not been configured.  Jam in a default one.
        !           350:                // Enable the card, enable enhanced mode operation, set the
        !           351:                // irql to 14, set the target id to 7 and enable the DMA.
        !           352:                //
        !           353: 
        !           354:                ScsiPortWritePortUchar(&eisaController->EBControl, 1);
        !           355:                ScsiPortWritePortUchar(&eisaController->PortAddress, 0x80);
        !           356:                ScsiPortWritePortUchar(&eisaController->BiosAddress, 0x00);
        !           357:                ScsiPortWritePortUchar(&eisaController->Interrupt, 0x1d);
        !           358:                ScsiPortWritePortUchar(&eisaController->ScsiId, 0x7);
        !           359:                ScsiPortWritePortUchar(&eisaController->DmaChannel, 0x2);
        !           360:                ScsiPortStallExecution(1000);
        !           361: 
        !           362:            }
        !           363: #endif
        !           364:            if (ScsiPortReadPortUchar(&eisaController->PortAddress) &
        !           365:                 ENHANCED_INTERFACE_ENABLED) {
        !           366: 
        !           367:                 //
        !           368:                 // An adapter with the enhanced interface enabled was found.
        !           369:                 //
        !           370: 
        !           371:                 break;
        !           372: 
        !           373:             } else {
        !           374: 
        !           375:                 DebugPrint((1,"AHA174X: Adapter is in STANDARD mode\n"));
        !           376:             }
        !           377:         }
        !           378: 
        !           379:         //
        !           380:         // If an adapter was not found unmap it.
        !           381:         //
        !           382: 
        !           383:         ScsiPortFreeDeviceBase(deviceExtension,
        !           384:                                eisaAddress);
        !           385: 
        !           386:     } // end for (eisaSlotNumber ...
        !           387: 
        !           388:     if (!(eisaSlotNumber < MAXIMUM_EISA_SLOTS)) {
        !           389: 
        !           390:         //
        !           391:         // No adapter was found.  Indicate that we are done and there are no
        !           392:         // more adapters here. Clear the adapter count for the next bus.
        !           393:         //
        !           394: 
        !           395:         *Again = FALSE;
        !           396:         *adapterCount = 0;
        !           397:         return SP_RETURN_NOT_FOUND;
        !           398:     }
        !           399: 
        !           400:     //
        !           401:     // There is still more to look at.
        !           402:     //
        !           403: 
        !           404:     *Again = TRUE;
        !           405: 
        !           406:     //
        !           407:     // Store base address of EISA registers in device extension.
        !           408:     //
        !           409: 
        !           410:     deviceExtension->EisaController = eisaController;
        !           411: 
        !           412:     ConfigInfo->InitiatorBusId[0] =
        !           413:         ScsiPortReadPortUchar(&eisaController->ScsiId) & 0x0F;
        !           414: 
        !           415:     deviceExtension->HostTargetId = ConfigInfo->InitiatorBusId[0];
        !           416: 
        !           417:     //
        !           418:     // Indicate maximum transfer length in bytes.
        !           419:     //
        !           420: 
        !           421:     ConfigInfo->MaximumTransferLength = MAXIMUM_TRANSFER_SIZE;
        !           422: 
        !           423:     //
        !           424:     // Maximum number of physical segments is 32.
        !           425:     //
        !           426: 
        !           427:     ConfigInfo->NumberOfPhysicalBreaks = MAXIMUM_SGL_DESCRIPTORS;
        !           428: 
        !           429:     ConfigInfo->ScatterGather = TRUE;
        !           430:     ConfigInfo->Master = TRUE;
        !           431:     ConfigInfo->NumberOfBuses = 1;
        !           432: 
        !           433:     //
        !           434:     // Get the system interrupt vector and IRQL.
        !           435:     //
        !           436: 
        !           437:     dataByte = ScsiPortReadPortUchar(&eisaController->Interrupt);
        !           438:     ConfigInfo->BusInterruptLevel = (dataByte & 7) + 9;
        !           439: 
        !           440:     //
        !           441:     // Determine level or edge interrupt.
        !           442:     //
        !           443: 
        !           444:     ConfigInfo->InterruptMode = dataByte & 0x08 ? Latched : LevelSensitive;
        !           445: 
        !           446:     //
        !           447:     // Fill in the access array information.
        !           448:     //
        !           449: 
        !           450:     (*ConfigInfo->AccessRanges)[0].RangeStart =
        !           451:         ScsiPortConvertUlongToPhysicalAddress(0x1000 * eisaSlotNumber + EISA_ADDRESS_BASE);
        !           452:     (*ConfigInfo->AccessRanges)[0].RangeLength = sizeof(EISA_CONTROLLER);
        !           453:     (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
        !           454: 
        !           455: 
        !           456:     //
        !           457:     // Determine the BIOS address.
        !           458:     //
        !           459: 
        !           460:     dataByte = ScsiPortReadPortUchar(&eisaController->BiosAddress);
        !           461: 
        !           462:     if (dataByte & BIOS_ENABLED) {
        !           463: 
        !           464:         dataByte &= BIOS_ADDRESS;
        !           465: 
        !           466:         //
        !           467:         // Calculate the bios base address.
        !           468:         //
        !           469: 
        !           470:         eisaSlotNumber = 0xC0000 + (dataByte * 0x4000);
        !           471: 
        !           472:         if (eisaSlotNumber < 0xF0000) {
        !           473: 
        !           474:             DebugPrint((1, "Aha174xConfiguration: Bios address at: %lx.\n", eisaSlotNumber));
        !           475:             (*ConfigInfo->AccessRanges)[1].RangeStart =
        !           476:                 ScsiPortConvertUlongToPhysicalAddress(eisaSlotNumber);
        !           477:             (*ConfigInfo->AccessRanges)[1].RangeLength = BIOS_LENGTH;
        !           478:             (*ConfigInfo->AccessRanges)[1].RangeInMemory = TRUE;
        !           479: 
        !           480:         }
        !           481:     }
        !           482: 
        !           483:     return SP_RETURN_FOUND;
        !           484: 
        !           485: } // end Aha174xConfiguration()
        !           486: 
        !           487: 
        !           488: BOOLEAN
        !           489: Aha174xInitialize(
        !           490:     IN PVOID HwDeviceExtension
        !           491:     )
        !           492: 
        !           493: /*++
        !           494: 
        !           495: Routine Description:
        !           496: 
        !           497:     Inititialize adapter and mailbox.
        !           498: 
        !           499: Arguments:
        !           500: 
        !           501:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !           502: 
        !           503: Return Value:
        !           504: 
        !           505:     TRUE - if initialization successful.
        !           506:     FALSE - if initialization unsuccessful.
        !           507: 
        !           508: --*/
        !           509: 
        !           510: {
        !           511:     PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
        !           512: 
        !           513:     //
        !           514:     // Reset Aha174x and SCSI bus.
        !           515:     //
        !           516: 
        !           517:     if (!Aha174xResetBus(deviceExtension, 0)) {
        !           518: 
        !           519:         DebugPrint((1, "Aha174xInitialize: Reset bus failed\n"));
        !           520:         return FALSE;
        !           521: 
        !           522:     } else {
        !           523: 
        !           524:         ScsiPortNotification(ResetDetected, deviceExtension, 0);
        !           525: 
        !           526:         return TRUE;
        !           527:     }
        !           528: 
        !           529: } // end Aha174xInitialize()
        !           530: 
        !           531: 
        !           532: BOOLEAN
        !           533: Aha174xStartIo(
        !           534:     IN PVOID HwDeviceExtension,
        !           535:     IN PSCSI_REQUEST_BLOCK Srb
        !           536:     )
        !           537: 
        !           538: /*++
        !           539: 
        !           540: Routine Description:
        !           541: 
        !           542:     This routine is called from the SCSI port driver synchronized
        !           543:     with the kernel to send an ECB or issue an immediate command.
        !           544: 
        !           545: Arguments:
        !           546: 
        !           547:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !           548:     Srb - IO request packet
        !           549: 
        !           550: Return Value:
        !           551: 
        !           552:     TRUE
        !           553: 
        !           554: --*/
        !           555: 
        !           556: {
        !           557:     PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
        !           558:     PEISA_CONTROLLER eisaController = deviceExtension->EisaController;
        !           559:     PECB ecb;
        !           560:     PSCSI_REQUEST_BLOCK abortedSrb;
        !           561:     UCHAR opCode;
        !           562:     ULONG physicalEcb;
        !           563:     ULONG length;
        !           564:     ULONG i = 0;
        !           565:     UCHAR count = MAX_QUEUE_DEPTH;
        !           566: 
        !           567:     ASSERT(Srb->SrbStatus == SRB_STATUS_PENDING);
        !           568: 
        !           569:     //
        !           570:     // Get ECB from SRB.
        !           571:     //
        !           572: 
        !           573:     if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND) {
        !           574: 
        !           575:         //
        !           576:         // Verify that SRB to abort is still outstanding.
        !           577:         //
        !           578: 
        !           579:         abortedSrb = ScsiPortGetSrb(deviceExtension,
        !           580:                                        Srb->PathId,
        !           581:                                        Srb->TargetId,
        !           582:                                        Srb->Lun,
        !           583:                                        Srb->QueueTag);
        !           584: 
        !           585:         if (abortedSrb != Srb->NextSrb ||
        !           586:             abortedSrb->SrbStatus != SRB_STATUS_PENDING) {
        !           587: 
        !           588:             DebugPrint((1, "A174xStartIo: SRB to abort already completed\n"));
        !           589: 
        !           590:             //
        !           591:             // Complete abort SRB.
        !           592:             //
        !           593: 
        !           594:             Srb->SrbStatus = SRB_STATUS_ABORT_FAILED;
        !           595: 
        !           596:             ScsiPortNotification(RequestComplete,
        !           597:                                  deviceExtension,
        !           598:                                  Srb);
        !           599:             //
        !           600:             // Adapter ready for next request.
        !           601:             //
        !           602: 
        !           603:             ScsiPortNotification(NextRequest,
        !           604:                                  deviceExtension,
        !           605:                                  NULL);
        !           606: 
        !           607:             return TRUE;
        !           608:         }
        !           609: 
        !           610:         //
        !           611:         // Get ECB to abort.
        !           612:         //
        !           613: 
        !           614:         ecb = Srb->NextSrb->SrbExtension;
        !           615: 
        !           616:         //
        !           617:         // Set abort SRB for completion.
        !           618:         //
        !           619: 
        !           620:         ecb->AbortSrb = Srb;
        !           621: 
        !           622:     } else {
        !           623: 
        !           624:         ecb = Srb->SrbExtension;
        !           625: 
        !           626:         //
        !           627:         // Save SRB back pointer in ECB.
        !           628:         //
        !           629: 
        !           630:         ecb->SrbAddress = Srb;
        !           631:         ecb->AbortSrb = NULL;
        !           632: 
        !           633:     }
        !           634: 
        !           635:     //
        !           636:     // Get ECB physical address.
        !           637:     //
        !           638: 
        !           639:     physicalEcb =
        !           640:         ScsiPortConvertPhysicalAddressToUlong(
        !           641:             ScsiPortGetPhysicalAddress(deviceExtension, NULL, ecb, &length));
        !           642: 
        !           643:     //
        !           644:     // Assume physical address is contiguous for size of ECB.
        !           645:     //
        !           646: 
        !           647:     ASSERT(length >= sizeof(ECB));
        !           648: 
        !           649:     switch (Srb->Function) {
        !           650: 
        !           651:         case SRB_FUNCTION_EXECUTE_SCSI:
        !           652: 
        !           653:             //
        !           654:             // Build ECB for regular request or request sense.
        !           655:             //
        !           656: 
        !           657:             if (Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
        !           658:                 A174xBuildRequestSense(deviceExtension, Srb);
        !           659:             } else {
        !           660:                 A174xBuildEcb(deviceExtension, Srb);
        !           661:             }
        !           662: 
        !           663:             //
        !           664:             // Increment the request count.
        !           665:             //
        !           666: 
        !           667:             count = ++deviceExtension->RequestCount[Srb->TargetId][Srb->Lun];
        !           668: 
        !           669:             opCode = START_ECB;
        !           670: 
        !           671:             break;
        !           672: 
        !           673:         case SRB_FUNCTION_ABORT_COMMAND:
        !           674: 
        !           675:             DebugPrint((1, "Aha174xStartIo: Abort request received\n"));
        !           676: 
        !           677:             opCode = ABORT_ECB;
        !           678: 
        !           679:             break;
        !           680: 
        !           681:         default:
        !           682: 
        !           683:             //
        !           684:             // Set error, complete request
        !           685:             // and signal ready for next request.
        !           686:             //
        !           687: 
        !           688:             Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
        !           689: 
        !           690:             ScsiPortNotification(RequestComplete,
        !           691:                          deviceExtension,
        !           692:                          Srb);
        !           693: 
        !           694:             ScsiPortNotification(NextRequest,
        !           695:                          deviceExtension,
        !           696:                          NULL);
        !           697: 
        !           698:             return TRUE;
        !           699: 
        !           700:     } // end switch
        !           701: 
        !           702:     if (!A174xSendCommand(deviceExtension,
        !           703:                           (UCHAR)(opCode | Srb->TargetId),
        !           704:                           physicalEcb)) {
        !           705: 
        !           706:         DebugPrint((1,"Aha174xStartIo: Send command timed out\n"));
        !           707: 
        !           708:         //
        !           709:         // Save the request utill a  pending one completes.
        !           710:         //
        !           711: 
        !           712:         deviceExtension->PendingSrb = Srb;
        !           713: 
        !           714:         return(TRUE);
        !           715: 
        !           716:     }
        !           717: 
        !           718:     //
        !           719:     // Adapter ready for next request.
        !           720:     //
        !           721: 
        !           722:     if (count < MAX_QUEUE_DEPTH) {
        !           723: 
        !           724:         //
        !           725:         // Request another request for this logical unit.
        !           726:         //
        !           727: 
        !           728:         ScsiPortNotification(NextLuRequest,
        !           729:                              deviceExtension,
        !           730:                              Srb->PathId,
        !           731:                              Srb->TargetId,
        !           732:                              Srb->Lun);
        !           733: 
        !           734:     } else {
        !           735: 
        !           736:         //
        !           737:         // Request another request for this adapter.
        !           738:         //
        !           739: 
        !           740:         ScsiPortNotification(NextRequest,
        !           741:                              deviceExtension,
        !           742:                              Srb->PathId,
        !           743:                              Srb->TargetId,
        !           744:                              Srb->Lun);
        !           745: 
        !           746:     }
        !           747: 
        !           748:     return TRUE;
        !           749: 
        !           750: } // end Aha174xStartIo()
        !           751: 
        !           752: 
        !           753: BOOLEAN
        !           754: Aha174xInterrupt(
        !           755:     IN PVOID HwDeviceExtension
        !           756:     )
        !           757: 
        !           758: /*++
        !           759: 
        !           760: Routine Description:
        !           761: 
        !           762:     This is the interrupt service routine for the Aha174x SCSI adapter.
        !           763:     It reads the interrupt register to determine if the adapter is indeed
        !           764:     the source of the interrupt and clears the interrupt at the device.
        !           765:     If the adapter is interrupting because a mailbox is full, the ECB is
        !           766:     retrieved to complete the request.
        !           767: 
        !           768: Arguments:
        !           769: 
        !           770:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !           771: 
        !           772: Return Value:
        !           773: 
        !           774:     TRUE if MailboxIn full
        !           775: 
        !           776: --*/
        !           777: 
        !           778: {
        !           779:     PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
        !           780:     PECB ecb;
        !           781:     PSCSI_REQUEST_BLOCK srb;
        !           782:     PEISA_CONTROLLER eisaController = deviceExtension->EisaController;
        !           783:     PSTATUS_BLOCK statusBlock;
        !           784:     UCHAR targetId;
        !           785:     UCHAR lun;
        !           786:     ULONG physicalEcb;
        !           787:     UCHAR interruptStatus;
        !           788: 
        !           789:     //
        !           790:     // Check interrupt pending.
        !           791:     //
        !           792: 
        !           793:     if (!(ScsiPortReadPortUchar(&eisaController->Status) &
        !           794:         INTERRUPT_PENDING)) {
        !           795: 
        !           796:         DebugPrint((4, "Aha174xInterrupt: Spurious interrupt\n"));
        !           797:         return FALSE;
        !           798:     }
        !           799: 
        !           800:     //
        !           801:     // Read interrupt status.
        !           802:     //
        !           803: 
        !           804:     interruptStatus = ScsiPortReadPortUchar(
        !           805:         &eisaController->InterruptStatus);
        !           806: 
        !           807:     //
        !           808:     // Get targetId
        !           809:     //
        !           810: 
        !           811:     targetId = interruptStatus & 0x0F;
        !           812: 
        !           813:     //
        !           814:     // Get physical address of ECB.
        !           815:     //
        !           816: 
        !           817:     physicalEcb = ScsiPortReadPortUlong(&eisaController->MailBoxIn);
        !           818: 
        !           819:     //
        !           820:     // Acknowledge interrupt.
        !           821:     //
        !           822: 
        !           823:     ScsiPortWritePortUchar(&eisaController->Control, CLEAR_INTERRUPT);
        !           824: 
        !           825:     //
        !           826:     // Check for pending requests.  If there is one then start it.
        !           827:     //
        !           828: 
        !           829:     if (deviceExtension->PendingSrb != NULL) {
        !           830: 
        !           831:         srb = deviceExtension->PendingSrb;
        !           832:         deviceExtension->PendingSrb = NULL;
        !           833: 
        !           834:         Aha174xStartIo(deviceExtension, srb);
        !           835: 
        !           836:     }
        !           837: 
        !           838:     switch (interruptStatus>>4) {
        !           839: 
        !           840:         case ECB_COMPLETE_SUCCESS:
        !           841:         case ECB_COMPLETE_SUCCESS_RETRY:
        !           842: 
        !           843:             //
        !           844:             // Get virtual ECB address.
        !           845:             //
        !           846: 
        !           847:             ecb = ScsiPortGetVirtualAddress(deviceExtension, ScsiPortConvertUlongToPhysicalAddress(physicalEcb));
        !           848: 
        !           849:             //
        !           850:             // Make sure this was a valid physical address.
        !           851:             //
        !           852: 
        !           853:             if (ecb == NULL || ecb->SrbAddress == NULL) {
        !           854:                 break;
        !           855:             }
        !           856: 
        !           857:             //
        !           858:             // Get SRB from ECB.
        !           859:             //
        !           860: 
        !           861:             srb = ecb->SrbAddress;
        !           862: 
        !           863:             //
        !           864:             // Clear SRB from ECB.
        !           865:             //
        !           866: 
        !           867:             ecb->SrbAddress = NULL;
        !           868: 
        !           869:             //
        !           870:             // Update SRB statuses.
        !           871:             //
        !           872: 
        !           873:             srb->SrbStatus = SRB_STATUS_SUCCESS;
        !           874:             srb->ScsiStatus = SCSISTAT_GOOD;
        !           875: 
        !           876:             //
        !           877:             // If there is a peneding abort request, then complete it.
        !           878:             // This adapter does not interrupt when an abort completes.
        !           879:             // So one of three cases will occur:
        !           880:             //      The abort succeeds and the command is termainated.
        !           881:             //      The abort is too late and command termainates.
        !           882:             //      The abort fails but the command does not terminate.
        !           883:             // The first two cases are handled by completing the abort when the
        !           884:             // command completes.  The last case is handled by the abort timing
        !           885:             // out.
        !           886:             //
        !           887: 
        !           888:             if (ecb->AbortSrb != NULL) {
        !           889: 
        !           890:                 ecb->AbortSrb->SrbStatus = SRB_STATUS_SUCCESS;
        !           891: 
        !           892:                 //
        !           893:                 // Complete the abort request.
        !           894:                 //
        !           895: 
        !           896:                 ScsiPortNotification(
        !           897:                     RequestComplete,
        !           898:                     deviceExtension,
        !           899:                     ecb->AbortSrb
        !           900:                     );
        !           901: 
        !           902:                 ecb->AbortSrb = NULL;
        !           903:             }
        !           904: 
        !           905:             if (deviceExtension->RequestCount[srb->TargetId][srb->Lun]--
        !           906:                 == MAX_QUEUE_DEPTH) {
        !           907: 
        !           908:                 //
        !           909:                 // The adapter can now take another request for this device.
        !           910:                 //
        !           911: 
        !           912:                 ScsiPortNotification(NextLuRequest,
        !           913:                                      deviceExtension,
        !           914:                                      srb->PathId,
        !           915:                                      srb->TargetId,
        !           916:                                      srb->Lun);
        !           917: 
        !           918:             }
        !           919: 
        !           920:             //
        !           921:             // Call notification routine for the SRB.
        !           922:             //
        !           923: 
        !           924:             ScsiPortNotification(RequestComplete,
        !           925:                     (PVOID)deviceExtension,
        !           926:                     srb);
        !           927: 
        !           928:             return TRUE;
        !           929: 
        !           930:         case ECB_COMPLETE_ERROR:
        !           931: 
        !           932:             //
        !           933:             // Get virtual ECB address.
        !           934:             //
        !           935: 
        !           936:             ecb = ScsiPortGetVirtualAddress(deviceExtension, ScsiPortConvertUlongToPhysicalAddress(physicalEcb));
        !           937: 
        !           938:             //
        !           939:             // Make sure this was a valid physical address.
        !           940:             //
        !           941: 
        !           942:             if (ecb == NULL || ecb->SrbAddress == NULL) {
        !           943:                 break;
        !           944:             }
        !           945: 
        !           946:             //
        !           947:             // Get SRB from ECB.
        !           948:             //
        !           949: 
        !           950:             srb = ecb->SrbAddress;
        !           951: 
        !           952:             //
        !           953:             // Clear SRB from ECB.
        !           954:             //
        !           955: 
        !           956:             ecb->SrbAddress = NULL;
        !           957: 
        !           958:             //
        !           959:             // Get Status Block virtual address.
        !           960:             //
        !           961: 
        !           962:             statusBlock = ScsiPortGetVirtualAddress(deviceExtension,
        !           963:                                          ScsiPortConvertUlongToPhysicalAddress(ecb->StatusBlockAddress));
        !           964: 
        !           965:             //
        !           966:             // If there is a peneding abort request, then complete it.
        !           967:             // This adapter does not interrupt when an abort completes.
        !           968:             // So one of three cases will occur:
        !           969:             //      The abort succeeds and the command is termainated.
        !           970:             //      The abort is too late and command termainates.
        !           971:             //      The abort fails but the command does not terminate.
        !           972:             // The first two cases are handled by completing the abort when the
        !           973:             // command completes.  The last case is handled by the abort timing
        !           974:             // out.
        !           975:             //
        !           976: 
        !           977:             if (ecb->AbortSrb != NULL) {
        !           978: 
        !           979:                 ecb->AbortSrb->SrbStatus = SRB_STATUS_SUCCESS;
        !           980: 
        !           981:                 //
        !           982:                 // Complete the abort request.
        !           983:                 //
        !           984: 
        !           985:                 ScsiPortNotification(
        !           986:                     RequestComplete,
        !           987:                     deviceExtension,
        !           988:                     ecb->AbortSrb
        !           989:                     );
        !           990: 
        !           991:                 ecb->AbortSrb = NULL;
        !           992:             }
        !           993: 
        !           994:             //
        !           995:             // Update SRB status.
        !           996:             //
        !           997: 
        !           998:             A174xMapStatus(deviceExtension, srb, statusBlock);
        !           999: 
        !          1000:             if (deviceExtension->RequestCount[srb->TargetId][srb->Lun]--
        !          1001:                 == MAX_QUEUE_DEPTH) {
        !          1002: 
        !          1003:                 //
        !          1004:                 // The adapter can now take another request for this device.
        !          1005:                 //
        !          1006: 
        !          1007:                 ScsiPortNotification(NextLuRequest,
        !          1008:                                      deviceExtension,
        !          1009:                                      srb->PathId,
        !          1010:                                      srb->TargetId,
        !          1011:                                      srb->Lun);
        !          1012: 
        !          1013:             }
        !          1014: 
        !          1015:             //
        !          1016:             // Call notification routine for the SRB.
        !          1017:             //
        !          1018: 
        !          1019:             ScsiPortNotification(RequestComplete,
        !          1020:                     (PVOID)deviceExtension,
        !          1021:                     srb);
        !          1022: 
        !          1023:             return TRUE;
        !          1024: 
        !          1025:         case IMMEDIATE_COMMAND_SUCCESS:
        !          1026: 
        !          1027:             DebugPrint((2,"Aha174xInterrupt: Immediate command completed\n"));
        !          1028:             return TRUE;
        !          1029: 
        !          1030:         case ASYNCHRONOUS_EVENT_NOTIFICATION:
        !          1031: 
        !          1032:             //
        !          1033:             // Check if bus was reset.
        !          1034:             //
        !          1035: 
        !          1036:             if ((physicalEcb >> 24) == 0x23) {
        !          1037: 
        !          1038:                 //
        !          1039:                 // Clear the reqeust counts.
        !          1040:                 //
        !          1041: 
        !          1042:                 for (targetId = 0; targetId < 8; targetId++) {
        !          1043:                     for (lun = 0; lun < 8; lun++) {
        !          1044: 
        !          1045:                         deviceExtension->RequestCount[targetId][lun] = 0;
        !          1046:                     }
        !          1047:                 }
        !          1048: 
        !          1049:                 //
        !          1050:                 // Complete all outstanding requests.
        !          1051:                 //
        !          1052: 
        !          1053:                 ScsiPortCompleteRequest(deviceExtension,
        !          1054:                                         0,
        !          1055:                                         SP_UNTAGGED,
        !          1056:                                         0,
        !          1057:                                         SRB_STATUS_BUS_RESET);
        !          1058: 
        !          1059: 
        !          1060:                 //
        !          1061:                 // Notify operating system of SCSI bus reset.
        !          1062:                 //
        !          1063: 
        !          1064:                 ScsiPortNotification(ResetDetected,
        !          1065:                                      deviceExtension,
        !          1066:                                      NULL);
        !          1067:             }
        !          1068: 
        !          1069:             return TRUE;
        !          1070: 
        !          1071:         case IMMEDIATE_COMMAND_ERROR:
        !          1072:         default:
        !          1073: 
        !          1074:             DebugPrint((1, "A174xInterrupt: Unrecognized interrupt status %x\n",
        !          1075:                 interruptStatus));
        !          1076: 
        !          1077:             //
        !          1078:             // Log the error.
        !          1079:             //
        !          1080: 
        !          1081:             ScsiPortLogError(
        !          1082:                 HwDeviceExtension,
        !          1083:                 NULL,
        !          1084:                 0,
        !          1085:                 deviceExtension->HostTargetId,
        !          1086:                 0,
        !          1087:                 SP_INTERNAL_ADAPTER_ERROR,
        !          1088:                 1 << 16 | interruptStatus
        !          1089:                 );
        !          1090: 
        !          1091:             return TRUE;
        !          1092: 
        !          1093:     } // end switch
        !          1094: 
        !          1095:     //
        !          1096:     // A bad physcial address was return by the adapter.
        !          1097:     // Log it as an error.
        !          1098:     //
        !          1099: 
        !          1100:     ScsiPortLogError(
        !          1101:         HwDeviceExtension,
        !          1102:         NULL,
        !          1103:         0,
        !          1104:         deviceExtension->HostTargetId,
        !          1105:         0,
        !          1106:         SP_INTERNAL_ADAPTER_ERROR,
        !          1107:         5 << 16 | interruptStatus
        !          1108:         );
        !          1109: 
        !          1110:     return TRUE;
        !          1111: 
        !          1112: } // end Aha174xInterrupt()
        !          1113: 
        !          1114: 
        !          1115: VOID
        !          1116: A174xBuildEcb(
        !          1117:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !          1118:     IN PSCSI_REQUEST_BLOCK Srb
        !          1119:     )
        !          1120: 
        !          1121: /*++
        !          1122: 
        !          1123: Routine Description:
        !          1124: 
        !          1125:     Build ECB for Aha174x.
        !          1126: 
        !          1127: Arguments:
        !          1128: 
        !          1129:     DeviceExtenson
        !          1130:     SRB
        !          1131: 
        !          1132: Return Value:
        !          1133: 
        !          1134:     Nothing.
        !          1135: 
        !          1136: --*/
        !          1137: 
        !          1138: {
        !          1139:     PECB ecb = Srb->SrbExtension;
        !          1140:     PSTATUS_BLOCK statusBlock = &ecb->StatusBlock;
        !          1141:     ULONG length;
        !          1142: 
        !          1143:     //
        !          1144:     // Set ECB command.
        !          1145:     //
        !          1146: 
        !          1147:     ecb->Command = ECB_COMMAND_INITIATOR_COMMAND;
        !          1148: 
        !          1149:     //
        !          1150:     // Disable updating status block on success;
        !          1151:     //
        !          1152: 
        !          1153:     ecb->Flags[0] = ECB_FLAGS_DISABLE_STATUS_BLOCK;
        !          1154: 
        !          1155:     //
        !          1156:     // initialize ECB flags
        !          1157:     //
        !          1158: 
        !          1159:     ecb->Flags[1] = 0;
        !          1160: 
        !          1161:     //
        !          1162:     // Set transfer direction bit.
        !          1163:     //
        !          1164: 
        !          1165:     if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
        !          1166: 
        !          1167:        //
        !          1168:        // Write command.
        !          1169:        //
        !          1170: 
        !          1171:        ecb->Flags[1] |= ECB_FLAGS_WRITE;
        !          1172: 
        !          1173:     } else if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
        !          1174: 
        !          1175:        //
        !          1176:        // Read command.
        !          1177:        //
        !          1178: 
        !          1179:        ecb->Flags[1] |= ECB_FLAGS_READ;
        !          1180:     }
        !          1181: 
        !          1182:     //
        !          1183:     // Check if disconnect explicity forbidden.
        !          1184:     //
        !          1185: 
        !          1186:     if (Srb->SrbFlags & SRB_FLAGS_DISABLE_DISCONNECT) {
        !          1187: 
        !          1188:         ecb->Flags[1] |= ECB_FLAGS_NO_DISCONNECT;
        !          1189:     }
        !          1190: 
        !          1191:     //
        !          1192:     // Set LUN (bits 16, 17 and 18).
        !          1193:     //
        !          1194: 
        !          1195:     ecb->Flags[1] |= Srb->Lun;
        !          1196: 
        !          1197:     //
        !          1198:     // Set CDB length and copy to ECB.
        !          1199:     //
        !          1200: 
        !          1201:     ecb->CdbLength = Srb->CdbLength;
        !          1202:     ScsiPortMoveMemory(ecb->Cdb, Srb->Cdb, Srb->CdbLength);
        !          1203: 
        !          1204:     //
        !          1205:     // Build SGL in ECB if data transfer.
        !          1206:     //
        !          1207: 
        !          1208:     if (Srb->DataTransferLength > 0) {
        !          1209:         ecb->Flags[0] |= ECB_FLAGS_SCATTER_GATHER;
        !          1210:         A174xBuildSgl(DeviceExtension, Srb);
        !          1211:     } else {
        !          1212:         ecb->SglLength = 0;
        !          1213:     }
        !          1214: 
        !          1215:     //
        !          1216:     // Set status block pointer.
        !          1217:     //
        !          1218: 
        !          1219:     ecb->StatusBlockAddress =
        !          1220:         ScsiPortConvertPhysicalAddressToUlong(
        !          1221:             ScsiPortGetPhysicalAddress(DeviceExtension,
        !          1222:                                    NULL,
        !          1223:                                    statusBlock,
        !          1224:                                    &length));
        !          1225: 
        !          1226:     ASSERT(length >= sizeof(STATUS_BLOCK));
        !          1227: 
        !          1228:     //
        !          1229:     // Setup auto sense if necessary.
        !          1230:     //
        !          1231: 
        !          1232:     if (Srb->SenseInfoBufferLength != 0 &&
        !          1233:         !(Srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)) {
        !          1234: 
        !          1235:         //
        !          1236:         // Set the flag to enable auto sense and fill in the address and length
        !          1237:         // of the sense buffer.
        !          1238:         //
        !          1239: 
        !          1240:         ecb->Flags[0] |= ECB_FLAGS_AUTO_REQUEST_SENSE;
        !          1241:         ecb->SenseInfoLength = Srb->SenseInfoBufferLength;
        !          1242:         ecb->SenseInfoAddress = ScsiPortConvertPhysicalAddressToUlong(
        !          1243:             ScsiPortGetPhysicalAddress(DeviceExtension,
        !          1244:                                    Srb,
        !          1245:                                    Srb->SenseInfoBuffer,
        !          1246:                                    &length));
        !          1247: 
        !          1248:         ASSERT(length >= Srb->SenseInfoBufferLength);
        !          1249: 
        !          1250:     } else {
        !          1251: 
        !          1252:         ecb->SenseInfoLength = 0;
        !          1253:     }
        !          1254: 
        !          1255:     //
        !          1256:     // Zero out next ECB, request sense info fields
        !          1257:     // and statuses in status block.
        !          1258:     //
        !          1259: 
        !          1260:     ecb->NextEcb = 0;
        !          1261:     statusBlock->HaStatus = 0;
        !          1262:     statusBlock->TargetStatus = 0;
        !          1263: 
        !          1264:     return;
        !          1265: 
        !          1266: } // end A174xBuildEcb()
        !          1267: 
        !          1268: 
        !          1269: VOID
        !          1270: A174xBuildSgl(
        !          1271:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !          1272:     IN PSCSI_REQUEST_BLOCK Srb
        !          1273:     )
        !          1274: 
        !          1275: /*++
        !          1276: 
        !          1277: Routine Description:
        !          1278: 
        !          1279:     This routine builds a scatter/gather descriptor list for the ECB.
        !          1280: 
        !          1281: Arguments:
        !          1282: 
        !          1283:     DeviceExtension
        !          1284:     Srb
        !          1285: 
        !          1286: Return Value:
        !          1287: 
        !          1288:     None
        !          1289: 
        !          1290: --*/
        !          1291: 
        !          1292: {
        !          1293:     PVOID dataPointer = Srb->DataBuffer;
        !          1294:     ULONG bytesLeft = Srb->DataTransferLength;
        !          1295:     PECB ecb = Srb->SrbExtension;
        !          1296:     PSGL sgl = &ecb->Sgl;
        !          1297:     ULONG physicalSgl;
        !          1298:     ULONG physicalAddress;
        !          1299:     ULONG length;
        !          1300:     ULONG descriptorCount = 0;
        !          1301: 
        !          1302:     //
        !          1303:     // Get physical SGL address.
        !          1304:     //
        !          1305: 
        !          1306:     physicalSgl = ScsiPortConvertPhysicalAddressToUlong(
        !          1307:         ScsiPortGetPhysicalAddress(DeviceExtension, NULL,
        !          1308:         sgl, &length));
        !          1309: 
        !          1310:     //
        !          1311:     // Assume physical memory contiguous for sizeof(SGL) bytes.
        !          1312:     //
        !          1313: 
        !          1314:     ASSERT(length >= sizeof(SGL));
        !          1315: 
        !          1316:     //
        !          1317:     // Create SGL segment descriptors.
        !          1318:     //
        !          1319: 
        !          1320:     do {
        !          1321: 
        !          1322:         //
        !          1323:         // Get physical address and length of contiguous
        !          1324:         // physical buffer.
        !          1325:         //
        !          1326: 
        !          1327:         physicalAddress =
        !          1328:             ScsiPortConvertPhysicalAddressToUlong(
        !          1329:                 ScsiPortGetPhysicalAddress(DeviceExtension,
        !          1330:                                        Srb,
        !          1331:                                        dataPointer,
        !          1332:                                        &length));
        !          1333: 
        !          1334:         //
        !          1335:         // If length of physical memory is more
        !          1336:         // than bytes left in transfer, use bytes
        !          1337:         // left as final length.
        !          1338:         //
        !          1339: 
        !          1340:         if  (length > bytesLeft) {
        !          1341:             length = bytesLeft;
        !          1342:         }
        !          1343: 
        !          1344:         sgl->Descriptor[descriptorCount].Address = physicalAddress;
        !          1345:         sgl->Descriptor[descriptorCount].Length = length;
        !          1346: 
        !          1347:         //
        !          1348:         // Adjust counts.
        !          1349:         //
        !          1350: 
        !          1351:         dataPointer = (PUCHAR)dataPointer + length;
        !          1352:         bytesLeft -= length;
        !          1353:         descriptorCount++;
        !          1354: 
        !          1355:     } while (bytesLeft);
        !          1356: 
        !          1357:     //
        !          1358:     // Write SGL length to ECB.
        !          1359:     //
        !          1360: 
        !          1361:     ecb->SglLength = descriptorCount * sizeof(SG_DESCRIPTOR);
        !          1362: 
        !          1363:     //
        !          1364:     // Write SGL address to ECB.
        !          1365:     //
        !          1366: 
        !          1367:     ecb->PhysicalSgl = physicalSgl;
        !          1368: 
        !          1369:     return;
        !          1370: 
        !          1371: } // end A174xBuildSgl()
        !          1372: 
        !          1373: 
        !          1374: VOID
        !          1375: A174xBuildRequestSense(
        !          1376:     IN PVOID HwDeviceExtension,
        !          1377:     IN PSCSI_REQUEST_BLOCK Srb
        !          1378:     )
        !          1379: 
        !          1380: /*++
        !          1381: 
        !          1382: Routine Description:
        !          1383: 
        !          1384:     This routine is called when a request sense is detected. An adapter
        !          1385:     command is then built for a request sense. This is the
        !          1386:     only way to clear the contingent alligience condition that the adapter
        !          1387:     is always in following a check condition.
        !          1388: 
        !          1389: Arguments:
        !          1390: 
        !          1391:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !          1392:     Srb - IO request packet
        !          1393: 
        !          1394: Return Value:
        !          1395: 
        !          1396:     TRUE is request succeeds.
        !          1397: 
        !          1398: --*/
        !          1399: 
        !          1400: {
        !          1401:     PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
        !          1402:     PEISA_CONTROLLER eisaController = deviceExtension->EisaController;
        !          1403:     PECB ecb = Srb->SrbExtension;
        !          1404:     PSTATUS_BLOCK statusBlock = &ecb->StatusBlock;
        !          1405:     ULONG length;
        !          1406: 
        !          1407:     //
        !          1408:     // Set ECB command.
        !          1409:     //
        !          1410: 
        !          1411:     ecb->Command = ECB_COMMAND_READ_SENSE_INFO;
        !          1412: 
        !          1413:     //
        !          1414:     // Disable updating status block on success and enable
        !          1415:     // automatic request senes.
        !          1416:     //
        !          1417: 
        !          1418:     ecb->Flags[0] = ECB_FLAGS_DISABLE_STATUS_BLOCK |
        !          1419:                     ECB_FLAGS_SUPPRESS_UNDERRUN;
        !          1420: 
        !          1421:     //
        !          1422:     // Set transfer direction bit.
        !          1423:     //
        !          1424: 
        !          1425:     ecb->Flags[1] = ECB_FLAGS_READ;
        !          1426: 
        !          1427:     //
        !          1428:     // Check if disconnect explicity forbidden.
        !          1429:     //
        !          1430: 
        !          1431:     if (Srb->SrbFlags & SRB_FLAGS_DISABLE_DISCONNECT) {
        !          1432: 
        !          1433:         ecb->Flags[1] |= ECB_FLAGS_NO_DISCONNECT;
        !          1434:     }
        !          1435: 
        !          1436:     //
        !          1437:     // Set LUN (bits 16, 17 and 18).
        !          1438:     //
        !          1439: 
        !          1440:     ecb->Flags[1] |= Srb->Lun;
        !          1441: 
        !          1442:     //
        !          1443:     // Set status block pointer.
        !          1444:     //
        !          1445: 
        !          1446:     ecb->StatusBlockAddress =
        !          1447:         ScsiPortConvertPhysicalAddressToUlong(
        !          1448:             ScsiPortGetPhysicalAddress(deviceExtension,
        !          1449:                                    NULL,
        !          1450:                                    statusBlock,
        !          1451:                                    &length));
        !          1452: 
        !          1453:     //
        !          1454:     // Set request sense address and length.
        !          1455:     //
        !          1456: 
        !          1457:     ecb->SenseInfoAddress = ScsiPortConvertPhysicalAddressToUlong(
        !          1458:         ScsiPortGetPhysicalAddress(deviceExtension,
        !          1459:                                                        Srb,
        !          1460:                                                        Srb->DataBuffer,
        !          1461:                                                        &length));
        !          1462: 
        !          1463:     ASSERT(length >= Srb->DataTransferLength);
        !          1464: 
        !          1465:     ecb->SenseInfoLength = (UCHAR) Srb->DataTransferLength;
        !          1466: 
        !          1467:     //
        !          1468:     // Zero out next ECB, request sense info fields
        !          1469:     // and statuses in status block.
        !          1470:     //
        !          1471: 
        !          1472:     ecb->NextEcb = 0;
        !          1473:     statusBlock->HaStatus = 0;
        !          1474:     statusBlock->TargetStatus = 0;
        !          1475: 
        !          1476:     return;
        !          1477: 
        !          1478: } // end A174xBuildRequestSense()
        !          1479: 
        !          1480: 
        !          1481: BOOLEAN
        !          1482: A174xSendCommand(
        !          1483:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !          1484:     IN UCHAR OperationCode,
        !          1485:     IN ULONG Address
        !          1486:     )
        !          1487: 
        !          1488: /*++
        !          1489: 
        !          1490: Routine Description:
        !          1491: 
        !          1492:     Send ECB or immediate command to AHA174X.
        !          1493: 
        !          1494: Arguments:
        !          1495: 
        !          1496:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !          1497:     OperationCode - value to be written to attention register
        !          1498:     Address - ECB address or immediate command
        !          1499: 
        !          1500: Return Value:
        !          1501: 
        !          1502:     True if command sent.
        !          1503:     False if adapter never reached 'ready for next command' state.
        !          1504: 
        !          1505: --*/
        !          1506: 
        !          1507: {
        !          1508:     PEISA_CONTROLLER eisaController = DeviceExtension->EisaController;
        !          1509:     ULONG i;
        !          1510: 
        !          1511:     for (i=0; i<10; i++) {
        !          1512: 
        !          1513:         UCHAR status;
        !          1514: 
        !          1515:         status = ScsiPortReadPortUchar(&eisaController->Status);
        !          1516: 
        !          1517:         if ((status & MAILBOX_OUT_EMPTY) &&
        !          1518:             !(status & ADAPTER_BUSY)) {
        !          1519: 
        !          1520:             //
        !          1521:             // Adapter ready for next command.
        !          1522:             //
        !          1523: 
        !          1524:             break;
        !          1525: 
        !          1526:         } else {
        !          1527: 
        !          1528:             //
        !          1529:             // Stall 1 microsecond before trying again.
        !          1530:             //
        !          1531: 
        !          1532:             ScsiPortStallExecution(1);
        !          1533:         }
        !          1534:     }
        !          1535: 
        !          1536:     if (i == 10) {
        !          1537: 
        !          1538:         return FALSE;
        !          1539:     }
        !          1540: 
        !          1541:     //
        !          1542:     // Write ECB address or immediate command.
        !          1543:     //
        !          1544: 
        !          1545:     ScsiPortWritePortUlong(&eisaController->MailBoxOut, Address);
        !          1546: 
        !          1547:     //
        !          1548:     // Write operation code to attention register.
        !          1549:     //
        !          1550: 
        !          1551:     ScsiPortWritePortUchar(&eisaController->Attention, OperationCode);
        !          1552: 
        !          1553:     return TRUE;
        !          1554: 
        !          1555: } // end A174xSendCommand()
        !          1556: 
        !          1557: BOOLEAN
        !          1558: Aha174xResetBus(
        !          1559:     IN PVOID HwDeviceExtension,
        !          1560:     IN ULONG PathId
        !          1561: )
        !          1562: 
        !          1563: /*++
        !          1564: 
        !          1565: Routine Description:
        !          1566: 
        !          1567:     Reset Aha174x SCSI adapter and SCSI bus.
        !          1568: 
        !          1569: Arguments:
        !          1570: 
        !          1571:     HwDeviceExtension - HBA miniport driver's adapter data storage
        !          1572: 
        !          1573: Return Value:
        !          1574: 
        !          1575:     Nothing.
        !          1576: 
        !          1577: --*/
        !          1578: 
        !          1579: {
        !          1580:     PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
        !          1581:     PEISA_CONTROLLER eisaController = deviceExtension->EisaController;
        !          1582:     ULONG j;
        !          1583:     UCHAR targetId;
        !          1584:     UCHAR lun;
        !          1585: 
        !          1586: 
        !          1587:     UNREFERENCED_PARAMETER(PathId);
        !          1588: 
        !          1589:     DebugPrint((2,"ResetBus: Reset Aha174x and SCSI bus\n"));
        !          1590: 
        !          1591:     //
        !          1592:     // Clean up pending requests.
        !          1593:     //
        !          1594: 
        !          1595:     if (deviceExtension->PendingSrb) {
        !          1596: 
        !          1597:         //
        !          1598:         // Notify the port driver that another request can be accepted.
        !          1599:         //
        !          1600: 
        !          1601:         ScsiPortNotification(NextRequest, deviceExtension);
        !          1602: 
        !          1603:         //
        !          1604:         // Clear the pending request.  It will be completed by
        !          1605:         // ScsiPortCompleteRequest.
        !          1606:         //
        !          1607: 
        !          1608:         deviceExtension->PendingSrb = NULL;
        !          1609: 
        !          1610:     }
        !          1611: 
        !          1612:     //
        !          1613:     // Clear the reqeust counts.
        !          1614:     //
        !          1615: 
        !          1616:     for (targetId = 0; targetId < 8; targetId++) {
        !          1617:         for (lun = 0; lun < 8; lun++) {
        !          1618: 
        !          1619:             deviceExtension->RequestCount[targetId][lun] = 0;
        !          1620:         }
        !          1621:     }
        !          1622: 
        !          1623:     //
        !          1624:     // Complete all outstanding requests.
        !          1625:     //
        !          1626: 
        !          1627:     ScsiPortCompleteRequest(deviceExtension,
        !          1628:                             0,
        !          1629:                             SP_UNTAGGED,
        !          1630:                             SP_UNTAGGED,
        !          1631:                             SRB_STATUS_BUS_RESET);
        !          1632: 
        !          1633:     targetId = deviceExtension->HostTargetId;
        !          1634: 
        !          1635:     //
        !          1636:     // Allow the adapter card to settle.
        !          1637:     //
        !          1638: 
        !          1639:     ScsiPortStallExecution(75000);
        !          1640:     ScsiPortReadPortUchar(&eisaController->Status);
        !          1641:     ScsiPortStallExecution(1);
        !          1642: 
        !          1643:     if (!A174xSendCommand(deviceExtension,
        !          1644:                           (UCHAR)(IMMEDIATE_COMMAND | targetId),
        !          1645:                           ECB_IMMEDIATE_RESET)) {
        !          1646: 
        !          1647:         //
        !          1648:         // Timed out waiting for adapter to become ready.
        !          1649:         //
        !          1650: 
        !          1651:         ScsiPortLogError(
        !          1652:             deviceExtension,
        !          1653:             NULL,
        !          1654:             0,
        !          1655:             deviceExtension->HostTargetId,
        !          1656:             0,
        !          1657:             SP_INTERNAL_ADAPTER_ERROR,
        !          1658:             4 << 16
        !          1659:             );
        !          1660: 
        !          1661:         //
        !          1662:         // Adapter never reached state to receive command.
        !          1663:         // Try a hard reset by wiggling the control line.
        !          1664:         //
        !          1665: 
        !          1666:         ScsiPortWritePortUchar(&eisaController->Control, HARD_RESET);
        !          1667: 
        !          1668:         //
        !          1669:         // Wait at least 10 microseconds.
        !          1670:         //
        !          1671: 
        !          1672:         ScsiPortStallExecution(10);
        !          1673: 
        !          1674:         //
        !          1675:         // Clear the reset line now that it has been held for 10 us.
        !          1676:         //
        !          1677: 
        !          1678:         ScsiPortWritePortUchar(&eisaController->Control, 0);
        !          1679: 
        !          1680:         //
        !          1681:         // Write the attention register to wake up the firmware so that
        !          1682:         // it will clear the busy line in the status register.
        !          1683:         // The attention value written (0) is ignored by the controller
        !          1684:         // but will wakeup the firmware.
        !          1685:         //
        !          1686: 
        !          1687:         ScsiPortStallExecution(20000);  // Add a little delay
        !          1688:         ScsiPortWritePortUchar(&eisaController->Attention, 0);
        !          1689: 
        !          1690:         //
        !          1691:         // Wait for busy to go low.
        !          1692:         //
        !          1693: 
        !          1694:         j = 0;
        !          1695:         while (ScsiPortReadPortUchar(&eisaController->Status) & ADAPTER_BUSY) {
        !          1696: 
        !          1697:             j++;
        !          1698:             if (j > 200000) {
        !          1699: 
        !          1700:                 //
        !          1701:                 // Busy has not gone low.  Assume the card is gone.
        !          1702:                 // Log the error and fail the request.
        !          1703:                 //
        !          1704: 
        !          1705: 
        !          1706:                 ScsiPortLogError(
        !          1707:                     deviceExtension,
        !          1708:                     NULL,
        !          1709:                     0,
        !          1710:                     deviceExtension->HostTargetId,
        !          1711:                     0,
        !          1712:                     SP_INTERNAL_ADAPTER_ERROR,
        !          1713:                     3 << 16
        !          1714:                     );
        !          1715: 
        !          1716:                 return FALSE;
        !          1717: 
        !          1718:             }
        !          1719: 
        !          1720:             ScsiPortStallExecution(10);
        !          1721:         }
        !          1722:     }
        !          1723: 
        !          1724:     return TRUE;
        !          1725: 
        !          1726: } // end Aha174xResetBus()
        !          1727: 
        !          1728: 
        !          1729: VOID
        !          1730: A174xMapStatus(
        !          1731:     IN PHW_DEVICE_EXTENSION DeviceExtension,
        !          1732:     IN PSCSI_REQUEST_BLOCK Srb,
        !          1733:     IN PSTATUS_BLOCK StatusBlock
        !          1734:     )
        !          1735: 
        !          1736: /*++
        !          1737: 
        !          1738: Routine Description:
        !          1739: 
        !          1740:     Translate Aha174x error to SRB error.
        !          1741: 
        !          1742: Arguments:
        !          1743: 
        !          1744:     SRB
        !          1745:     Status block for request completing with error.
        !          1746: 
        !          1747: Return Value:
        !          1748: 
        !          1749:     Updated SRB
        !          1750: 
        !          1751: --*/
        !          1752: 
        !          1753: {
        !          1754:     ULONG logError = 0;
        !          1755:     UCHAR srbStatus;
        !          1756:     PECB ecb = Srb->SrbExtension;
        !          1757: 
        !          1758: 
        !          1759:     DebugPrint((2,
        !          1760:                    "A174xMapStatus: Status word is %x\n",
        !          1761:                    StatusBlock->StatusWord));
        !          1762: 
        !          1763:     if (StatusBlock->TargetStatus == SCSISTAT_CHECK_CONDITION) {
        !          1764: 
        !          1765:         //
        !          1766:         // A check condition occured.  Set the srb status and process the
        !          1767:         // auto sense data.
        !          1768:         //
        !          1769: 
        !          1770:         Srb->SrbStatus = SRB_STATUS_ERROR;
        !          1771: 
        !          1772:         //
        !          1773:         // Set target SCSI status in SRB.
        !          1774:         //
        !          1775: 
        !          1776:         Srb->ScsiStatus = StatusBlock->TargetStatus;
        !          1777: 
        !          1778:         //
        !          1779:         // Update SRB with actual bytes transferred.
        !          1780:         //
        !          1781: 
        !          1782:         Srb->DataTransferLength -= StatusBlock->ResidualByteCount;
        !          1783: 
        !          1784:         if (StatusBlock->StatusWord & SB_STATUS_SENSE_INFORMATION) {
        !          1785: 
        !          1786:             //
        !          1787:             // Indicate the sense information is valid and update the length.
        !          1788:             //
        !          1789: 
        !          1790:             Srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
        !          1791:             Srb->SenseInfoBufferLength = StatusBlock->RequestSenseLength;
        !          1792:         }
        !          1793: 
        !          1794:         return;
        !          1795:     }
        !          1796: 
        !          1797:     switch (StatusBlock->HaStatus) {
        !          1798: 
        !          1799:     case SB_HASTATUS_SELECTION_TIMEOUT:
        !          1800:         srbStatus = SRB_STATUS_SELECTION_TIMEOUT;
        !          1801:         break;
        !          1802: 
        !          1803:     case SB_HASTATUS_DATA_OVERUNDER_RUN:
        !          1804:         DebugPrint((1,"A174xMapStatus: Data over/underrun\n"));
        !          1805: 
        !          1806:         //
        !          1807:         // Update SRB with actual bytes transferred.
        !          1808:         //
        !          1809: 
        !          1810:         Srb->DataTransferLength -= StatusBlock->ResidualByteCount;
        !          1811: 
        !          1812:         srbStatus = SRB_STATUS_DATA_OVERRUN;
        !          1813:         break;
        !          1814: 
        !          1815:     case SB_HASTATUS_UNEXPECTED_BUS_FREE:
        !          1816:         DebugPrint((1,"A174xMapStatus: Unexpected bus free\n"));
        !          1817:         logError = SP_PROTOCOL_ERROR;
        !          1818:         srbStatus = SRB_STATUS_UNEXPECTED_BUS_FREE;
        !          1819:         break;
        !          1820: 
        !          1821:     case SB_HASTATUS_INVALID_BUS_PHASE:
        !          1822:         DebugPrint((1,"A174xMapStatus: Invalid bus phase\n"));
        !          1823:         logError = SP_PROTOCOL_ERROR;
        !          1824:         srbStatus = SRB_STATUS_PHASE_SEQUENCE_FAILURE;
        !          1825:         break;
        !          1826: 
        !          1827:     case SB_HASTATUS_TARGET_NOT_USED:
        !          1828:         DebugPrint((1,"A174xMapStatus: Target not used\n"));
        !          1829:         srbStatus = SRB_STATUS_NO_DEVICE;
        !          1830:         break;
        !          1831: 
        !          1832:     case SB_HASTATUS_INVALID_ECB:
        !          1833:         DebugPrint((1,"A174xMapStatus: Invalid ECB\n"));
        !          1834:         logError = SP_INTERNAL_ADAPTER_ERROR;
        !          1835:         srbStatus = SRB_STATUS_INVALID_REQUEST;
        !          1836:         break;
        !          1837: 
        !          1838:     case SB_HASTATUS_ADAPTER_HARDWARE_ERROR:
        !          1839:         DebugPrint((1,"A174xMapStatus: Hardware error\n"));
        !          1840:         logError = SP_INTERNAL_ADAPTER_ERROR;
        !          1841:         srbStatus = SRB_STATUS_ERROR;
        !          1842:         break;
        !          1843: 
        !          1844:     case SB_HASTATUS_ADAPTER_RESET_BUS:
        !          1845:         DebugPrint((1,"A174xMapStatus: Adapter reset bus\n"));
        !          1846:         srbStatus = SRB_STATUS_BUS_RESET;
        !          1847:         break;
        !          1848: 
        !          1849:     case SB_HASTATUS_DEVICE_RESET_BUS:
        !          1850:         DebugPrint((1,"A174xMapStatus: Device reset bus\n"));
        !          1851:         srbStatus = SRB_STATUS_BUS_RESET;
        !          1852:         break;
        !          1853: 
        !          1854:     case SB_HASTATUS_CHECKSUM_FAILURE:
        !          1855:         DebugPrint((1,"A174xMapStatus: Checksum failure\n"));
        !          1856:         logError = SP_INTERNAL_ADAPTER_ERROR;
        !          1857:         srbStatus = SRB_STATUS_ERROR;
        !          1858:         break;
        !          1859: 
        !          1860:     case SB_HASTATUS_ADAPTER_ABORTED:
        !          1861:         DebugPrint((1,"A174xMapStatus: Adapter aborted\n"));
        !          1862:         srbStatus = SRB_STATUS_ABORTED;
        !          1863:         break;
        !          1864: 
        !          1865:     case SB_HASTATUS_HOST_ABORTED:
        !          1866:         DebugPrint((1,"A174xMapStatus: Host aborted\n"));
        !          1867:         srbStatus = SRB_STATUS_ABORTED;
        !          1868:         break;
        !          1869: 
        !          1870:     case SB_HASTATUS_FW_NOT_DOWNLOADED:
        !          1871:         DebugPrint((1,"A174xMapStatus: Firmware not downloaded\n"));
        !          1872:         logError = SP_INTERNAL_ADAPTER_ERROR;
        !          1873:         srbStatus = SRB_STATUS_ERROR;
        !          1874:         break;
        !          1875: 
        !          1876:     case SB_HASTATUS_INVALID_SGL:
        !          1877:         DebugPrint((1,"A174xMapStatus: Invalid SGL\n"));
        !          1878:         logError = SP_INTERNAL_ADAPTER_ERROR;
        !          1879:         srbStatus = SRB_STATUS_INVALID_REQUEST;
        !          1880:         break;
        !          1881: 
        !          1882:     case SB_HASTATUS_REQUEST_SENSE_FAILED:
        !          1883:         DebugPrint((1,"A174xMapStatus: Request sense failed\n"));
        !          1884:         srbStatus = SRB_STATUS_ERROR;
        !          1885:         break;
        !          1886: 
        !          1887:     default:
        !          1888: 
        !          1889:         srbStatus = SRB_STATUS_ERROR;
        !          1890: 
        !          1891:         //
        !          1892:         // Check status block word.
        !          1893:         //
        !          1894: 
        !          1895:         if (StatusBlock->StatusWord & SB_STATUS_NO_ERROR) {
        !          1896: 
        !          1897:             //
        !          1898:             // This should never happen as this routine is only
        !          1899:             // called when there is an error.
        !          1900:             //
        !          1901: 
        !          1902:             DebugPrint((1,"A174xMapStatus: No error\n"));
        !          1903:             srbStatus = SRB_STATUS_SUCCESS;
        !          1904:             break;
        !          1905: 
        !          1906:         }
        !          1907: 
        !          1908:         //
        !          1909:         // Check for underrun.
        !          1910:         //
        !          1911: 
        !          1912:         if (StatusBlock->StatusWord & SB_STATUS_DATA_UNDERRUN) {
        !          1913: 
        !          1914:             DebugPrint((1,
        !          1915:                 "A174xMapStatus: Data underrun indicated in status word\n"));
        !          1916: 
        !          1917:             //
        !          1918:             // Update SRB with actual bytes transferred.
        !          1919:             //
        !          1920: 
        !          1921:             Srb->DataTransferLength -= StatusBlock->ResidualByteCount;
        !          1922:             break;
        !          1923:         }
        !          1924: 
        !          1925:         //
        !          1926:         // Check for overrun.
        !          1927:         //
        !          1928: 
        !          1929:         if (StatusBlock->StatusWord & SB_STATUS_DATA_OVERRUN) {
        !          1930: 
        !          1931:             DebugPrint((1,
        !          1932:                 "A174xMapStatus: Data overrun indicate in status word\n"));
        !          1933:             logError = SP_PROTOCOL_ERROR;
        !          1934:             break;
        !          1935:         }
        !          1936: 
        !          1937:         //
        !          1938:         // Check for initialization required.
        !          1939:         //
        !          1940: 
        !          1941:         if (StatusBlock->StatusWord & SB_STATUS_INIT_REQUIRED) {
        !          1942:             DebugPrint((1,
        !          1943:                 "A174xMapStatus: Initialization required\n"));
        !          1944:             break;
        !          1945:         }
        !          1946: 
        !          1947:         //
        !          1948:         // Check for contingent allegience condition. If this happens
        !          1949:         // something is very wrong (because autorequest sense was indicated).
        !          1950:         //
        !          1951: 
        !          1952:         if (StatusBlock->StatusWord & SB_STATUS_EXT_CONT_ALLEGIANCE) {
        !          1953: 
        !          1954:             DebugPrint((1,
        !          1955:                 "A174xMapStatus: Contingent allegiance condition\n"));
        !          1956: 
        !          1957:             ASSERT(0);
        !          1958:         }
        !          1959: 
        !          1960:         if (StatusBlock->StatusWord & SB_STATUS_MAJOR_ERROR) {
        !          1961: 
        !          1962:             DebugPrint((1,
        !          1963:                 "A174xMapStatus: Major error indicated in status word\n"));
        !          1964:             break;
        !          1965:         }
        !          1966: 
        !          1967:         logError = SP_INTERNAL_ADAPTER_ERROR;
        !          1968:         break;
        !          1969: 
        !          1970:     } // end switch ...
        !          1971: 
        !          1972:     if (logError != 0) {
        !          1973: 
        !          1974:         //
        !          1975:         // Log error.
        !          1976:         //
        !          1977: 
        !          1978:         ScsiPortLogError(
        !          1979:             DeviceExtension,
        !          1980:             Srb,
        !          1981:             Srb->PathId,
        !          1982:             Srb->TargetId,
        !          1983:             Srb->Lun,
        !          1984:             logError,
        !          1985:             2 << 16 | StatusBlock->HaStatus
        !          1986:             );
        !          1987: 
        !          1988:     }
        !          1989: 
        !          1990:     //
        !          1991:     // Set SRB status.
        !          1992:     //
        !          1993: 
        !          1994:     Srb->SrbStatus = srbStatus;
        !          1995: 
        !          1996:     //
        !          1997:     // Set target SCSI status in SRB.
        !          1998:     //
        !          1999: 
        !          2000:     Srb->ScsiStatus = StatusBlock->TargetStatus;
        !          2001: 
        !          2002:     return;
        !          2003: 
        !          2004: } // end A174xMapStatus()

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.