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

📄 serialdevice.h

📁 这个是串口驱动程序开发包
💻 H
📖 第 1 页 / 共 3 页
字号:
#ifndef __SERIAL_DEVICE__
#define __SERIAL_DEVICE__

#include "precomp.h"

typedef KdTimer * PKdTimer;
typedef KdIrp * PKdIrp;

class KdSerialDevice;

typedef VOID (KdSerialDevice::*P_GET_NEXT_ROUTINE) (PKdIrp CurrentOpIrp,
                                                    PLIST_ENTRY QueueToProcess,
                                                    PKdIrp NewIrp,
                                                    BOOLEAN CompleteCurrent);

typedef struct _SERIAL_UPDATE_CHAR {
    ULONG CharsCopied;
    BOOLEAN Completed;
    } SERIAL_UPDATE_CHAR,*PSERIAL_UPDATE_CHAR;

// The following three macros are used to initialize, set
// and clear references in IRPs that are used by
// this driver.  The reference is stored in the fourth
// argument of the irp, which is never used by any operation
// accepted by this driver.

#define SERIAL_REF_ISR         (0x00000001)
#define SERIAL_REF_CANCEL      (0x00000002)
#define SERIAL_REF_TOTAL_TIMER (0x00000004)
#define SERIAL_REF_INT_TIMER   (0x00000008)
#define SERIAL_REF_XOFF_REF    (0x00000010)



#define SERIAL_INIT_REFERENCE(Irp) { \
    ASSERT(sizeof(LONG) <= sizeof(PVOID)); \
    (Irp).GetStackLocation()->Parameters.Others.Argument4 = NULL; }

#define SERIAL_SET_REFERENCE(Irp,RefType) \
   do { \
       LONG _refType = (RefType); \
       PLONG _arg4 = (PLONG)((PVOID)&(Irp).GetStackLocation()->Parameters.Others.Argument4); \
       ASSERT(!(*_arg4 & _refType)); \
       *_arg4 |= _refType; \
   } while (0)

#define SERIAL_CLEAR_REFERENCE(Irp,RefType) \
   do { \
       LONG _refType = (RefType); \
       PLONG _arg4 = (PLONG)((PVOID)&(Irp).GetStackLocation()->Parameters.Others.Argument4); \
       ASSERT(*_arg4 & _refType); \
       *_arg4 &= ~_refType; \
   } while (0)

#define SERIAL_REFERENCE_COUNT(Irp) \
    ((LONG)(((Irp).GetStackLocation()->Parameters.Others.Argument4)))


class KdSerialDevice : public KdDevice
{
public:
    KdSerialDevice();
    virtual ~KdSerialDevice(); 
    virtual NTSTATUS DispatchCreate             ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchClose              ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchDeviceControl      ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchRead               ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchWrite              ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchFlushBuffers       ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchSetInformation     ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchQueryInformation   ( IN KdIrp &Irp );
    virtual NTSTATUS DispatchCleanup            ( IN KdIrp &Irp );

    typedef NTSTATUS (KdSerialDevice::*PSERIAL_START_ROUTINE) ();

    DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelCurrentRead);
    DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelImmediate);
    DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelQueued);
    DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelWait);
    DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelCurrentWrite);
    DEFINE_IRP_CANCEL_ROUTINE(KdSerialDevice, CancelCurrentXoff);

    NTSTATUS CompleteIfError(KdIrp Irp);

    BOOLEAN DoesPortExist(KdString InsertString, ULONG ForceFifo, ULONG LogFifo);

    NTSTATUS InitializeOneController(PCONFIG_DATA ConfigData, BOOLEAN MapInterruptStatus);
    NTSTATUS InitializeController(PCONFIG_DATA ConfigData, BOOLEAN MapInterruptStatus);

    VOID PropagateDeleteSharers(PULONG CountSoFar = NULL, PKINTERRUPT Interrupt = NULL);

    VOID TryToCompleteCurrent(KDIRQ_SYNC_CALLBACK SynchRoutine,
                              KIRQL IrqlForRelease,
                              NTSTATUS StatusToUse,
                              PKdIrp CurrentOpIrp,
                              PLIST_ENTRY QueueToProcess,
                              PKdTimer IntervalTimer,
                              PKdTimer TotalTimer,
                              PSERIAL_START_ROUTINE Starter,
                              P_GET_NEXT_ROUTINE GetNextIrpRoutine,
                              LONG RefType);

    VOID CompleteWrite      (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID CompleteRead       (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID ReadTimeout        (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID IntervalReadTimeout(PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID WriteTimeout       (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID CommError          (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID CompleteImmediate  (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID TimeoutImmediate   (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID CompleteWait       (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID TimeoutXoff        (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID CompleteXoff       (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID StartTimerLowerRTS (PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);
    VOID InvokePerhapsLowerRTS(PKdDpc Dpc, PVOID SystemContext1, PVOID SystemContext2);

    NTSTATUS StartWrite();
    NTSTATUS StartRead();
    NTSTATUS StartFlush();
    NTSTATUS StartMask();
    NTSTATUS StartPurge();
    VOID StartImmediate();

    VOID KillAllReadsOrWrites(PLIST_ENTRY QueueToClean, PKdIrp CurrentOpIrp);
    VOID HandleReducedIntBuffer();
    VOID ProdXonXoff( IN BOOLEAN SendXon );

    VOID PutChar(IN UCHAR CharToPut);

    UCHAR ProcessLSR();
    ULONG HandleModemUpdate(IN BOOLEAN DoingTX);
    BOOLEAN SetupNewHandFlow(IN PSERIAL_HANDFLOW NewHandFlow);

    LARGE_INTEGER GetCharTime();

    VOID GetProperties(IN PSERIAL_COMMPROP Properties);

    NTSTATUS StartOrQueue(KdIrp Irp,
                          PLIST_ENTRY QueueToExamine,
                          PKdIrp CurrentOpIrp,
                          PSERIAL_START_ROUTINE Starter);

    NTSTATUS GetDivisorFromBaud(LONG DesiredBaud, PSHORT pAppropriateDivisor = NULL);

    ULONG GetCharsFromIntBuffer();

    NTSTATUS ResizeBuffer();
    ULONG MoveToNewIntBuffer(PUCHAR NewBuffer);
    
    BOOLEAN IsrCallBack(KdIrq *Irq, PVOID Context);
    BOOLEAN ISR(PVOID Context);
    BOOLEAN SharerIsr(PVOID Context);
    BOOLEAN IndexedMultiportIsr(PVOID Context);
    BOOLEAN BitMappedMultiportIsr(PVOID Context);

    BOOLEAN GiveWriteToIsr();
    BOOLEAN GiveImmediateToIsr();
    BOOLEAN GrabImmediateFromIsr();
    BOOLEAN SetBaud(IN PVOID Context);
    BOOLEAN Reset();
    BOOLEAN SetLineControl();
    BOOLEAN ProcessEmptyTransmit();
    BOOLEAN GrabReadFromIsr();
    BOOLEAN UpdateReadByIsr();
    BOOLEAN UpdateInterruptBuffer(IN PVOID Context);
    BOOLEAN UpdateAndSwitchToUser(IN PVOID Context);
    BOOLEAN UpdateAndSwitchToNew(IN PVOID Context);
    BOOLEAN SetDTR();
    BOOLEAN ClrDTR();
    BOOLEAN SetRTS();
    BOOLEAN ClrRTS();
    BOOLEAN SetChars(IN PVOID Context);
    BOOLEAN SetHandFlow(IN PVOID Context);
    BOOLEAN TurnOnBreak();
    BOOLEAN TurnOffBreak();
    BOOLEAN PretendXoff();
    BOOLEAN PretendXon();
    BOOLEAN GetModemUpdate(IN PVOID Context);
    BOOLEAN GetCommStatus(IN PVOID Context);
    BOOLEAN SetEscapeChar(IN PVOID Context);
    BOOLEAN GetStats(IN PVOID Context);
    BOOLEAN DecrementRTSCounter();
    BOOLEAN MarkOpen();
    BOOLEAN CheckOpen(IN PVOID Context);
    BOOLEAN NullSynch();
    BOOLEAN MarkClose();
    BOOLEAN PurgeInterruptBuff();
    BOOLEAN PerhapsLowerRTS();
    BOOLEAN ClearStats();
    BOOLEAN GrabWaitFromIsr();
    BOOLEAN GiveWaitToIsr();
    BOOLEAN FinishOldWait();
    BOOLEAN GrabWriteFromIsr();
    BOOLEAN GrabXoffFromIsr();
    BOOLEAN GiveXoffToIsr();

    VOID GetNextWrite(PKdIrp CurrentOpIrp,
                      PLIST_ENTRY QueueToProcess,
                      PKdIrp NewIrp,
                      BOOLEAN CompleteCurrent);

    VOID GetNextIrp(PKdIrp CurrentOpIrp,
                    PLIST_ENTRY QueueToProcess,
                    PKdIrp NextIrp,
                    BOOLEAN CompleteCurrent);

    VOID GetNextImmediate(KdIrp *CurrentOpIrp,
                          PLIST_ENTRY QueueToProcess,
                          KdIrp *NewIrp,
                          BOOLEAN CompleteCurrent);

    typedef BOOLEAN (KdSerialDevice::*ISR_FUNCTION)(PVOID Context);
    typedef struct _SERIAL_ISR_CONTEXT 
    {
        ISR_FUNCTION pFunction;
        PVOID Context;
    } SERIAL_ISR_CONTEXT, *PSERIAL_ISR_CONTEXT;

/*********************************************************************************************
*********************************************************************************************/
    // Holds & Reports the resources that the device needs 
    KdResources m_Resources;

    // Mark this as registered device;
    BOOLEAN m_fRegisteredDeviceMap;

    // This holds the isr that should be called from our own
    // dispatching isr for "cards" that are trying to share the
    // same interrupt.
    // This holds the context that should be used when we
    // call the above service routine.
    SERIAL_ISR_CONTEXT m_TopLevelIsr;

    // This links together all of the different "cards" that are
    // trying to share the same interrupt of a non-mca machine.
    LIST_ENTRY m_TopLevelSharers;

    // This circular doubly linked list links together all
    // devices that are using the same interrupt object.
    // NOTE: This does not mean that they are using the
    // same interrupt "dispatching" routine.
    LIST_ENTRY m_CommonInterruptObject;

    // For reporting resource usage, we keep around the physical
    // address we got from the registry.
    PHYSICAL_ADDRESS m_OriginalController;

    // For reporting resource usage, we keep around the physical
    // address we got from the registry.
    PHYSICAL_ADDRESS m_OriginalInterruptStatus;

    // This value is set by the read code to hold the time value
    // used for read interval timing.  We keep it in the device

⌨️ 快捷键说明

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