summaryrefslogtreecommitdiffstats
path: root/private/ntos/miniport/always/intrlreq.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/intrlreq.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/intrlreq.c')
-rw-r--r--private/ntos/miniport/always/intrlreq.c359
1 files changed, 359 insertions, 0 deletions
diff --git a/private/ntos/miniport/always/intrlreq.c b/private/ntos/miniport/always/intrlreq.c
new file mode 100644
index 000000000..71753aa22
--- /dev/null
+++ b/private/ntos/miniport/always/intrlreq.c
@@ -0,0 +1,359 @@
+/* Copyright (C) 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"
+
+
+LOCAL void REGPARMS StartNextInternalRequest(ADAPTER_PTR HA);
+LOCAL void REGPARMS DeviceInfo(const ADAPTER_PTR HA);
+LOCAL void REGPARMS AutoSense(ADAPTER_PTR HA);
+LOCAL void REGPARMS CompleteDeferedRequest(ADAPTER_PTR HA, APIStatus Status);
+LOCAL void REGPARMS ExecuteDeferedRequest(ADAPTER_PTR HA);
+LOCAL void DoTestUnitReadyComplete(IO_REQ_PTR IReq);
+LOCAL void REGPARMS DoTestUnitReady(ADAPTER_PTR HA);
+
+
+#if !defined(LocalPostCallback)
+extern U32 LocalPostCallback(void (*CallBack)(IO_REQ_PTR));
+#endif
+
+enum ASPI_Priority {NORMAL_REQ, PRIORTY_REQ, IPRIORTY_REQ};
+extern void IExecuteReq(ADAPTER_PTR HA, DEVICE_PTR DevP, IO_REQ_PTR Req,
+ enum ASPI_Priorty Priorty);
+
+void
+QueueInternalRequest (ADAPTER_PTR HA, IO_REQ_PTR XReq, RequestType Type)
+{
+ IO_REQ_PTR *ReqScan = &(HA->Ext->InternalReqDeferQueue);
+
+ critical(HA);
+ ReqState(XReq).ReqType = Type;
+ while(*ReqScan != (IO_REQ_PTR)NILL)
+ ReqScan = &ReqNext(*ReqScan);
+
+ *ReqScan = XReq;
+ uncritical(HA);
+
+ StartNextInternalRequest(HA);
+}
+
+
+LOCAL void REGPARMS
+StartNextInternalRequest (ADAPTER_PTR HA)
+{
+ IO_REQ_PTR IReq = &HA->Ext->InternalRequest;
+ IO_REQ_PTR XReq;
+ int i;
+
+ TRACE(2, ("StartNextInternalRequest(): InUse flag == %s\n",
+ (HA->State.InternalReqInUse) ? "True" : "False"));
+
+ critical(HA);
+ while (!HA->State.InternalReqInUse
+ && HA->Ext->InternalReqDeferQueue != (IO_REQ_PTR)NILL) {
+
+ HA->State.InternalReqInUse = TRUE;
+ XReq = HA->Ext->InternalReqDeferQueue;
+
+ uncritical(HA);
+
+ ReqTargetID(IReq) = ReqTargetID(XReq);
+ ReqTargetLUN(IReq) = ReqTargetLUN(XReq);
+ ReqDevP(IReq) = ReqDevP(XReq);
+
+ for (i=0; i<12;i++)
+ ReqCDB(IReq)[i] = 0;
+
+ ReqState(IReq).ReqType = ReqState(XReq).ReqType;
+ switch(ReqState(XReq).ReqType) {
+
+ case RTGetInfoReq:
+
+ DeviceInfo(HA);
+ break;
+
+
+ case RTAutoSenseReq:
+
+ AutoSense(HA);
+ break;
+
+
+ case RTSyncNegReq:
+
+ DoTestUnitReady(HA);
+ break;
+
+
+ default:
+ CompleteDeferedRequest(HA, S_REQ_REQUEST);
+ continue;
+
+ }
+
+ critical(HA);
+ }
+ uncritical(HA);
+
+}
+
+
+
+
+void AutoSenseReqComplete(IO_REQ_PTR Req);
+
+LOCAL void REGPARMS
+AutoSense (ADAPTER_PTR HA)
+{
+ IO_REQ_PTR IReq = &HA->Ext->InternalRequest;
+ IO_REQ_PTR XReq = HA->Ext->InternalReqDeferQueue;
+
+ TRACE(4, ("AutoSense(): Starting auto sense for request %lx\n", XReq));
+
+ ReqCDBLen(IReq) = 6;
+ ReqSenseCount(IReq) = 0;
+ ReqDataCount(IReq) = ReqSenseCount(XReq);
+ ReqDataPtr(IReq) = ReqSensePtr(XReq);
+ TRACE(4, ("AutoSense(): Sense data pointer = %lx, sense count = %d\n",
+ ReqSensePtr(XReq), ReqSenseCount(XReq)));
+
+ ReqSetDataInFlags(IReq);
+
+ // First do a request sense to clear the reset, etc conditions:
+ ReqCDB(IReq)[0] = 0x03; // Request Sense is command 0x03
+ ReqCDB(IReq)[4] = min(255, ReqSenseCount(XReq));
+ ReqPost(IReq) = LocalPostCallback(AutoSenseReqComplete);
+
+ TRACE(3, ("AutoSense(): request built, calling IExecuteReq()\n"));
+ QueueReq(HA, IReq, TRUE);
+
+}
+
+
+
+LOCAL void
+AutoSenseReqComplete (IO_REQ_PTR Req)
+{
+ IO_REQ_PTR XReq = ReqAdapterPtr(Req)->Ext->InternalReqDeferQueue;
+
+ TRACE(3, ("AutoSenseReqComplete(): Completion of autosense for request %lx ", XReq));
+ TRACE(3, ("cmd = %02x\n", ReqCommand(XReq)));
+ DmsPause(7, 200);
+
+ FreeMemHandle(Req->ReqDataPtr);
+
+ TRACE(3, ("AutoSenseReqComplete(): Completion of auto sense\n"));
+ DmsPause(7, 100);
+ CompleteDeferedRequest(ReqAdapterPtr(Req),
+ (APIStatus)((ReqAPIStatus(Req) == S_TAR_NOERROR) ? S_AD_AUTOSENSE_OK : S_AD_AUTOSENSE_FAIL));
+
+}
+
+
+
+// The request completed
+LOCAL void
+DevInfoDone (ADAPTER_PTR HA, APIStatus Status)
+{
+ if (Status == S_TAR_NOERROR)
+ ExecuteDeferedRequest(HA); // Queue up request
+ else
+ CompleteDeferedRequest(HA, Status);
+
+}
+
+
+
+// This is the POST routine called when the second step (Inquiry) of the device info completes
+// This completes this devices inquiry. Start the next DevInfoReq for this adapter.
+LOCAL void
+DevInfoInqDone (IO_REQ_PTR Req)
+{
+ DEVICE_PTR DevP = ReqDevP(Req);
+ ADAPTER_PTR HA = ReqAdapterPtr(Req);
+
+ TRACE(4, ("DevInfoInqDone(): Status of Inquiry: %04x\n", ReqAPIStatus(Req)));
+ if (ReqAPIStatus(Req) == S_TAR_NOERROR) {
+
+ TRACE(4, ("DevInfoInqDone(): Inquiry completed without error\n"));
+ if (HA->Ext->InternalReqBuffer[0] == 0x7f) { // Check for LUN not present
+
+ TRACE(2, ("DeviceInfo(): LUN not present\n"));
+ DevInfoDone(HA, S_REQ_NOTAR);
+ return;
+
+ }
+
+ DevP->Device_Type = HA->Ext->InternalReqBuffer[0]; // Get device type
+ TRACE(2, ("DevInfoInqDone(): Device type = %02x\n", DevP->Device_Type));
+ TRACE(3, ("DevInfoInqDone(): Device is SCSI-%d, Flags = %02x\n",
+ (HA->Ext->InternalReqBuffer[3] & 0x0f), (unsigned)HA->Ext->InternalReqBuffer[7]));
+
+ if ((HA->Ext->InternalReqBuffer[3] & 0x0f) > 1) { // Is this dev. SCSI2 or later?
+
+ DevP->Flags.IsSCSI2 = 1; // Set SCSI-2 params valid flag
+ DevP->SCSI2_Flags.Byte = HA->Ext->InternalReqBuffer[7]; // Get the SCSI-2 parameter bytes
+ if (DevP->SCSI_LUN == 0)
+ HA->DevInfo[DevP->SCSI_ID].Flags.NeedSync = (HA->DevInfo[DevP->SCSI_ID].Flags.AllowSync &= DevP->SCSI2_Flags.Bits.Sync); // Use the inquiry info on Sync xfer
+
+ } else { // All right; we'll do thigns the SCSI-1 way
+
+ DevP->SCSI2_Flags.Byte = 0; // Clear all SCSI-2 mode bits
+ HA->DevInfo[DevP->SCSI_ID].Flags.NeedSync =
+ HA->DevInfo[DevP->SCSI_ID].Flags.AllowSync;
+ TRACE(2, ("DevInfoInqDone(): Setting NEED_SYNC flag to %d\n",
+ HA->DevInfo[DevP->SCSI_ID].Flags.NeedSync));
+
+ }
+ DevP->Flags.Allow_Disc = HA->Supports.Identify; // If the adapter supports identify messages, is allows disconnects
+ DevP->Flags.Initialized = 1;
+
+ }
+
+ DevInfoDone(HA, ReqAPIStatus(Req));
+
+}
+
+
+
+// This is the POST routine called when the first step (Request Sense) of the device info completes
+// The next step will be to do the inquiry, initiated here, completed above
+LOCAL void
+DevInfoSenseDone (IO_REQ_PTR Req)
+{
+ ADAPTER_PTR HA = ReqAdapterPtr(Req);
+
+ TRACE(3, ("DevInfoSenseDone(): Status of ReqSense: %02x\n", ReqAPIStatus(Req)));
+ if (ReqAPIStatus(Req) != S_TAR_NOERROR) {
+
+ TRACE(4, ("DevInfoSenseDone(): Completed with error\n"));
+ DevInfoDone(HA, ReqAPIStatus(Req));
+ return;
+
+ }
+
+ // OK, the Request Sense completed OK, now do the inquiry
+ TRACE(3, ("DevInfoSenseDone(): Req. sense completed OK, setting up inquiry\n"));
+ ReqCDB(Req)[0] = (U8)0x12; // Inquiry is command 0x12
+
+ ReqDataCount(Req) = DevInfoInqSize;
+ ReqDataPtr(Req) = HA->Ext->InternalReqBuffer;
+
+ ReqPost(Req) = DevInfoInqDone;
+
+ QueueReq(ReqAdapterPtr(Req), Req, FALSE); // Queue up request
+
+}
+
+
+
+LOCAL void REGPARMS
+DeviceInfo (const ADAPTER_PTR HA)
+{
+ int i;
+ DEVICE_PTR DevP=ReqDevP(HA->Ext->InternalReqDeferQueue);
+ IO_REQ_PTR IReq = &(HA->Ext->InternalRequest);
+
+ TRACE(2, ("DeviceInfo(): for adapter %x\n"));
+
+ for (i = 0; i < sizeof(DevP->Flags); i++)
+ ((char ALLOC_D *)&(DevP->Flags))[i] = 0;
+
+ DevP->SCSI_ID = ReqTargetID(IReq);
+ DevP->SCSI_LUN = ReqTargetLUN(IReq);
+ if (DevP->SCSI_LUN == 0) {
+
+ HA->DevInfo[ReqTargetID(IReq)].Flags.AllowSync = HA->Supports.Synchronous
+ /* && (HA->Parms[DRIVE_PL(ReqTargetID(IReq))] & PL_ALLOW_SYNC) */;
+
+ }
+
+ DevP->HA = HA;
+ DevP->MaxDepth = 1;
+ DevP->CurrDepth = 0;
+ DevP->Device_Type = 0xff;
+
+ DevP->PendingReqList = DevP->AcceptedList = (IO_REQ_PTR)NILL;
+ ReqCDBLen(IReq) = 6;
+ ReqSenseCount(IReq) = 0;
+ ReqDataCount(IReq) = DevInfoInqSize;
+ ReqDataPtr(IReq) = HA->Ext->InternalReqBuffer;
+
+ ReqSetDataInFlags(IReq);
+
+ // First do a request sense to clear the reset, etc conditions:
+ ReqCDB(IReq)[0] = 0x03; // Request Sense is command 0x03
+ ReqCDB(IReq)[4] = (unsigned char)DevInfoInqSize;
+ ReqPost(IReq) = DevInfoSenseDone;
+
+ QueueReq(HA, IReq, FALSE); // Queue up request
+
+}
+
+
+
+
+LOCAL void REGPARMS
+DoTestUnitReady (ADAPTER_PTR HA)
+{
+ IO_REQ_PTR IReq = &HA->Ext->InternalRequest;
+ IO_REQ_PTR XReq = HA->Ext->InternalReqDeferQueue;
+
+ TRACE(4, ("DoTestUnitReady(): Starting Test Unit Ready for request %lx\n", XReq));
+
+ ReqCDBLen(IReq) = 6;
+ ReqSenseCount(IReq) = 0;
+ ReqDataCount(IReq) = 0;
+
+ ReqPost(IReq) = LocalPostCallback(DoTestUnitReadyComplete);
+
+ TRACE(3, ("DoTestUnitReady(): request built, calling IExecuteReq()\n"));
+ QueueReq(HA, IReq, FALSE); // Queue up request
+
+}
+
+
+LOCAL void
+DoTestUnitReadyComplete (IO_REQ_PTR IReq)
+{
+
+ ExecuteDeferedRequest(ReqAdapterPtr(IReq)); // Queue up original request
+
+}
+
+
+LOCAL void REGPARMS
+CompleteDeferedRequest (ADAPTER_PTR HA, APIStatus Status)
+{
+ IO_REQ_PTR XReq = HA->Ext->InternalReqDeferQueue;
+ HA->Ext->InternalReqDeferQueue = ReqNext(XReq);
+
+ TRACE(3, ("CompleteDeferedRequest(): Completing defered request %x on adapter %x\n", XReq, HA));
+ HA->State.InternalReqInUse = FALSE;
+ StartNextInternalRequest(HA);
+ ReqState(XReq).ReqType = RTNormalReq;
+ APISetStatus(XReq, Status, Terminal, NotSenseable);
+
+}
+
+
+
+LOCAL void REGPARMS
+ExecuteDeferedRequest (ADAPTER_PTR HA)
+{
+ IO_REQ_PTR XReq = HA->Ext->InternalReqDeferQueue;
+ HA->Ext->InternalReqDeferQueue = ReqNext(XReq);
+
+ TRACE(3, ("ExecuteDeferedRequest(): Executing defered request %x on adapter %x\n", XReq, HA));
+ HA->State.InternalReqInUse = FALSE;
+ StartNextInternalRequest(HA);
+ ReqState(XReq).ReqType = RTNormalReq;
+ IExecuteReq(HA, ReqDevP(XReq), XReq, NORMAL_REQ); // Queue up request
+
+}