diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/miniport/always/ntmgr.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/miniport/always/ntmgr.c')
-rw-r--r-- | private/ntos/miniport/always/ntmgr.c | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/private/ntos/miniport/always/ntmgr.c b/private/ntos/miniport/always/ntmgr.c new file mode 100644 index 000000000..511f7b4d2 --- /dev/null +++ b/private/ntos/miniport/always/ntmgr.c @@ -0,0 +1,547 @@ +/* Copyright (C) 1991-1994 by Always Technology Corporation. + This module contains information proprietary to + Always Technology Corporation, and is be treated as confidential. +*/ + +#include "environ.h" +#include "rqm.h" +#include "api.h" +#include "apiscsi.h" +#include "debug.h" + +#define HAExtentLen sizeof(struct Adapter) +#define DEVExtentLen sizeof(struct DeviceDescr) +#define REQExtentLen sizeof(struct IOReqExtension) + + +enum ASPI_Priority {NORMAL_REQ, PRIORTY_REQ, IPRIORTY_REQ}; +void IExecuteReq(ADAPTER_PTR HA, DEVICE_PTR DevP, IO_REQ_PTR Req, enum ASPI_Priorty Priorty); + +extern void EnvLib_Init(void); + + +#define FreeDev(DevP) + +#if !defined(APIFindDev) +DEVICE_PTR +APIFindDev (const ADAPTER_PTR HA, const unsigned TID, const unsigned LUN) +{ + + return ScsiPortGetLogicalUnit(HA, 0, (char)TID, (char)LUN); + +} +#endif + + +void +APISetStatus (IO_REQ_PTR Req, // Request structure + APIStatus Status, // Status + TerminateCode Terminal, // Is this the terminal (Notify completion) + AutosenseCode IsSenseable) // Auto sense allowed? +{ + static U8 REQStats[]={ + SRB_STATUS_PENDING, SRB_STATUS_PENDING, SRB_STATUS_ABORTED, + SRB_STATUS_BAD_FUNCTION, SRB_STATUS_INVALID_REQUEST, SRB_STATUS_NO_HBA, + SRB_STATUS_DATA_OVERRUN, SRB_STATUS_SELECTION_TIMEOUT, + SRB_STATUS_INVALID_TARGET_ID, SRB_STATUS_INVALID_LUN + }; + + static U8 ADStats[]={ + SRB_STATUS_NO_HBA, SRB_STATUS_BUSY, SRB_STATUS_UNEXPECTED_BUS_FREE, + SRB_STATUS_PHASE_SEQUENCE_FAILURE, SRB_STATUS_BUS_RESET, + SRB_STATUS_AUTOSENSE_VALID, SRB_STATUS_ERROR}; + + +// Make sure the high numbers match what this module knows of: +#if S_LAST_S_REQ != 0x09 +#err +#endif + +#if S_LAST_S_AD != 0x06 +#err +#endif + +#if S_LAST_S_SYS != 0 +#err +#endif + + + switch (ErrorClass(Status)) { + + case RequestClass: + + DEBUG(0, if (Status == S_REQ_ABORT) + TRACE(0, ("APISetStatus(): Set Req (%x) status to aborted\n")) ); + Req->SrbStatus = REQStats[ErrorCode(Status)]; + break; + + + case AdapterClass: + + Req->SrbStatus = ADStats[ErrorCode(Status)]; + break; + + + case TargetClass: + + Req->ScsiStatus = ErrorCode(Status); + switch (ErrorCode(Status)) { + + case STATUS_CKCOND: + + ReqDataCount(Req) = ReqSavedIndex(Req); +#if defined(AUTOSENSE) + if ((IsSenseable == Senseable) && ReqSenseCount(Req)) { + + Terminal = NonTerminal; + QueueInternalRequest(ReqAdapterPtr(Req), Req, RTAutoSenseReq); + + } else +#endif + Req->SrbStatus = SRB_STATUS_ERROR; + break; + + + case STATUS_GOOD: + case STATUS_CONDMET: + case STATUS_INTGOOD: + case STATUS_INTCONDMET: + + Req->SrbStatus = SRB_STATUS_SUCCESS; + if (ReqDataCount(Req) > ReqSavedIndex(Req)) { + + Req->SrbStatus = SRB_STATUS_DATA_OVERRUN; + + // Update number of bytes transferred. + + // ReqSavedIndex is the number of bytes successfully transfered + + // One thing the NT people will have to address is zero latency + // xfers. How will number of bytes xfered be represented + // on an error, when the xfer has holes? + ReqDataCount(Req) = ReqSavedIndex(Req); + + } + break; + + + default: + + Req->SrbStatus = SRB_STATUS_ERROR; + break; + + } + TRACE(4, ("APISetStatus(): Setting target status to %02x\n", + Req->ScsiStatus)); + + break; + } + + TRACE(4, ("APISetStatus(): Setting request status to %02x\n", Req->SrbStatus)); + + if (Terminal != NonTerminal) { + + TRACE(3, ("APISetStatus(): Notifying completion\n")); + Notify(ReqAdapterPtr(Req), Req); + + } +} + + + +void +Notify (ADAPTER_PTR HA, IO_REQ_PTR Req) +{ + + if (ReqState(Req).InternalRequest) + (*(ReqPost(Req)))(Req); + else + ScsiPortNotification(RequestComplete, HA, Req); + +} + + +void +APINotifyReset (ADAPTER_PTR HA) +{ + TRACE(0, ("APINotifyReset():\n")); + ScsiPortNotification(ResetDetected, HA); +} + + + +void +IExecuteReq (ADAPTER_PTR HA, DEVICE_PTR DevP, IO_REQ_PTR Req, enum ASPI_Priorty Priorty) +{ + TRACE(5, ("IExecuteReq(): Got request %x for device %x on adapter %x\n", Req, DevP, HA)); + + if (HA->DevInfo[ReqTargetID(Req)].Flags.NeedSync) + QueueInternalRequest(HA, Req, RTSyncNegReq); + else + QueueReq(HA, (IO_REQ_PTR)Req, (Priorty > NORMAL_REQ)); + +} + + +#define HAPollTime (ULONG)500000 // Time in uS for 500mS +void +HATimer (IN PVOID HAObject) +{ + + TRACE(6, ("HATimer(): Timer entered\n")); + ((ADAPTER_PTR)HAObject)->Service(HA_TIMER, (ADAPTER_PTR)HAObject, 0l); + ScsiPortNotification(RequestTimerCall, HAObject, HATimer, HAPollTime); + +} + + + +BOOLEAN +HAInit (PVOID HAObject) +{ + ADAPTER_PTR HA = HAObject; + + TRACE(3, ("HAInit(): \n")); + + HA->Ext->InternalRequest.Length = sizeof(HA->Ext->InternalRequest); + HA->Ext->InternalRequest.SrbExtension = &(HA->Ext->IntlReqExtension); + ReqCommand(&(HA->Ext->InternalRequest)) = SRB_FUNCTION_EXECUTE_SCSI; // internally generated command + ReqAdapterPtr(&HA->Ext->InternalRequest) = HA; + ReqState(&(HA->Ext->InternalRequest)).InternalRequest = 1; + + ((ADAPTER_PTR)HAObject)->Service(HA_INITIALIZE, (ADAPTER_PTR)HAObject, 0l); + ScsiPortNotification(RequestTimerCall, HAObject, HATimer, HAPollTime); + return TRUE; + +} + + + +BOOLEAN +ResetBus (PVOID HAObject, ULONG PathID) +{ + + TRACE(0, ("ResetBus(): \n")); + + ((ADAPTER_PTR)HAObject)->Service(HA_RESET_BUS, (ADAPTER_PTR)HAObject, 0l); + + // Stall here, to allow the interrupt service routine to handle the reset + // and blow off requests, etc. + ScsiPortStallExecution(100l); + + // Send completion of reset request: + ScsiPortCompleteRequest(HAObject, (UCHAR)PathID, (UCHAR)-1, (UCHAR)-1, SRB_STATUS_BUS_RESET); + return TRUE; + +} + + + +BOOLEAN +AdapterState (IN PVOID HAObject, IN PVOID Context, IN BOOLEAN SaveState) +{ + + if (SaveState) + ((ADAPTER_PTR)HAObject)->Service(HA_RESTORE_STATE, (ADAPTER_PTR)HAObject, + (U32)0); + return TRUE; + +} + + +BOOLEAN +StartIO (IN PVOID HAObject, IN PSCSI_REQUEST_BLOCK Req) +{ + ADAPTER_PTR HA = HAObject; + DEVICE_PTR DevP; + int i; + + TRACE(2, ("StartIO(): Req @%x, Function = 0x%x, Req->SrbExtension @%x\n", Req, Req->Function, Req->SrbExtension)); + + switch (Req->Function) { + + case SRB_FUNCTION_EXECUTE_SCSI: + + + ReqNext(Req) = (IO_REQ_PTR)NILL; + ReqAdapterPtr(Req) = HA; + for (i=0; i < sizeof(ReqState(Req)); i++) + ((U8 *)&ReqState(Req))[i] = 0; + + ReqState(Req).ReqType = RTNormalReq; + + if ( (DevP = ScsiPortGetLogicalUnit(HA, Req->PathId, ReqTargetID(Req), ReqTargetLUN(Req))) == NILL) { + + TRACE(3, ("ExecuteReq(): Unable to get device info\n")); + Req->SrbStatus = SRB_STATUS_NO_DEVICE; + return FALSE; + + } + + ReqDevP(Req) = DevP; + if (!DevP->Flags.Initialized) + QueueInternalRequest(HA, Req, RTGetInfoReq); + else + IExecuteReq(HA, DevP, Req, NORMAL_REQ); + break; + + + case SRB_FUNCTION_RESET_BUS: + + TRACE(3, ("StartIO(): RESET_BUS command\n")); + ResetBus(HAObject, Req->PathId); + break; + + + case SRB_FUNCTION_RESET_DEVICE: + case SRB_FUNCTION_TERMINATE_IO: + case SRB_FUNCTION_FLUSH: + case SRB_FUNCTION_SHUTDOWN: + + Req->SrbStatus = SRB_STATUS_SUCCESS; + ScsiPortNotification(RequestComplete, HA, Req); + break; + + + case SRB_FUNCTION_ABORT_COMMAND: + + TRACE(0, ("StartIO(): Request at %x to abort request %x\n", Req, Req->NextSrb)); + if ((DevP = ScsiPortGetLogicalUnit(HA, Req->PathId, ReqTargetID(Req), ReqTargetLUN(Req))) == NILL + || (DevP->Flags.Initialized == 0) + || !AbortRequest(HA, DevP, Req->NextSrb) ) { + + TRACE(0, ("StartIO(): Abort operation failed\n")); + Req->SrbStatus = SRB_STATUS_ABORT_FAILED; + + } else { + + + TRACE(0, ("StartIO(): Abort operation success\n")); + Req->SrbStatus = SRB_STATUS_SUCCESS; + + } + ScsiPortNotification(RequestComplete, HA, Req); + break; + + + case SRB_FUNCTION_RELEASE_RECOVERY: + case SRB_FUNCTION_RECEIVE_EVENT: + case SRB_FUNCTION_IO_CONTROL: + default: + + TRACE(0, ("StartIO(): Unsupported command: 0x%x\n", Req->Function)); + APISetStatus(Req, S_REQ_OPCODE, Terminal, NotSenseable); + return FALSE; + break; + + + } + + ScsiPortNotification(NextLuRequest, HA, Req->PathId, Req->TargetId, Req->Lun); + return TRUE; + +} + + +BOOLEAN +GeneralISR (PVOID HAObject) +{ + + return (BOOLEAN) ( ((ADAPTER_PTR)HAObject)->ISR((ADAPTER_PTR)HAObject) ); + +} + + +ULONG +FindAdapter (IN PVOID HAObject, IN PVOID PContext, IN PVOID BusInfo, + IN PCHAR ArgString, IN OUT PPORT_CONFIGURATION_INFORMATION Config, + OUT PBOOLEAN PAgain) +{ + ADAPTER_PTR HA = HAObject; + + TRACE(3, ("FindAdapter(): Adapter ptr = %x, Config ptr = %x, Len = 0x%x\n", HA, Config, sizeof(struct _PORT_CONFIGURATION_INFORMATION))); + + /* Hunt down and register the adapters in the system: */ + HA->IOBaseAddr = (U16)ScsiPortConvertPhysicalAddressToUlong( + (*Config->AccessRanges)[0].RangeStart); + + if (Adapter_Init(HA, (unsigned *)PContext)) { + + // Set Again TRUE, only if we're being called with a non-sepcific access range + *PAgain = ScsiPortConvertPhysicalAddressToUlong( + (*Config->AccessRanges)[0].RangeStart) == 0; + + Config->BusInterruptLevel = HA->IRQNumber; + + Config->ScatterGather = HA->Supports.ScatterGather; + Config->MaximumTransferLength = 0x400000; + Config->NumberOfPhysicalBreaks = 0x400; +// Config->NumberOfPhysicalBreaks = HA->MaxSGListLength; + + (*Config->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(HA->IOBaseAddr); + (*Config->AccessRanges)[0].RangeLength = HA->IOAddrLen; + (*Config->AccessRanges)[0].RangeInMemory = FALSE; + + Config->NumberOfBuses = 1; + Config->InitiatorBusId[0] = HA->SCSI_ID; + Config->Master = (HA->Physical.Xfermode == XM_MASTER) || (HA->Physical.Xfermode == XM_MASTER24); + Config->Dma32BitAddresses = (HA->Physical.Xfermode == XM_MASTER); + Config->DemandMode = (HA->Physical.Xfermode == XM_DMAD); + Config->NeedPhysicalAddresses = XM_PHYSICAL(HA->Physical.Xfermode); + Config->MapBuffers = TRUE; + Config->CachesData = HA->Supports.Caching; + Config->AlignmentMask = 0x3; + + Config->TaggedQueuing = FALSE; + +#if defined(AUTOSENSE) + Config->AutoRequestSense = TRUE; +#else + Config->AutoRequestSense = FALSE; +#endif + + Config->MultipleRequestPerLu = Config->AutoRequestSense; + + Config->ReceiveEvent = FALSE; + + HA->Ext = ScsiPortGetUncachedExtension(HA, Config, sizeof(AdapterExtension)); + + return SP_RETURN_FOUND; + + } else { + + *PAgain = FALSE; + return SP_RETURN_NOT_FOUND; + + } +} + + +ULONG +DriverEntry (IN PVOID HAObject, IN PVOID ARG) +{ + HW_INITIALIZATION_DATA InitData; // Adapter init. struct + unsigned i; + ULONG AdapterCount; + ULONG ISAStatus, EISAStatus; +// ULONG MCAStatus, LocalStatus; + + /* Initialize the environment: */ + EnvLib_Init(); + + // Initialize the object + for (i=0; i < sizeof(InitData); i++) + ((char *)&InitData)[i] = 0; + + InitData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA); + + // Set pointers to service functions: + InitData.HwInitialize = HAInit; + InitData.HwStartIo = StartIO; + InitData.HwInterrupt = GeneralISR; + InitData.HwFindAdapter = FindAdapter; + InitData.HwResetBus = ResetBus; + InitData.HwAdapterState = AdapterState; // + + // Set capabilities + InitData.MapBuffers = TRUE; // This should be in PORT config info + InitData.NeedPhysicalAddresses = FALSE; + InitData.TaggedQueuing = FALSE; + +#if defined(AUTOSENSE) + InitData.AutoRequestSense = TRUE; +#else + InitData.AutoRequestSense = FALSE; +#endif + + InitData.MultipleRequestPerLu = InitData.AutoRequestSense; + + InitData.ReceiveEvent = FALSE; + + // Set misc. things: + InitData.NumberOfAccessRanges = 1; + + // Set the size of extensions + InitData.DeviceExtensionSize = HAExtentLen; + InitData.SpecificLuExtensionSize = DEVExtentLen; + InitData.SrbExtensionSize = REQExtentLen; + + AdapterCount = 0; + + TRACE(3, ("DriverEntry(): Trying EISA adapters\n")); + InitData.AdapterInterfaceType = Eisa; + EISAStatus = ScsiPortInitialize(HAObject, ARG, &InitData, (PVOID)&AdapterCount); + TRACE(2, ("DriverEntry(): ScsiPortInitialize() returned: %x\n", EISAStatus)); + + if (EISAStatus != 0) { + + TRACE(3, ("DriverEntry(): Trying ISA adapters\n")); + InitData.AdapterInterfaceType = Isa; + ISAStatus = ScsiPortInitialize(HAObject, ARG, &InitData, (PVOID)&AdapterCount); + TRACE(2, ("DriverEntry(): ScsiPortInitialize() returned: %x\n", ISAStatus)); + + } + + return min(ISAStatus, EISAStatus); + +} + + + +void +GetXferSegment (const ADAPTER_PTR HA, IO_REQ_PTR Req, SegmentDescr *SGDescr, + U32 Offset, BOOLEAN DemandPhysicalAddr) +{ + + TRACE(4, ("GetXferSegment(): Offset = %d\n", Offset)); + TRACE(4, ("GetXferSegment(): Non-S/G request, ReqDataCount = %d\n", ReqDataCount(Req))); + + if (Offset < ReqDataCount(Req)) { // Make sure we don't over run + + SGDescr->SegmentLength = ReqDataCount(Req) - Offset; + SGDescr->SegmentPtr = (U32)ReqDataPtr(Req) + Offset; + + } else { + + SGDescr->SegmentLength = 0; // No data left + SGDescr->SegmentPtr = 0; + BreakPoint(HA); + + } + TRACE(4, ("GetXferSegment(): %d bytes remain in segment at %08x (offset %d)\n", + SGDescr->SegmentLength, SGDescr->SegmentPtr, Offset)); + + SGDescr->Flags.IsPhysical = FALSE; + + if (DemandPhysicalAddr) { + + if (ReqState(Req).InternalRequest) { + + TRACE(5, ("GetXferSegment(): Mapping internal request\n")); + MapToPhysical(HA, SGDescr); + + } else { + + ULONG Size = SGDescr->SegmentLength; + + SGDescr->SegmentPtr = (U32)ScsiPortConvertPhysicalAddressToUlong( + ScsiPortGetPhysicalAddress(HA, Req, + (PVOID)((U32)ReqDataPtr(Req) + Offset) /*(SGDescr->SegmentPtr)*/, + &Size)); + + if (Size < SGDescr->SegmentLength) + SGDescr->SegmentLength = Size; + + DEBUG(5, { + if (SGDescr->SegmentLength < (ReqDataCount(Req) - Offset)) + DPrintf("Segment length is %d out of %d\n", + SGDescr->SegmentLength, ReqDataCount(Req) - Offset);}); + + SGDescr->Flags.IsPhysical = TRUE; + + TRACE(5, ("GetXferSegment(): Mapped to 0x%lx for %lu bytes\n", + SGDescr->SegmentPtr, Size)); + + } + } +} |