home *** CD-ROM | disk | FTP | other *** search
- /*DDK*************************************************************************/
- /* */
- /* COPYRIGHT Copyright (C) 1995 IBM Corporation */
- /* */
- /* The following IBM OS/2 WARP source code is provided to you solely for */
- /* the purpose of assisting you in your development of OS/2 WARP device */
- /* drivers. You may use this code in accordance with the IBM License */
- /* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */
- /* Copyright statement may not be removed. */
- /* */
- /*****************************************************************************/
- /*static char *SCCSID = "%w% %e%";*/
- #define SCCSID "%w% %e%"
-
- /**************************************************************************
- *
- * SOURCE FILE NAME = DMQUEUE.C
- *
- * DESCRIPTIVE NAME = OS2DASD.DMD - OS/2 DASD Device Manager
- * Request sorting/queuing routines for OS/2 DASD Mgr
- *
- *
- * VERSION = V2.0
- *
- * DATE
- *
- * DESCRIPTION Maintains sorted queues of Strategy 1/2 requests from
- * the OS/2 kernel and Installable File Systems (IFS)
- * that are awaiting processing. Also provides routing of
- * IORBs to Adapter Device Drivers.
- *
- *
- *
- */
- #include "dmh.h"
- #include "dmfault.h"
-
- USHORT NotifyDoneIORB_RLE (NPIORB, PPB_Read_Write, NPUNITCB);
- VOID NotifyDoneIORB_RP (NPIORB, PBYTE, NPUNITCB);
- VOID CallADD (NPUNITCB, NPIORB);
-
- /*------------------------------------------------------------------------
- ;
- ;** PutPriorityQueue - Put a Request List Entry or RP on a priority queue
- ;
- ; Put a RLE or a RP on one of the priority queues in
- ; the Unit Control Block for the specified unit.
- ;
- ; VOID PutPriorityQueue (NPUNITCB pUnitCB, PBYTE pReq)
- ;
- ; ENTRY: pUnitCB - Pointer to UnitCB
- ; pReq - Pointer to Request Packet or Request List Entry
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID FAR f_PutPriorityQueue (pUnitCB, pReq)
-
- NPUNITCB pUnitCB;
- PBYTE pReq;
- {
- PutPriorityQueue(pUnitCB, pReq);
- }
-
- VOID NEAR PutPriorityQueue (pUnitCB, pReq)
-
- NPUNITCB pUnitCB;
- PBYTE pReq;
- {
- if ( ((PRPH)pReq)->Cmd == PB_REQ_LIST)
- PutPriorityQueue_RLE (pUnitCB, (PPB_Read_Write) pReq);
- else
- PutPriorityQueue_RP (pUnitCB, pReq);
- }
-
- /*------------------------------------------------------------------------
- ;
- ;** PutPriorityQueue_RLE - Put a Request List Entry on a priority queue.
- ;
- ; Put a Request List Entry on one of the priority queues in
- ; the Unit Control Block for the specified unit.
- ;
- ; VOID PutPriorityQueue_RLE (NPUNITCB pUnitCB, PPB_Read_Write pRLE)
- ;
- ; ENTRY: pUnitCB - Pointer to UnitCB
- ; pRLE - Pointer to Request List Entry
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID FAR f_PutPriorityQueue_RLE (pUnitCB, pRLE)
-
- NPUNITCB pUnitCB;
- PPB_Read_Write pRLE;
-
- {
- PutPriorityQueue_RLE (pUnitCB, pRLE);
- }
-
-
- VOID PutPriorityQueue_RLE (pUnitCB, pRLE)
-
- NPUNITCB pUnitCB;
- PPB_Read_Write pRLE;
-
- {
- PRTYQ *pPrtyQ;
-
- PUSHFLAGS;
- DISABLE;
-
- /* For request list entries, put on a priority queue based on the */
- /* priority value in the request list entry. */
-
- if (pRLE->RqHdr.Status != RH_NOT_QUEUED)
- goto PutRLE_Ret;
-
- pRLE->RqHdr.Status = RH_QUEUED;
- pRLE->RqHdr.Waiting = 0;
-
- pPrtyQ =
- (PRTYQ *) (&(pUnitCB->PrtyQRLE[GetPrtyQIndex(pUnitCB, pRLE->RqHdr.Priority)])); /*@V74404*/
-
- /* If the queue is empty then stick the request at the head */
-
- if (pPrtyQ->Head == 0)
- {
- pPrtyQ->Head = (PBYTE) pRLE;
- pPrtyQ->Tail = (PBYTE) pRLE;
- }
- else
- {
-
- if (pUnitCB->SortMethod == SORT_METHOD_FIFO) /*@V74404*/
- {
- /* Put request at end of queue */
-
- ((PPB_Read_Write)(pPrtyQ->Tail))->RqHdr.Waiting = (ULONG) pRLE;
- pPrtyQ->Tail = (PBYTE) pRLE;
- }
- else
- {
- /* Sort on queue via an elevator algorithm */
-
- SortPriorityQueue (pPrtyQ, (PBYTE) pRLE);
- }
- }
-
- pUnitCB->NumReqsWaiting++;
- NumReqsWaiting++;
-
- ENABLE;
-
- PutRLE_Ret:
- POPFLAGS;
-
- }
-
- /*------------------------------------------------------------------------
- ;
- ;** PutPriorityQueue_RP - Put a request packet on a priority queue.
- ;
- ; Put a Request Packet on one of the priority queues in the
- ; Unit Control Block for the specified unit.
- ;
- ; VOID PutPriorityQueue_RP (NPUNITCB pUnitCB, PBYTE pReq)
- ;
- ; ENTRY: pUnitCB - Pointer to UnitCB
- ; pReq - Pointer to Request Packet
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID PutPriorityQueue_RP (pUnitCB, pReq)
-
- NPUNITCB pUnitCB;
- PBYTE pReq;
-
- {
- PRTYQ *pPrtyQ;
-
- PUSHFLAGS;
- DISABLE;
-
- /* Put a request packet on the priority queue for request packets. */
- /* The first request packet priority queue is for read/writes/verifys */
- /* which may require elevator sorting. The second request packet */
- /* queue is for requests that should not be elevator sorted, i.e. */
- /* "Get Media Sense", etc. */
-
- ((PRPH)pReq)->Link = 0;
-
- if ( ((PRPH)pReq)->Cmd != CMDInternal)
- pPrtyQ = &(pUnitCB->PrtyQRP[0]);
- else
- {
- if (((PRP_INTERNAL)pReq)->Function == DISKOP_READ_VERIFY)
- pPrtyQ = &(pUnitCB->PrtyQRP[0]);
- else
- pPrtyQ = &(pUnitCB->PrtyQRP[1]);
- }
-
- /* If the queue is empty then stick request at the head */
-
- if (pPrtyQ->Head == 0)
- {
- pPrtyQ->Head = pReq;
- pPrtyQ->Tail = pReq;
- }
- else
- {
- /* Either sort the request or put at end of queue */
-
- if ( (pPrtyQ == &(pUnitCB->PrtyQRP[1])) ||
- (pUnitCB->SortMethod == SORT_METHOD_FIFO) ) /*@V74404*/
- {
- /* Put request at end of queue */
-
- ((PRPH)(pPrtyQ->Tail))->Link = (PRPH) pReq;
- pPrtyQ->Tail = pReq;
- }
- else
- {
- /* Sort on queue via an elevator algorithm */
-
- SortPriorityQueue (pPrtyQ, pReq);
- }
- }
-
- pUnitCB->NumReqsWaiting++;
- NumReqsWaiting++;
-
- ENABLE;
- POPFLAGS;
-
- }
-
- /*------------------------------------------------------------------------
- ;
- ;** PullPriorityQueue - Pull a request from a priority queue.
- ;
- ; Pull the highest priority request from the priority queues
- ; for the specified unit. The request returned can either be
- ; a request packet of a request list entry.
- ;
- ; USHORT PullPriorityQueue (NPUNITCB pUnitCB, PBYTE *pReqAddr)
- ;
- ; ENTRY: pUnitCB - Pointer to UnitCB
- ; pReqAddr - returned pointer to Request Packet or
- ; Request List entry
- ;
- ; RETURN: USHORT - = 0, Request pulled
- ; <> 0, No request pulled, queues empty
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- USHORT PullPriorityQueue (pUnitCB, pReqAddr)
-
- NPUNITCB pUnitCB;
- PBYTE FAR *pReqAddr;
-
- {
- USHORT i, j, rc;
- PBYTE pReq;
- USHORT PullRequest = 0;
-
- /* Priority queues are ordered with the highest priority queue as the */
- /* first queue in the array. The request packet queues are searched */
- /* after the PRIO_FOREGROUND priority queue for request list entries */
-
- PUSHFLAGS;
- DISABLE;
-
- /* Make sure there's a request waiting to be processed before */
- /* searching the queues. */
-
- if (pUnitCB->NumReqsWaiting == 0)
- {
- rc = ERROR;
- goto PullRet;
- }
-
- /* Search the Request List Priority Queues First */
-
- for (i = 0; i < NUM_RLE_QUEUES; i++)
- {
- if (pUnitCB->PrtyQRLE[i].Head != 0)
- {
- PullRequest = 1;
- break;
- }
- }
-
- /* If not found, or priority queue above 4 (Foreground I/O) found, */
- /* then search the request packet queues. */
-
- if (i > 4)
- {
- for (j = 0; j < NUM_RP_QUEUES; j++)
- {
- if (pUnitCB->PrtyQRP[j].Head != 0)
- {
- PullRequest = 2;
- break;
- }
- }
- }
-
- /* If PullRequest == 1, then pull a request list entry from the queue */
-
- if (PullRequest == 1)
- {
- pReq = pUnitCB->PrtyQRLE[i].Head;
- (ULONG) pUnitCB->PrtyQRLE[i].Head=((PPB_Read_Write)pReq)->RqHdr.Waiting;
- ((PPB_Read_Write)pReq)->RqHdr.Waiting = 0;
- if (pUnitCB->PrtyQRLE[i].Head == 0)
- pUnitCB->PrtyQRLE[i].Tail = 0;
- }
-
- /* If PullRequest = 2, then pull a request packet entry from the queue */
-
- else if (PullRequest == 2)
- {
- pReq = pUnitCB->PrtyQRP[j].Head;
- pUnitCB->PrtyQRP[j].Head = (PBYTE) (((PRPH)pReq)->Link);
- ((PRPH)pReq)->Link = 0;
- if (pUnitCB->PrtyQRP[j].Head == 0)
- pUnitCB->PrtyQRP[j].Tail = 0;
- }
-
- /* If request pulled, then return address of request, else return error */
-
- if (PullRequest != 0)
- {
- *pReqAddr = pReq;
- pUnitCB->NumReqsWaiting--;
- NumReqsWaiting--;
- rc = NO_ERROR;
- }
- else
- rc = ERROR;
-
- PullRet:
- POPFLAGS;
- return(rc);
- }
-
- /*------------------------------------------------------------------------
- ;
- ;** RemovePriorityQueue - Remove an entry from a priority queue.
- ;
- ; This routine removes a specific Request List entry from one of
- ; the priority queues.
- ;
- ; USHORT RemovePriorityQueue (NPUNITCB pUnitCB, PPB_Read_Write pRLE)
- ;
- ; ENTRY: pUnitCB - Pointer to UnitCB
- ; pRLE - Request List Entry
- ;
- ; RETURN: USHORT - = 0, Request removed
- ; <> 0, No request removed, entry not found
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- USHORT RemovePriorityQueue (pUnitCB, pRLE)
-
- NPUNITCB pUnitCB;
- PPB_Read_Write pRLE;
-
- {
- PPB_Read_Write pCurReq, pPrevReq;
- USHORT PrtyQIndex, rc;
- USHORT Removed = NO;
-
- /* First make sure the entry is queued and the queue is not empty */
-
- PUSHFLAGS;
- DISABLE;
-
- if (pRLE->RqHdr.Status & RH_QUEUED)
- {
- PrtyQIndex = GetPrtyQIndex(pUnitCB,pRLE->RqHdr.Priority); /*@V74404*/
-
- if (pUnitCB->PrtyQRLE[PrtyQIndex].Head != 0)
- {
- /* See if entry is at the head of the queue */
-
- if (pUnitCB->PrtyQRLE[PrtyQIndex].Head = (PBYTE) pRLE)
- {
- pUnitCB->PrtyQRLE[PrtyQIndex].Head = (PBYTE) pRLE->RqHdr.Waiting;
- if (pRLE->RqHdr.Waiting == 0)
- pUnitCB->PrtyQRLE[PrtyQIndex].Tail = 0;
- else
- pRLE->RqHdr.Waiting = 0;
- Removed = YES;
- }
- else /* Entry is not at the head, so search for it */
- {
- (PBYTE) pCurReq = pUnitCB->PrtyQRLE[PrtyQIndex].Head;
- while (pCurReq != 0 && Removed == NO)
- {
- if (pCurReq = pRLE)
- {
- pPrevReq->RqHdr.Waiting = pCurReq->RqHdr.Waiting;
- if (pUnitCB->PrtyQRLE[PrtyQIndex].Tail = (PBYTE) pCurReq)
- (ULONG) pUnitCB->PrtyQRLE[PrtyQIndex].Tail =
- ((PPB_Read_Write)pCurReq)->RqHdr.Waiting;
- Removed = YES;
- }
- pPrevReq = pCurReq;
- if (pCurReq->RqHdr.Waiting != 0)
- pCurReq = (PPB_Read_Write) pCurReq->RqHdr.Waiting;
- }
- }
- }
- }
-
- if (Removed == YES)
- {
- pRLE->RqHdr.Status = RH_NOT_QUEUED;
- rc = 0;
- }
- else
- rc = 1;
-
- ENABLE;
- POPFLAGS;
- return(rc);
-
- }
- /*------------------------------------------------------------------------
- ;
- ;** PurgePriorityQueues - Purge Priority Queues
- ;
- ; Purge all requests from all priority queues for a specifed unit.
- ;
- ; USHORT PurgePriorityQueues (NPUNITCB pUnitCB, UCHAR ErrorCode)
- ;
- ; ENTRY: pUnitCB - Pointer to UnitCB
- ; ErrorCode - error code stored in Request Packet
- ; or Request List prior to notifying caller
- ;
- ; RETURN:
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID PurgePriorityQueues (pUnitCB, ErrorCode)
-
- NPUNITCB pUnitCB;
- UCHAR ErrorCode;
-
- {
- PBYTE pRequest;
- USHORT AwakeCount;
-
- while (PullPriorityQueue(pUnitCB, (PBYTE FAR *) &pRequest) == NO_ERROR)
- {
- if ( ((PRPH)pRequest)->Cmd == PB_REQ_LIST )
- {
- ((PPB_Read_Write)pRequest)->Blocks_Xferred = 0;
- ((PPB_Read_Write)pRequest)->RqHdr.Status = RH_UNREC_ERROR;
- ((PPB_Read_Write)pRequest)->RqHdr.Error_Code = ErrorCode;
- NotifyRLE((PPB_Read_Write)pRequest);
- }
- else
- {
- ((PRPH)pRequest)->Status = STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA;
- ((PRP_RWV)pRequest)->NumSectors = 0;
-
- if (TraceFlags != 0)
- Trace(TRACE_STRAT1 | TRACE_ASYNCDONE, (PBYTE)pRequest,
- pUnitCB->pCurrentVolCB);
-
- /* If internal request came from us, then issue PRUN */
-
- if (((PRPH)pRequest)->Flags & RPF_Internal)
- DevHelp_ProcRun((ULONG)pRequest, &AwakeCount);
-
- else
- {
- /* Normal request from file system, issue DevHelp_DevDone */
-
- DevHelp_DevDone((PBYTE) pRequest);
- }
- }
- }
- }
-
-
- /*------------------------------------------------------------------------
- ;
- ;** GetPrtyQIndex - Get priority queue index
- ;
- ; This function converts an input priority value to an index
- ; into the priority queue array in the UnitCB.
- ;
- ; USHORT GetPrtyQIndex (UCHAR Priority)
- ;
- ; ENTRY: Priority - Priority flag value
- ;
- ; RETURN: USHORT - Index into priority array
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- USHORT GetPrtyQIndex (pUnitCB,Priority) /*@V74404*/
-
- NPUNITCB pUnitCB; /*@V74404*/
- UCHAR Priority;
-
- {
- USHORT i;
-
- /* If priority queuing disabled, return highest priority queue index */
-
- if (pUnitCB->QueueMethod == QUEUE_METHOD_NOPRIORITY) /*@V74404*/
- return(0);
-
- /* Lowest priority value (i.e. 0) is the last queue */
-
- if (Priority == 0)
- return(NUM_RLE_QUEUES - 1);
-
- for (i = NUM_RLE_QUEUES - 1; i > 0; i--)
- {
- Priority >>= 1;
- if (Priority == 0)
- return(i-1);
- }
- return(5); /* Set to background user if invalid priority */
-
-
- }
-
-
- /*------------------------------------------------------------------------
- ;
- ;** SubmitRequestsToADD - Submit Requests to an Adapter Device Driver
- ;
- ; This function submits requests in priority order to the Adapter
- ; Device Driver which manages this unit. Requests are pulled from
- ; the priority waiting queues, IORBs are built and submitted to the
- ; ADD. IORBs will be chained together is the ADD supports a queuing
- ; count > 1 and the recommended queuing limit has not been exceded.
- ;
- ; USHORT SubmitRequestsToADD (pUnitCB)
- ;
- ; ENTRY: pUnitCB - pointer to unit control block
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID FAR f_SubmitRequestsToADD (pUnitCB)
-
- NPUNITCB pUnitCB;
- {
- SubmitRequestsToADD (pUnitCB);
- }
-
-
- VOID NEAR SubmitRequestsToADD (pUnitCB)
-
- NPUNITCB pUnitCB;
-
- {
- NPIORB pIORB, pPrevIORB, pFirstIORB;
- PBYTE pReq;
- USHORT i;
- USHORT NumIORBsBuilt = 0;
-
- PUSHFLAGS;
- DISABLE;
-
- /* If the number of requests already submitted to the ADD is */
- /* less than the ADD's recommended queuing count, then submit */
- /* additional requests. */
-
- for (i=pUnitCB->NumReqsInProgress; i < pUnitCB->QueueDepth; i++) /*@V74404*/
- {
-
- /* Allocate an IORB. If one is available, then pull the next */
- /* highest priority request from the unit's priority queues. */
-
- if (AllocIORB(pUnitCB, (NPIORB FAR *) &pIORB) != NO_ERROR)
- break;
-
- if (PullPriorityQueue (pUnitCB, (PBYTE FAR *)&pReq) != NO_ERROR)
- {
- FreeIORB(pUnitCB, pIORB);
- break;
- }
-
- /* We've pulled another request from the queue, so build the IORB */
- /* for it and chain it to the previous if we've built more than one. */
-
- pUnitCB->NumReqsInProgress++;
- NumReqsInProgress++;
-
- ENABLE;
-
- SetupIORB(pUnitCB, pReq, pIORB);
-
- NumIORBsBuilt++;
-
- if (NumIORBsBuilt == 1)
- {
- /* Only Execute_IO commands can be chained */
-
- if (pIORB->CommandCode == IOCC_EXECUTE_IO)
- {
- pFirstIORB = pIORB;
- pPrevIORB = pIORB;
- }
- else
- {
- /* Non Execute_IO request, send single IORB now */
-
- CallADD(pUnitCB, pIORB);
- NumIORBsBuilt = 0;
- }
- }
- else
- {
- /* Only Execute_IO commands can be chained */
-
- if (pIORB->CommandCode == IOCC_EXECUTE_IO)
- {
- pPrevIORB->pNxtIORB = (PVOID) pIORB;
- pPrevIORB->RequestControl |= IORB_CHAIN;
- pPrevIORB = pIORB;
- }
- else
- {
- /* Pulled non-Execute_IO Request after chain built */
-
- CallADD(pUnitCB, pFirstIORB); /* Send Execute_IO chain */
- CallADD(pUnitCB, pIORB); /* Send Non Execute_IO request */
- NumIORBsBuilt = 0;
- }
- }
- DISABLE;
- }
-
- ENABLE;
- POPFLAGS;
-
- /* If at least one IORB has been built, then send the IORB chain */
- /* (or single IORB) to the ADD. */
-
- if (NumIORBsBuilt > 0)
- {
- CallADD(pUnitCB, pFirstIORB);
- }
- }
- /*------------------------------------------------------------------------
- ;
- ;** CallADD - Call the Adapter Driver Entry Point
- ;
- ; This function calls the adapter driver entry point with the
- ; specified IORB chain.
- ;
- ; VOID CallADD (pUnitCB, pIORB)
- ;
- ; ENTRY: pUnitCB - pointer to unit control block
- ; pIORB - pointer to IORB chain
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID CallADD (pUnitCB, pIORB)
-
- NPUNITCB pUnitCB;
- NPIORB pIORB;
-
- {
- if (TraceFlags != 0)
- Trace(TRACE_IORB | TRACE_ENTRY, (PBYTE)pIORB, pUnitCB);
-
- (pUnitCB->AdapterDriverEP) ((PVOID) pIORB);
- }
-
- /*------------------------------------------------------------------------
- ;
- ;** SubmitImmedRequestToADD - Submit Immediate request to Adapter Driver
- ;
- ; This function bypasses the priority queues and sends an immediate
- ; request to the adapter driver. An IORB is built and submitted to
- ; the ADD even if the recommended queuing count has reached its limit.
- ; This is required for commands like RESUME, which must be sent to
- ; the ADD in order to resume work which may have already been queued up
- ; in the driver.
- ;
- ; USHORT SubmitImmedRequestsToADD (pUnitCB, pRequest)
- ;
- ; ENTRY: pUnitCB - pointer to unit control block
- ; pRequest - pointer to Request
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID SubmitImmedRequestToADD (pUnitCB, pRequest)
-
- NPUNITCB pUnitCB;
- PBYTE pRequest;
- {
- NPIORB pIORB;
-
- /* Allocate an IORB. Wait until one is available. */
-
- AllocIORB_Wait(pUnitCB, (NPIORB FAR *) &pIORB);
-
- DISABLE;
-
- pUnitCB->NumReqsInProgress++;
- NumReqsInProgress++;
-
- ENABLE;
-
- SetupIORB(pUnitCB, pRequest, pIORB);
-
- /* Send the IORB to the adapter driver */
-
- (pUnitCB->AdapterDriverEP) ((PVOID) pIORB);
-
- }
-
-
- /*------------------------------------------------------------------------
- ;
- ;** NotifyDoneIORB - Notify routine when IORB is done in ADD
- ;
- ; This function is the notification routine called by an Adapter Device
- ; Driver when an IORB is done. Error status and blocks transferred
- ; are updated in the associated Request Packet or Request List entry. If
- ; the request is a Strategy-2 Request List Entry, the file system is
- ; notified that the request has completed. If the request is a
- ; Strategy-1 Request Packet, the thread waiting on the request is woken up.
- ;
- ; VOID NotifyDoneIORB (PIORB fpIORB)
- ;
- ; ENTRY: fpIORB - far pointer to completed IORB
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID _loadds FAR NotifyDoneIORB (fpIORB)
-
- PIORB fpIORB;
-
- {
- PRPH pReq;
- NPUNITCB pUnitCB;
- NPIORB pIORB;
- NPIORB_DMWORK pDMWork;
-
- pIORB = (NPIORB) (OFFSETOF(fpIORB));
- pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
- pUnitCB = (NPUNITCB) pDMWork->pUnitCB;
-
-
- if (TraceFlags != 0)
- Trace(TRACE_IORB | TRACE_ASYNCDONE, (PBYTE) pIORB, pUnitCB);
- else if ((pIORB->Status & IORB_ERROR) && !(DDFlags & DDF_DISCARD_TRACE)) /*@V81576*/
- {
- TraceIORBInternal(TRACE_IORB | TRACE_ASYNCDONE, (PBYTE) pIORB);
- }
-
- if ( ((PRPH)pDMWork->pRequest)->Cmd == PB_REQ_LIST)
- NotifyDoneIORB_RLE(pIORB, (PPB_Read_Write) pDMWork->pRequest, pUnitCB);
- else
- {
- NotifyDoneIORB_RP (pIORB, (PBYTE) pDMWork->pRequest, pUnitCB);
- }
-
- /* Call the file system's end of interrupt routine */
-
- if (pFSD_EndofInt != 0)
- FSD_EndofInt();
- }
-
- /*------------------------------------------------------------------------
- ;
- ;** NotifyDoneIORB_RLE - Notify routine when IORB for a RLE is done
- ;
- ; This function is called when the ADD notifies us that a
- ; Request List entry is done. Error status and blocks transferred
- ; are updated in the Request List Entry. The file system is
- ; notified that the request has completed.
- ;
- ; USHORT NotifyDoneIORB_RLE (NPIORB pIORB, PPB_Read_Write pRLE)
- ;
- ; ENTRY: pIORB - pointer to completed IORB
- ; pRLE - pointer to Request List Entry
- ; pUnitCB - pointer to UnitCB
- ;
- ; RETURN: USHORT - Next Event Code
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- USHORT NotifyDoneIORB_RLE (pIORB, pRLE, pUnitCB)
-
- NPIORB pIORB;
- PPB_Read_Write pRLE;
- NPUNITCB pUnitCB;
-
- {
- PReq_List_Header pRLH;
- PPB_Read_Write pRLEOrig;
- NPIORB_DMWORK pDMWork;
- USHORT NextEvent = 0;
- USHORT FT_Status = 0;
- NPVOLCB pVolCB;
-
- pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
-
- pRLH = (PReq_List_Header) pRLE;
- OFFSETOF(pRLH) = OFFSETOF(pRLE) - (USHORT) (pRLE->RqHdr.Head_Offset);
-
- /* Set the error status and error code and call the file system */
- /* notification routine. */
-
- if (pIORB->Status & IORB_ERROR)
- {
- if (pIORB->Status & IORB_RECOV_ERROR)
- {
- /* HPFS doesnt handle recovered errors so set to no error */
-
- pRLE->RqHdr.Status = RH_NO_ERROR;
- pRLE->RqHdr.Error_Code = 0;
- pRLE->Blocks_Xferred = pRLE->Block_Count;
- }
- else
- {
- pRLE->RqHdr.Status = RH_UNREC_ERROR;
- pRLE->RqHdr.Error_Code = MapIORBError(pIORB->ErrorCode);
- pRLE->Blocks_Xferred = 0;
- }
- }
- else
- {
- pRLE->RqHdr.Status = RH_NO_ERROR;
- pRLE->RqHdr.Error_Code = 0;
- pRLE->Blocks_Xferred = pRLE->Block_Count;
- }
-
-
- if ( (DDFlags & DDF_FT_ENABLED) &&
- ( ((PRHFT)pRLE)->ftdb.FT_Flags & FTF_FT_REQUEST) )
- {
- if ((FT_Status = f_FT_NotifyDoneIORB_RLE(pIORB, pRLE,
- (PPB_Read_Write FAR *)&pRLEOrig)) & STDON)
- {
- pRLE = pRLEOrig;
- pRLH = (PReq_List_Header) pRLE;
- OFFSETOF(pRLH) = OFFSETOF(pRLE) - (USHORT) (pRLE->RqHdr.Head_Offset);
- }
- else
- goto RLE_Cleanup;
- }
- NotifyRLE (pRLE);
-
- /* If Uncertain Media error or Abort List on Error specified, */
- /* then abort the entire request list. */
-
- if (pRLE->RqHdr.Status & RH_UNREC_ERROR)
- {
- if (pRLE->RqHdr.Error_Code == ERROR_I24_UNCERTAIN_MEDIA)
- {
- pUnitCB->pCurrentVolCB->Flags |= vf_UncertainMedia;
-
- PurgePriorityQueues(pUnitCB, ERROR_I24_UNCERTAIN_MEDIA);
- }
- else if ( (pRLH->Lst_Status & RLH_Abort_Err) &&
- (pRLH->Lst_Status & RLH_Exe_Req_Seq) )
- {
- pRLH->Lst_Status |= RLH_Abort_pendings;
- AbortReqList(pRLH);
- }
- }
-
- /* Clean up request */
-
- RLE_Cleanup:
- FreeIORB(pUnitCB, pIORB);
-
- PUSHFLAGS;
- DISABLE;
- pUnitCB->NumReqsInProgress --;
- NumReqsInProgress--;
- POPFLAGS;
-
- /* If Execute in Sequence specified, then queue the next request in */
- /* in the list and submit it for processing. */
-
- if ( (pRLH->Request_Control & RLH_Exe_Req_Seq) &&
- ( !(pRLH->Lst_Status & RLH_All_Req_Done)) )
- {
- if (DDFlags & DDF_FT_ENABLED)
- {
- if (FT_Status & STDON)
- {
- Get_VolCB_Addr(pRLH->Block_Dev_Unit, (NPVOLCB FAR *)&pVolCB);
- f_FT_ExecReqList(pRLH, pVolCB->pUnitCB);
- }
- }
- else
- ExecReqList(pRLH, pUnitCB); /* Execute in sequence case */
- }
- else
-
- /* Pull the next request from the priority queues and submit it */
-
- SubmitRequestsToADD(pUnitCB); /* Normal case */
-
- }
-
-
- /*------------------------------------------------------------------------
- ;
- ;** NotifyDoneIORB_RP - Notify routine when an IORB for a RP is done
- ;
- ; This function is called when the ADD notifies us that a
- ; Request Packet is done. Error status and blocks transferred
- ; are updated in the Request Packet. The thread waiting on
- ; the request is woken up.
- ;
- ; VOID NotifyDoneIORB_RP (PIORB pIORB, PBYTE pRP)
- ;
- ; ENTRY: pIORB - pointer to completed IORB
- ; pRP - pointer to Request Packet
- ; pUnitCB - pointer to UnitCB
- ;
- ; RETURN: VOID
- ;
- ; EFFECTS:
- ;
- ------------------------------------------------------------------------*/
- VOID NotifyDoneIORB_RP (pIORB, pRP, pUnitCB)
-
- NPIORB pIORB;
- PBYTE pRP;
- NPUNITCB pUnitCB;
-
- {
- USHORT RP_Status;
- USHORT AwakeCount;
- NPIORB_DMWORK pDMWork;
- PBYTE pRPOrig;
- NPVOLCB pVolCB;
-
- pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
-
- RP_Status = STDON;
-
- /* Set the packet status word and wake up the thread waiting */
- /* on completition of this request. Recovered errors are */
- /* treated as no error, since Request Packets dont handle */
- /* recovered error conditions. */
-
- if (pIORB->Status & IORB_ERROR)
- {
- if ( !(pIORB->Status & IORB_RECOV_ERROR) )
- {
- RP_Status |= STERR;
-
- (UCHAR) RP_Status = MapIORBError(pIORB->ErrorCode);
-
- if (pIORB->CommandCode == IOCC_EXECUTE_IO)
- ((PRP_RWV)pRP)->NumSectors = 0;
-
- if ((UCHAR) RP_Status == ERROR_I24_UNCERTAIN_MEDIA)
- {
- pUnitCB->pCurrentVolCB->Flags |= vf_UncertainMedia;
-
- PurgePriorityQueues(pUnitCB, ERROR_I24_UNCERTAIN_MEDIA);
- }
- }
- }
-
- /* Set the status word and blocks transferred count in the RP */
-
- ((PRPH)pRP)->Status = RP_Status;
-
- if ( (DDFlags & DDF_FT_ENABLED) &&
- ( ((PRPFT)pRP)->ftdb.FT_Flags & FTF_FT_REQUEST ) )
- {
- if (f_FT_NotifyDoneIORB_RP(pIORB, (PRP_RWV) pRP,
- (PRP_RWV FAR *)&pRPOrig) & STDON)
- pRP = pRPOrig;
- else
- goto RP_Cleanup;
- }
-
- if (pIORB->CommandCode == IOCC_UNIT_STATUS)
- ((PRP_INTERNAL)pRP)->RetStatus = ((NPIORB_UNIT_STATUS)pIORB)->UnitStatus;
-
- if (pIORB->CommandCode == IOCC_GEOMETRY)
- {
- if (pIORB->CommandModifier == IOCM_GET_MEDIA_GEOMETRY)
- { /*@V63867*/
- if ( ((PRP_INTERNAL)pRP)->Function == DISKOP_UPDATE_REC_BPB ) /*@V63867*/
- { /*@V63867*/
- if ( !(pIORB->Status & IORB_ERROR) ) /*@V63867*/
- { /*@V63867*/
- pVolCB = (NPVOLCB) ((PRP_INTERNAL)pRP)->NumSectors; /*@V63867*/
- /*@V63867*/
- f_BPBFromGeom( (NPVOLCB) pVolCB, /*@V63867*/
- (NPBPB) &pVolCB->RecBPB, /*@V63867*/
- (PGEOMETRY) ((NPIORB_GEOMETRY) pIORB)->pGeometry ); /*@V63867*/
- } /*@V63867*/
- } /*@V63867*/
- else /*@V63867*/
- { /*@V63867*/
- ((PRP_INTERNAL)pRP)->NumSectors =
- (USHORT)((NPGEOMETRY)((NPIORB_GEOMETRY)pIORB)->pGeometry)->TotalSectors;
- }
- }
- }
-
-
- /* Wake up the thread waiting on completion of this request */
-
- if (TraceFlags != 0)
- Trace(TRACE_STRAT1 | TRACE_ASYNCDONE, (PBYTE) pRP, (NPVOLCB) 0);
-
-
- /* If internal request came from us, then issue ProcRun, */
- /* else issue DevDone for normal file system requests. */
-
- if (((PRPH)pRP)->Flags & RPF_Internal)
- DevHelp_ProcRun((ULONG)pRP, &AwakeCount);
- else
- DevHelp_DevDone((PBYTE) pRP);
-
-
- /* Clean up request and submit next request for processing */
-
- if (DDFlags & DDF_INIT_TIME) /* No cleanup if at init time */
- return;
-
- RP_Cleanup:
- FreeIORB(pUnitCB, pIORB);
-
- PUSHFLAGS;
- DISABLE;
- pUnitCB->NumReqsInProgress --;
- NumReqsInProgress--;
- POPFLAGS;
-
- SubmitRequestsToADD(pUnitCB); /* Normal case */
-
- }
-
-
-
-