⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
📖 第 1 页 / 共 3 页
字号:

--*/
{
   LONG pendingCnt;

   pendingCnt = InterlockedDecrement(&PDevExt->PendingIRPCnt);

   ASSERT(pendingCnt >= 0);

   if (pendingCnt == 0) {
      KeSetEvent(&PDevExt->PendingIRPEvent, IO_NO_INCREMENT, FALSE);
   }
}


BOOLEAN
SerialInsertQueueDpc(IN PRKDPC PDpc, IN PVOID Sarg1, IN PVOID Sarg2,
                     IN PDEVICE_EXTENSION PDevExt)
/*++

Routine Description:

   This function must be called to queue DPC's for the serial driver.

Arguments:

   PDpc thru Sarg2  - Standard args to KeInsertQueueDpc()

   PDevExt - Pointer to the device extension for the device that needs to
             queue a DPC

Return Value:

   Kicks up return value from KeInsertQueueDpc()

--*/
{
   BOOLEAN queued;

   InterlockedIncrement(&PDevExt->DpcCount);
   //LOGENTRY(LOG_CNT, 'DpI1', PDpc, PDevExt->DpcCount, 0);

   queued = KeInsertQueueDpc(PDpc, Sarg1, Sarg2);

   if (!queued) {
      ULONG pendingCnt;

      pendingCnt = InterlockedDecrement(&PDevExt->DpcCount);
//      LOGENTRY(LOG_CNT, 'DpD1', PDpc, PDevExt->DpcCount, 0);

      if (pendingCnt == 0) {
         KeSetEvent(&PDevExt->PendingIRPEvent, IO_NO_INCREMENT, FALSE);
         //LOGENTRY(LOG_CNT, 'DpF1', PDpc, PDevExt->DpcCount, 0);
      }
   }

#if 0 // DBG
   if (queued) {
      int i;

      for (i = 0; i < MAX_DPC_QUEUE; i++) {
                     if (PDevExt->DpcQueued[i].Dpc == PDpc) {
                        PDevExt->DpcQueued[i].QueuedCount++;
                        break;
                     }
      }

      ASSERT(i < MAX_DPC_QUEUE);
   }
#endif

   return queued;
}


BOOLEAN
SerialSetTimer(IN PKTIMER Timer, IN LARGE_INTEGER DueTime,
               IN PKDPC Dpc OPTIONAL, IN PDEVICE_EXTENSION PDevExt)
/*++

Routine Description:

   This function must be called to set timers for the serial driver.

Arguments:

   Timer - pointer to timer dispatcher object

   DueTime - time at which the timer should expire

   Dpc - option Dpc

   PDevExt - Pointer to the device extension for the device that needs to
             set a timer

Return Value:

   Kicks up return value from KeSetTimer()

--*/
{
   BOOLEAN set;

   InterlockedIncrement(&PDevExt->DpcCount);
   //LOGENTRY(LOG_CNT, 'DpI2', Dpc, PDevExt->DpcCount, 0);

   set = KeSetTimer(Timer, DueTime, Dpc);

   if (set) {
      InterlockedDecrement(&PDevExt->DpcCount);
//      LOGENTRY(LOG_CNT, 'DpD2', Dpc, PDevExt->DpcCount, 0);
   }

#if 0 // DBG
   if (set) {
      int i;

      for (i = 0; i < MAX_DPC_QUEUE; i++) {
                     if (PDevExt->DpcQueued[i].Dpc == Dpc) {
                        PDevExt->DpcQueued[i].QueuedCount++;
                        break;
                     }
      }

      ASSERT(i < MAX_DPC_QUEUE);
   }
#endif

   return set;
}


BOOLEAN
SerialCancelTimer(IN PKTIMER Timer, IN PDEVICE_EXTENSION PDevExt)
/*++

Routine Description:

   This function must be called to cancel timers for the serial driver.

Arguments:

   Timer - pointer to timer dispatcher object

   PDevExt - Pointer to the device extension for the device that needs to
             set a timer

Return Value:

   True if timer was cancelled

--*/
{
   BOOLEAN cancelled;

   cancelled = KeCancelTimer(Timer);

   if (cancelled) {
      SerialDpcEpilogue(PDevExt, Timer->Dpc);
   }

   return cancelled;
}


VOID
SerialDpcEpilogue(IN PDEVICE_EXTENSION PDevExt, PKDPC PDpc)
/*++

Routine Description:

   This function must be called at the end of every dpc function.

Arguments:

   PDevObj - Pointer to the device object we are tracking dpc's for.

Return Value:

   None.

--*/
{
   LONG pendingCnt;
#if 1 // !DBG
   UNREFERENCED_PARAMETER(PDpc);
#endif

   pendingCnt = InterlockedDecrement(&PDevExt->DpcCount);
//   LOGENTRY(LOG_CNT, 'DpD3', PDpc, PDevExt->DpcCount, 0);

   ASSERT(pendingCnt >= 0);

#if 0 //DBG
{
      int i;

      for (i = 0; i < MAX_DPC_QUEUE; i++) {
                     if (PDevExt->DpcQueued[i].Dpc == PDpc) {
                        PDevExt->DpcQueued[i].FlushCount++;

                        ASSERT(PDevExt->DpcQueued[i].QueuedCount >=
                               PDevExt->DpcQueued[i].FlushCount);
                        break;
                     }
      }

      ASSERT(i < MAX_DPC_QUEUE);
   }
#endif

   if (pendingCnt == 0) {
      KeSetEvent(&PDevExt->PendingDpcEvent, IO_NO_INCREMENT, FALSE);
      //LOGENTRY(LOG_CNT, 'DpF2', PDpc, PDevExt->DpcCount, 0);
   }
}



VOID
SerialUnlockPages(IN PKDPC PDpc, IN PVOID PDeferredContext,
                  IN PVOID PSysContext1, IN PVOID PSysContext2)
/*++

Routine Description:

   This function is a DPC routine queue from the ISR if he released the
   last lock on pending DPC's.

Arguments:

   PDpdc, PSysContext1, PSysContext2 -- not used

   PDeferredContext -- Really the device extension

Return Value:

   None.

--*/
{
   PDEVICE_EXTENSION pDevExt
      = (PDEVICE_EXTENSION)PDeferredContext;

   UNREFERENCED_PARAMETER(PDpc);
   UNREFERENCED_PARAMETER(PSysContext1);
   UNREFERENCED_PARAMETER(PSysContext2);

   KeSetEvent(&pDevExt->PendingDpcEvent, IO_NO_INCREMENT, FALSE);
}


NTSTATUS
SerialIoCallDriver(PDEVICE_EXTENSION PDevExt, PDEVICE_OBJECT PDevObj,
                   PIRP PIrp)
/*++

Routine Description:

   This function must be called instead of IoCallDriver.  It automatically
   updates Irp tracking for PDevObj.

Arguments:
   PDevExt - Device extension attached to PDevObj

   PDevObj - Pointer to the device object we are tracking pending IRP's for.

   PIrp - Pointer to the Irp we are passing to the next driver.

Return Value:

   None.

--*/
{
   NTSTATUS status;

   status = IoCallDriver(PDevObj, PIrp);
   SerialIRPEpilogue(PDevExt);
   return status;
}



NTSTATUS
SerialPoCallDriver(PDEVICE_EXTENSION PDevExt, PDEVICE_OBJECT PDevObj,
                   PIRP PIrp)
/*++

Routine Description:

   This function must be called instead of PoCallDriver.  It automatically
   updates Irp tracking for PDevObj.

Arguments:
   PDevExt - Device extension attached to PDevObj

   PDevObj - Pointer to the device object we are tracking pending IRP's for.

   PIrp - Pointer to the Irp we are passing to the next driver.

Return Value:

   None.

--*/
{
   NTSTATUS status;

   status = PoCallDriver(PDevObj, PIrp);
   SerialIRPEpilogue(PDevExt);
   return status;
}


VOID
SerialLogError(
              IN PDRIVER_OBJECT DriverObject,
              IN PDEVICE_OBJECT DeviceObject OPTIONAL,
              IN PHYSICAL_ADDRESS P1,
              IN PHYSICAL_ADDRESS P2,
              IN ULONG SequenceNumber,
              IN UCHAR MajorFunctionCode,
              IN UCHAR RetryCount,
              IN ULONG UniqueErrorValue,
              IN NTSTATUS FinalStatus,
              IN NTSTATUS SpecificIOStatus,
              IN ULONG LengthOfInsert1,
              IN PWCHAR Insert1,
              IN ULONG LengthOfInsert2,
              IN PWCHAR Insert2
              )

/*++

Routine Description:

    This routine allocates an error log entry, copies the supplied data
    to it, and requests that it be written to the error log file.

Arguments:

    DriverObject - A pointer to the driver object for the device.

    DeviceObject - A pointer to the device object associated with the
    device that had the error, early in initialization, one may not
    yet exist.

    P1,P2 - If phyical addresses for the controller ports involved
    with the error are available, put them through as dump data.

    SequenceNumber - A ulong value that is unique to an IRP over the
    life of the irp in this driver - 0 generally means an error not
    associated with an irp.

    MajorFunctionCode - If there is an error associated with the irp,
    this is the major function code of that irp.

    RetryCount - The number of times a particular operation has been
    retried.

    UniqueErrorValue - A unique long word that identifies the particular
    call to this function.

    FinalStatus - The final status given to the irp that was associated
    with this error.  If this log entry is being made during one of
    the retries this value will be STATUS_SUCCESS.

    SpecificIOStatus - The IO status for a particular error.

    LengthOfInsert1 - The length in bytes (including the terminating NULL)
                      of the first insertion string.

    Insert1 - The first insertion string.

    LengthOfInsert2 - The length in bytes (including the terminating NULL)
                      of the second insertion string.  NOTE, there must
                      be a first insertion string for their to be
                      a second insertion string.

    Insert2 - The second insertion string.

Return Value:

    None.

--*/

{
   PIO_ERROR_LOG_PACKET errorLogEntry;

   PVOID objectToUse;
   SHORT dumpToAllocate = 0;
   PUCHAR ptrToFirstInsert;
   PUCHAR ptrToSecondInsert;

   PAGED_CODE();

   if (Insert1 == NULL) {
      LengthOfInsert1 = 0;
   }

   if (Insert2 == NULL) {
      LengthOfInsert2 = 0;
   }


   if (ARGUMENT_PRESENT(DeviceObject)) {

      objectToUse = DeviceObject;

   } else {

      objectToUse = DriverObject;

   }
/*
   if (SerialMemCompare(
                       P1,
                       (ULONG)1,
                       SerialPhysicalZero,
                       (ULONG)1
                       ) != AddressesAreEqual) {

      dumpToAllocate = (SHORT)sizeof(PHYSICAL_ADDRESS);

   }

   if (SerialMemCompare(
                       P2,
                       (ULONG)1,
                       SerialPhysicalZero,
                       (ULONG)1
                       ) != AddressesAreEqual) {

      dumpToAllocate += (SHORT)sizeof(PHYSICAL_ADDRESS);

   }
*/
   errorLogEntry = IoAllocateErrorLogEntry(
                                          objectToUse,
                                          (UCHAR)(sizeof(IO_ERROR_LOG_PACKET) +
                                                  dumpToAllocate
                                                  + LengthOfInsert1 +
                                                  LengthOfInsert2)
                                          );

   if ( errorLogEntry != NULL ) {

      errorLogEntry->ErrorCode = SpecificIOStatus;
      errorLogEntry->SequenceNumber = SequenceNumber;
      errorLogEntry->MajorFunctionCode = MajorFunctionCode;
      errorLogEntry->RetryCount = RetryCount;
      errorLogEntry->UniqueErrorValue = UniqueErrorValue;
      errorLogEntry->FinalStatus = FinalStatus;
      errorLogEntry->DumpDataSize = dumpToAllocate;

      if (dumpToAllocate) {

         RtlCopyMemory(
                      &errorLogEntry->DumpData[0],
                      &P1,
                      sizeof(PHYSICAL_ADDRESS)
                      );

         if (dumpToAllocate > sizeof(PHYSICAL_ADDRESS)) {

            RtlCopyMemory(
                         ((PUCHAR)&errorLogEntry->DumpData[0])
                         +sizeof(PHYSICAL_ADDRESS),
                         &P2,
                         sizeof(PHYSICAL_ADDRESS)
                         );

            ptrToFirstInsert =
            ((PUCHAR)&errorLogEntry->DumpData[0])+(2*sizeof(PHYSICAL_ADDRESS));

         } else {

            ptrToFirstInsert =
            ((PUCHAR)&errorLogEntry->DumpData[0])+sizeof(PHYSICAL_ADDRESS);


         }

      } else {

         ptrToFirstInsert = (PUCHAR)&errorLogEntry->DumpData[0];

      }

      ptrToSecondInsert = ptrToFirstInsert + LengthOfInsert1;

      if (LengthOfInsert1) {

         errorLogEntry->NumberOfStrings = 1;
         errorLogEntry->StringOffset = (USHORT)(ptrToFirstInsert -
                                                (PUCHAR)errorLogEntry);
         RtlCopyMemory(
                      ptrToFirstInsert,
                      Insert1,
                      LengthOfInsert1
                      );

         if (LengthOfInsert2) {

            errorLogEntry->NumberOfStrings = 2;
            RtlCopyMemory(
                         ptrToSecondInsert,
                         Insert2,
                         LengthOfInsert2
                         );

         }

      }

      IoWriteErrorLogEntry(errorLogEntry);

   }

}

VOID
SerialMarkHardwareBroken(IN PDEVICE_EXTENSION PDevExt)
/*++

Routine Description:

   Marks a UART as broken.  This causes the driver stack to stop accepting
   requests and eventually be removed.

Arguments:
   PDevExt - Device extension attached to PDevObj

Return Value:

   None.

--*/
{
/*   PAGED_CODE();

   //
   // Mark as damaged goods
   //

   SerialSetFlags(PDevExt, SERIAL_FLAGS_BROKENHW);

   //
   // Write a log entry
   //

   SerialLogError(PDevExt->DriverObject, NULL, SerialPhysicalZero,
                  SerialPhysicalZero, 0, 0, 0, 88, STATUS_SUCCESS,
                  SERIAL_HARDWARE_FAILURE, PDevExt->DeviceName.Length
                  + sizeof(WCHAR), PDevExt->DeviceName.Buffer, 0, NULL);

   //
   // Invalidate the device
   //

   IoInvalidateDeviceState(PDevExt->Pdo);
   */
}

VOID
SerialSetDeviceFlags(IN PDEVICE_EXTENSION PDevExt, OUT PULONG PFlags,
                     IN ULONG Value, IN BOOLEAN Set)
/*++

Routine Description:

   Sets flags in a value protected by the flags spinlock.  This is used
   to set values that would stop IRP's from being accepted.

Arguments:
   PDevExt - Device extension attached to PDevObj

   PFlags - Pointer to the flags variable that needs changing

   Value - Value to modify flags variable with

   Set - TRUE if |= , FALSE if &=

Return Value:

   None.

--*/
{
   KIRQL oldIrql;

   KeAcquireSpinLock(&PDevExt->FlagsLock, &oldIrql);

   if (Set) {
      *PFlags |= Value;
   } else {
      *PFlags &= ~Value;
   }

   KeReleaseSpinLock(&PDevExt->FlagsLock, oldIrql);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -