?? usbcom.h
字號:
/*++
Module Name:
USBCOM.H
Abstract:
Kernel mode definitions and function prototypes
Environment:
Kernel mode
Notes:
Copyright (c) 1997-2000 Maverick Corporation. All Rights Reserved.
Revision History:
04/26/00 : created
--*/
#ifndef USBCOM_INCD
#define USBCOM_INCD
#include "ntddser.h"
#include "BusbDbg.h"
#include "serial.h"
#include "wmidata.h"
#include "wmilib.h"
// the size of the transfer buffer on your test board or device
#define UsbCom_TEST_BOARD_TRANSFER_BUFFER_SIZE (64 *1024 )
#define THREAD_DELAY_VALUE (ULONG)(-1 * 1 * 1000) // 0.5 ms
//
// Default xon/xoff characters.
//
#define SERIAL_DEF_XON 0x11
#define SERIAL_DEF_XOFF 0x13
#define THREAD_NOTIFIED 0
#define DATA_REQUEST_EVENT 1
#define BULK_REQUEST_COMPLETED 2
#define WRITE_DATA_EVENT 1
#define WRITE_COMPLETE_NOTIFY 2
//Flags values
#define IO_FLAGS_DATA_IN 1
#define IO_FLAGS_DATA_OUT 2
#define IO_FLAGS_SCATTER_GATHER 4
#define READ_REQUEST 0
#define WRITE_REQUEST 1
#define SYMBOLIC_NAME_LENGTH 128
#define DEVICE_OBJECT_NAME_LENGTH 128
#define UsbCom_MAX_TRANSFER_SIZE 256
#define SERIAL_DEVICE_MAP L"SERIALCOMM"
//#define DEFAULT_DIRECTORY L"DosDevices"
#define MIN(a,b) ((a) < (b) ? (a) :(b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
// used to track driver-generated io irps for staged read/write processing
typedef struct _UsbCom_RW_CONTEXT {
PURB Urb;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PMDL Mdl;
} UsbCom_RW_CONTEXT, *PUsbCom_RW_CONTEXT;
typedef struct _IOPACKET
{
ULONG Fdo;
PVOID Iop;
UCHAR* Cdb;
UCHAR CdbLength ;
PUCHAR DataBuffer;
ULONG DataLength;
ULONG BlockSize;
ULONG Flags;
ULONG Status;
ULONG BytesXmitOrRecv;
ULONG RequestType;
ULONG VxdSerObjContext;
ULONG VxdSerIOPacketContext;
ULONG WdmSerialContext;
UCHAR DummyBuffer[2048];
} IOPACKET, *PIOPACKET;
typedef struct _pack_2_pointers
{
PVOID pointer1;
PVOID pointer2;
} PACK_TWO_POINTERS, * P_PACK_TWO_POINTERS;
// used to track information on pipes in use;
// currently just to flag if opened or closed
typedef struct UsbCom_PIPEINFO {
BOOLEAN fPipeOpened;
} UsbCom_PIPEINFO, *PUsbCom_PIPEINFO;
extern ULONG GlobalPdaCount;
#define OutPipeMaxSize 16
//
// A structure representing the instance information associated with
// this particular device.
//
typedef struct _DEVICE_EXTENSION {
// Device object we call when submitting Urbs
PDEVICE_OBJECT TopOfStackDeviceObject;
// The bus driver object
PDEVICE_OBJECT PhysicalDeviceObject;
//
// This points to the symbolic link name that will be
// linked to the actual nt device name.
//
UNICODE_STRING SymbolicLinkName;
//
// We keep a pointer around to our device name for dumps
// and for creating "external" symbolic links to this
// device.
//
UNICODE_STRING DeviceName;
//
// Points to the device object that contains
// this device extension.
//
PDEVICE_OBJECT DeviceObject;
ULONG VxdSerObjContext;
// In data bulk pipe
ULONG DataInPipe;
// Out data bulk pipe
ULONG DataOutPipe;
// Status interrupt pipe
ULONG InterruptPipe;
// IRP used to poll for interrupts
PIRP PollingIrp;
// URB used to poll for interrupts
PURB PollingUrb;
BOOLEAN pollpending; // polling irp is pending (interrupt pipe)
// interrupt data
UCHAR intdata[4];
// IRP used to read
PIRP ReadingIrp;
// URB used to read
PURB ReadingUrb;
// Read data
UCHAR ReadData[64];
BOOLEAN readpending; // reading irp is pending (IN BULK pipe)
// IRP used to write
PIRP WritingIrp;
// URB used to write
PURB WritingUrb;
// Read data
UCHAR WriteData[16];
// Indicates number of bytes in array, WriteData to transfer.
ULONG WriteSize;
BOOLEAN writepending; // writing irp is pending (OUT BULK pipe)
ULONG CurrentSGD;
PIO_WORKITEM WorkItem;
KDPC IoCtrlTimerDpc;
KTIMER IoCtrlTimer;
// use mutex to guard somethings.
// Since there is a single I/O completion handler we need to make
// sure that it is not pre-empted or called twice
KMUTEX CompleteRequestMutex;
PIRP ReadIrp;
PIRP WriteIrp;
PIRP IoCtrlIrp;
DEVICE_POWER_STATE CurrentDevicePowerState;
// USB configuration handle and ptr for the configuration the
// device is currently in
USBD_CONFIGURATION_HANDLE UsbConfigurationHandle;
PUSB_CONFIGURATION_DESCRIPTOR UsbConfigurationDescriptor;
// ptr to the USB device descriptor
// for this device
PUSB_DEVICE_DESCRIPTOR UsbDeviceDescriptor;
// we support one interface
// this is a copy of the info structure
// returned from select_configuration or
// select_interface
PUSBD_INTERFACE_INFORMATION UsbInterface;
//Bus drivers set the appropriate values in this structure in response
//to an IRP_MN_QUERY_CAPABILITIES IRP. Function and filter drivers might
//alter the capabilities set by the bus driver.
DEVICE_CAPABILITIES DeviceCapabilities;
// used to save the currently-being-handled system-requested power irp request
PIRP PowerIrp;
// used to save base Irp ( user-originated via IOCTL ) of staged read/write request
PIRP BaseIrp;
// used to save URB of short, non-staged read/write requests
PURB BaseUrb;
// count of self-staged irps pending
ULONG StagedPendingIrpCount;
// count of self-staged bytes read or written so far
ULONG StagedBytesTransferred;
// set when PendingIoCount goes to 0; flags device can be removed
KEVENT RemoveEvent;
// set when PendingIoCount goes to 1 ( 1st increment was on add device )
// this indicates no IO requests outstanding, either user, system, or self-staged
KEVENT NoPendingIoEvent;
// set to signal driver-generated power request is finished
KEVENT SelfRequestedPowerIrpEvent;
// spinlock used to protect inc/dec iocount logic
KSPIN_LOCK IoCountSpinLock;
// incremented when device is added and any IO request is received;
// decremented when any io request is completed or passed on, and when device is removed
ULONG PendingIoCount;
// count of open pipes
ULONG OpenPipeCount;
// ptr to array of structs to track pipeinfo;
// in this basic sample it's only used to track if open/closed;
PUsbCom_PIPEINFO PipeInfo;
// save ptr to array of info on self-generated IRPS for staged read/writes;
// will allocate this separately
PUsbCom_RW_CONTEXT PendingIoIrps;
UNICODE_STRING DeviceNameLink;
// Name buffer for our named Functional device object link
// The name is generated based on the driver's class GUID
WCHAR DeviceLinkNameBuffer[ MAXIMUM_FILENAME_LENGTH ]; // MAXIMUM_FILENAME_LENGTH defined in wdm.h
//flag set when processing IRP_MN_REMOVE_DEVICE
BOOLEAN DeviceRemoved;
// flag set when driver has answered success to IRP_MN_QUERY_REMOVE_DEVICE
BOOLEAN RemoveDeviceRequested;
// flag set when driver has answered success to IRP_MN_QUERY_STOP_DEVICE
BOOLEAN StopDeviceRequested;
// flag set when device has been successfully started
BOOLEAN DeviceStarted;
// flag set when IRP_MN_WAIT_WAKE is received and we're in a power state
// where we can signal a wait
BOOLEAN EnabledForWakeup;
// used to flag that we're currently handling a self-generated power request
BOOLEAN SelfPowerIrp;
// default power state to power down to on self-suspend
ULONG PowerDownLevel;
// default maximum transfer per staged irp size
ULONG MaximumTransferSize;
// Henry's modifications start here. 31/7/2000
//
// This list head is used to contain the time ordered list
// of read requests. Access to this list is protected by
// the global cancel spinlock.
//
LIST_ENTRY ReadQueue;
//
// This list head is used to contain the time ordered list
// of write requests. Access to this list is protected by
// the global cancel spinlock.
//
LIST_ENTRY WriteQueue;
//
// This list head is used to contain the time ordered list
// of set and wait mask requests. Access to this list is protected by
// the global cancel spinlock.
//
LIST_ENTRY MaskQueue;
//
// Holds the serialized list of purge requests.
//
LIST_ENTRY PurgeQueue;
//
// This points to the irp that is currently being processed
// for the read queue. This field is initialized by the open to
// NULL.
//
// This value is only set at dispatch level. It may be
// read at interrupt level.
//
PIRP CurrentReadIrp;
//
// This points to the irp that is currently being processed
// for the write queue.
//
// This value is only set at dispatch level. It may be
// read at interrupt level.
//
PIRP CurrentWriteIrp;
//
// Points to the irp that is currently being processed to
// affect the wait mask operations.
//
PIRP CurrentMaskIrp;
//
// Points to the irp that is currently being processed to
// purge the read/write queues and buffers.
//
PIRP CurrentPurgeIrp;
//
// Points to the current irp that is waiting on a comm event.
//
PIRP CurrentWaitIrp;
//
// Points to the irp that is being used to send an immediate
// character.
//
PIRP CurrentImmediateIrp;
//
// Points to the irp that is being used to count the number
// of characters received after an xoff (as currently defined
// by the IOCTL_SERIAL_XOFF_COUNTER ioctl) is sent.
//
PIRP CurrentXoffIrp;
//
// Holds the number of bytes remaining in the current write
// irp.
//
// This location is only accessed while at interrupt level.
//
ULONG WriteLength;
//
// Holds a pointer to the current character to be sent in
// the current write.
//
// This location is only accessed while at interrupt level.
//
PUCHAR WriteCurrentChar;
//
// This is a buffer for the read processing.
//
// The buffer works as a ring. When the character is read from
// the device it will be place at the end of the ring.
//
// Characters are only placed in this buffer at interrupt level
// although character may be read at any level. The pointers
// that manage this buffer may not be updated except at interrupt
// level.
//
PUCHAR InterruptReadBuffer;
//
// This is a pointer to the first character of the buffer into
// which the interrupt service routine is copying characters.
//
PUCHAR ReadBufferBase;
//
// This is a count of the number of characters in the interrupt
// buffer. This value is set and read at interrupt level. Note
// that this value is only *incremented* at interrupt level so
// it is safe to read it at any level. When characters are
// copied out of the read buffer, this count is decremented by
// a routine that synchronizes with the ISR.
//
ULONG CharsInInterruptBuffer;
//
// Points to the first available position for a newly received
// character. This variable is only accessed at interrupt level and
// buffer initialization code.
//
PUCHAR CurrentCharSlot;
//
// This variable is used to contain the last available position
// in the read buffer. It is updated at open and at interrupt
// level when switching between the users buffer and the interrupt
// buffer.
//
PUCHAR LastCharSlot;
//
// This marks the first character that is available to satisfy
// a read request. Note that while this always points to valid
// memory, it may not point to a character that can be sent to
// the user. This can occur when the buffer is empty.
//
PUCHAR FirstReadableChar;
//
// Pointer to the lock variable returned for this extension when
// locking down the driver
//
PVOID LockPtr;
//
// This variable holds the size of whatever buffer we are currently
// using.
//
ULONG BufferSize;
//
// This variable holds .8 of BufferSize. We don't want to recalculate
// this real often - It's needed when so that an application can be
// "notified" that the buffer is getting full.
//
ULONG BufferSizePt8;
BOOLEAN ToSubmitReadUrb;
// This flag is to indicate that there is currently no read urb in the USBD stack.
// Although there should always be a read urb waiting for data from dongle, it is
// stopped because the interrupt buffer is getting full (80%).
BOOLEAN NoReadUrb;
//
// This value holds the number of characters desired for a
// particular read. It is initially set by read length in the
// IRP. It is decremented each time more characters are placed
// into the "users" buffer buy the code that reads characters
// out of the typeahead buffer into the users buffer. If the
// typeahead buffer is exhausted by the read, and the reads buffer
// is given to the isr to fill, this value is becomes meaningless.
//
ULONG NumberNeededForRead;
//
// This mask will hold the bitmask sent down via the set mask
// ioctl. It is used by the interrupt service routine to determine
// if the occurence of "events" (in the serial drivers understanding
// of the concept of an event) should be noted.
//
ULONG IsrWaitMask;
//
// This mask will always be a subset of the IsrWaitMask. While
// at device level, if an event occurs that is "marked" as interesting
// in the IsrWaitMask, the driver will turn on that bit in this
// history mask. The driver will then look to see if there is a
// request waiting for an event to occur. If there is one, it
// will copy the value of the history mask into the wait irp, zero
// the history mask, and complete the wait irp. If there is no
// waiting request, the driver will be satisfied with just recording
// that the event occured. If a wait request should be queued,
// the driver will look to see if the history mask is non-zero. If
// it is non-zero, the driver will copy the history mask into the
// irp, zero the history mask, and then complete the irp.
//
ULONG HistoryMask;
//
// This is a pointer to the where the history mask should be
// placed when completing a wait. It is only accessed at
// device level.
//
// We have a pointer here to assist us to synchronize completing a wait.
// If this is non-zero, then we have wait outstanding, and the isr still
// knows about it. We make this pointer null so that the isr won't
// attempt to complete the wait.
//
// We still keep a pointer around to the wait irp, since the actual
// pointer to the wait irp will be used for the "common" irp completion
// path.
//
ULONG *IrpMaskLocation;
//
// This mask holds all of the reason that transmission
// is not proceeding. Normal transmission can not occur
// if this is non-zero.
//
// This is only written from interrupt level.
// This could be (but is not) read at any level.
//
ULONG TXHolding;
//
// This mask holds all of the reason that reception
// is not proceeding. Normal reception can not occur
// if this is non-zero.
//
// This is only written from interrupt level.
// This could be (but is not) read at any level.
//
ULONG RXHolding;
//
// This holds the reasons that the driver thinks it is in
// an error state.
//
// This is only written from interrupt level.
// This could be (but is not) read at any level.
//
ULONG ErrorWord;
//
// This keeps a total of the number of characters that
// are in all of the "write" irps that the driver knows
// about. It is only accessed with the cancel spinlock
// held.
//
ULONG TotalCharsQueued;
//
// This holds a count of the number of characters read
// the last time the interval timer dpc fired. It
// is a long (rather than a ulong) since the other read
// completion routines use negative values to indicate
// to the interval timer that it should complete the read
// if the interval timer DPC was lurking in some DPC queue when
// some other way to complete occurs.
//
LONG CountOnLastRead;
//
// This is a count of the number of characters read by the
// isr routine. It is *ONLY* written at isr level. We can
// read it at dispatch level.
//
ULONG ReadByIsr;
//
// This holds the current baud rate for the device.
//
ULONG CurrentBaud;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -