summaryrefslogtreecommitdiffstats
path: root/private/ntos/miniport/always/ntmgr.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/miniport/always/ntmgr.c
downloadNT4.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.c547
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));
+
+ }
+ }
+}