windows-nt/Source/XPSP1/NT/drivers/wdm/usb/driver/usbser/usbser.h

980 lines
32 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/****************************************************************************
Copyright (c) 1998 Microsoft Corporation
Module Name:
USBSER.H
Abstract:
This header file is used for the Legacy USB Modem Driver
Environment:
Kernel mode & user mode
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 1998 Microsoft Corporation. All Rights Reserved.
Revision History:
12/23/97 : created
Author:
Tom Green
****************************************************************************/
#ifndef __USBSER_H__
#define __USBSER_H__
#ifdef DRIVER
// Various definitions
#define NAME_MAX 80
#define MILLISECONDS_TIMEOUT(x) ((ULONGLONG) ((-x) * 10000))
#define NOTIFICATION_BUFF_SIZE 10
#define MAXIMUM_TRANSFER_SIZE (8 * 1024)
#define RX_BUFF_SIZE (16 * 1024)
#define USB_RX_BUFF_SIZE (RX_BUFF_SIZE / 4)
#define LOW_WATER_MARK (USB_RX_BUFF_SIZE * 3)
#define DEVICE_STATE_UNKNOWN 0x0000
#define DEVICE_STATE_STARTED 0x0001
#define DEVICE_STATE_STOPPED 0x0002
#define DEVICE_STATE_REMOVED 0x0003
// device capabilities
#define DEVICE_CAP_VERSION 0x0001
#define DEVICE_CAP_UNUSED_PARAM ((ULONG) -1)
// these describe bits in the modem status register
#define SERIAL_MSR_DCTS 0x0001
#define SERIAL_MSR_DDSR 0x0002
#define SERIAL_MSR_TERI 0x0004
#define SERIAL_MSR_DDCD 0x0008
#define SERIAL_MSR_CTS 0x0010
#define SERIAL_MSR_DSR 0x0020
#define SERIAL_MSR_RI 0x0040
#define SERIAL_MSR_DCD 0x0080
//
// These masks define access to the line status register. The line
// status register contains information about the status of data
// transfer. The first five bits deal with receive data and the
// last two bits deal with transmission. An interrupt is generated
// whenever bits 1 through 4 in this register are set.
//
//
// This bit is the data ready indicator. It is set to indicate that
// a complete character has been received. This bit is cleared whenever
// the receive buffer register has been read.
//
#define SERIAL_LSR_DR 0x01
//
// This is the overrun indicator. It is set to indicate that the receive
// buffer register was not read befor a new character was transferred
// into the buffer. This bit is cleared when this register is read.
//
#define SERIAL_LSR_OE 0x02
//
// This is the parity error indicator. It is set whenever the hardware
// detects that the incoming serial data unit does not have the correct
// parity as defined by the parity select in the line control register.
// This bit is cleared by reading this register.
//
#define SERIAL_LSR_PE 0x04
//
// This is the framing error indicator. It is set whenever the hardware
// detects that the incoming serial data unit does not have a valid
// stop bit. This bit is cleared by reading this register.
//
#define SERIAL_LSR_FE 0x08
//
// This is the break interrupt indicator. It is set whenever the data
// line is held to logic 0 for more than the amount of time it takes
// to send one serial data unit. This bit is cleared whenever the
// this register is read.
//
#define SERIAL_LSR_BI 0x10
//
// This is the transmit holding register empty indicator. It is set
// to indicate that the hardware is ready to accept another character
// for transmission. This bit is cleared whenever a character is
// written to the transmit holding register.
//
#define SERIAL_LSR_THRE 0x20
//
// This bit is the transmitter empty indicator. It is set whenever the
// transmit holding buffer is empty and the transmit shift register
// (a non-software accessable register that is used to actually put
// the data out on the wire) is empty. Basically this means that all
// data has been sent. It is cleared whenever the transmit holding or
// the shift registers contain data.
//
#define SERIAL_LSR_TEMT 0x40
//
// This bit indicates that there is at least one error in the fifo.
// The bit will not be turned off until there are no more errors
// in the fifo.
//
#define SERIAL_LSR_FIFOERR 0x80
//
// Serial naming values
//
//
// Maximum length for symbolic link
//
#define SYMBOLIC_NAME_LENGTH 128
//
// This define gives the default Object directory
// that we should use to insert the symbolic links
// between the NT device name and namespace used by
// that object directory.
#define DEFAULT_DIRECTORY L"DosDevices"
//
// Where in the DeviceMap section of the registry serial port entries
// should appear
//
#define SERIAL_DEVICE_MAP L"SERIALCOMM"
// performance info for modem driver
typedef struct _PERF_INFO
{
BOOLEAN PerfModeEnabled;
ULONG BytesPerSecond;
} PERF_INFO, *PPERF_INFO;
#define SANITY_CHECK ((ULONG) 'ENAS')
#else
#include <winioctl.h>
#endif
// IOCTL info, needs to be visible for application
#define USBSER_IOCTL_INDEX 0x0800
#define GET_DRIVER_LOG CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 0, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define GET_IRP_HIST CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 1, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define GET_PATH_HIST CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 2, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define GET_ERROR_LOG CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 3, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define GET_ATTACHED_DEVICES CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 4, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define SET_IRP_HIST_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 5, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define SET_PATH_HIST_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 6, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define SET_ERROR_LOG_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 7, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define GET_DRIVER_INFO CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 8, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define ENABLE_PERF_TIMING CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 9, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define DISABLE_PERF_TIMING CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 10, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define GET_PERF_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 11, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define SET_DEBUG_TRACE_LEVEL CTL_CODE(FILE_DEVICE_UNKNOWN, \
USBSER_IOCTL_INDEX + 12, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#ifdef DRIVER
// info about the driver, initialized in DriverEntry routine
PCHAR DriverName;
PCHAR DriverVersion;
ULONG Usbser_Debug_Trace_Level;
ULONG UsbSerSerialDebugLevel;
KSPIN_LOCK GlobalSpinLock;
//
// Count of how many times the paged code has been locked
//
ULONG PAGEUSBSER_Count;
//
// Handle to the locked paged code
//
PVOID PAGEUSBSER_Handle;
//
// Pointer to funcion
//
PVOID PAGEUSBSER_Function;
typedef struct _READ_CONTEXT
{
PURB Urb;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
} READ_CONTEXT, *PREAD_CONTEXT;
// device extension for driver instance, used to store needed data
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT PhysDeviceObject; // physical device object
PDEVICE_OBJECT StackDeviceObject; // stack device object
CHAR LinkName[NAME_MAX]; // string name of symbolic link
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // device descriptor for device
USBD_CONFIGURATION_HANDLE ConfigurationHandle; // configuration of USB device
USBD_PIPE_HANDLE DataInPipe; // pipe for reading data
USBD_PIPE_HANDLE DataOutPipe; // pipe for writing data
USBD_PIPE_HANDLE NotificationPipe; // pipe for getting notifications from the device
ULONG IRPCount; // number of IRPs that passed through this device object
LARGE_INTEGER ByteCount; // number of bytes of data passed through this device object
ULONG Instance; // instance of device
BOOLEAN IsDevice; // is this a device or "global" device object
BOOLEAN PerfTimerEnabled; // enable perf timing
LARGE_INTEGER BytesXfered; // byte count for perf
LARGE_INTEGER ElapsedTime; // elapsed time for perf
LARGE_INTEGER TimerStart; // timer start for perf
DEVICE_CAPABILITIES DeviceCapabilities;
ULONG PowerDownLevel;
DEVICE_POWER_STATE CurrentDevicePowerState;
PIRP PowerIrp;
BOOLEAN SelfPowerIrp;
KEVENT SelfRequestedPowerIrpEvent;
//
// Nota Bene: Locking hierarchy is acquire ControlLock *then*
// acquire CancelSpinLock. We don't want to stall other
// drivers waiting for the cancel spin lock
//
KSPIN_LOCK ControlLock; // protect extension
ULONG CurrentBaud; // current baud rate
SERIAL_TIMEOUTS Timeouts; // timeout controls for device
ULONG IsrWaitMask; // determine if occurence of events should be noticed
SERIAL_LINE_CONTROL LineControl; // current value of line control reg
SERIAL_HANDFLOW HandFlow; // Handshake and control flow settings
SERIALPERF_STATS PerfStats; // performance stats
SERIAL_CHARS SpecialChars; // special characters
ULONG DTRRTSState; // keep track of the current state of these lines
ULONG SupportedBauds; // "named" baud rates for device
UCHAR EscapeChar; // for LsrmstInsert IOCTL
USHORT FakeModemStatus; // looks like status register on modem
USHORT FakeLineStatus; // looks like line status register
USHORT RxMaxPacketSize; // max packet size fo the in data pipe
PIRP NotifyIrp; // Irp for notify reads
PURB NotifyUrb; // Urb for notify Irp
PIRP ReadIrp; // Irp for read requests
PURB ReadUrb; // Urb for read requests
KEVENT ReadEvent; // used to cancel a read Irp
ULONG CharsInReadBuff; // current number of characters buffered
ULONG CurrentReadBuffPtr; // pointer into read buffer
BOOLEAN AcceptingRequests; // is the device stopped or removed
PIRP CurrentMaskIrp; // current set or wait mask Irp
ULONG HistoryMask; // store mask events here
ULONG OpenCnt; // number of create calls on device
PUCHAR NotificationBuff; // buffer for notifications
PUCHAR ReadBuff; // circular buffer for read requests
PUCHAR USBReadBuff; // buffer to get data from device
UCHAR CommInterface; // index of communications interface
ULONG RxQueueSize; // fake read buffer size
ULONG ReadInterlock; // state machine for starting reads from completion routine
BOOLEAN ReadInProgress;
ULONG DeviceState; // current state of enumeration
//
// True if a symbolic link has been created and should be
// removed upon deletion.
//
BOOLEAN CreatedSymbolicLink;
//
// Symbolic link name -- e.g., \\DosDevices\COMx
//
UNICODE_STRING SymbolicLinkName;
//
// Dos Name -- e.g., COMx
//
UNICODE_STRING DosName;
//
// Device Name -- e.g., \\Devices\UsbSerx
//
UNICODE_STRING DeviceName;
//
// Current Read Irp which is pending
//
PIRP CurrentReadIrp;
//
// Current Write Irp which is pending
//
PIRP CurrentWriteIrp;
//
// Read queue
//
LIST_ENTRY ReadQueue;
//
// 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;
//
// Timer for timeout on total read request
//
KTIMER ReadRequestTotalTimer;
//
// Timer for timeout on the interval
//
KTIMER ReadRequestIntervalTimer;
//
// This is the kernal timer structure used to handle
// total time request timing.
//
KTIMER WriteRequestTotalTimer;
//
// This value is set by the read code to hold the time value
// used for read interval timing. We keep it in the extension
// so that the interval timer dpc routine determine if the
// interval time has passed for the IO.
//
LARGE_INTEGER IntervalTime;
//
// This holds the value that we use to determine if we should use
// the long interval delay or the short interval delay.
//
LARGE_INTEGER CutOverAmount;
//
// This holds the system time when we last time we had
// checked that we had actually read characters. Used
// for interval timing.
//
LARGE_INTEGER LastReadTime;
//
// This points the the delta time that we should use to
// delay for interval timing.
//
PLARGE_INTEGER IntervalTimeToUse;
//
// These two values hold the "constant" time that we should use
// to delay for the read interval time.
//
LARGE_INTEGER ShortIntervalAmount;
LARGE_INTEGER LongIntervalAmount;
//
// This dpc is fired off if the timer for the total timeout
// for the read expires. It will execute a dpc routine that
// will cause the current read to complete.
//
//
KDPC TotalReadTimeoutDpc;
//
// This dpc is fired off if the timer for the interval timeout
// expires. If no more characters have been read then the
// dpc routine will cause the read to complete. However, if
// more characters have been read then the dpc routine will
// resubmit the timer.
//
KDPC IntervalReadTimeoutDpc;
//
// This dpc is fired off if the timer for the total timeout
// for the write expires. It will execute a dpc routine that
// will cause the current write to complete.
//
//
KDPC TotalWriteTimeoutDpc;
//
// 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;
//
// If non-NULL, means this write timed out and we should correct the
// return value in the completion routine.
//
PIRP TimedOutWrite;
//
// If TRUE, that means we need to insert LSRMST
//
BOOLEAN EscapeSeen;
//
// Holds data that needs to be pushed such as LSRMST data
//
LIST_ENTRY ImmediateReadQueue;
//
// Pending wait-wake irp
//
PIRP PendingWakeIrp;
//
// True if WaitWake needs to be sent down before a powerdown
//
BOOLEAN SendWaitWake;
//
// SystemWake from devcaps
//
SYSTEM_POWER_STATE SystemWake;
//
// DeviceWake from devcaps
//
DEVICE_POWER_STATE DeviceWake;
//
// Count of Writes pending in the lower USB levels
//
ULONG PendingWriteCount;
//
// Counters and events to drain USB requests
//
KEVENT PendingDataInEvent;
KEVENT PendingDataOutEvent;
KEVENT PendingNotifyEvent;
KEVENT PendingFlushEvent;
ULONG PendingDataInCount;
ULONG PendingDataOutCount;
ULONG PendingNotifyCount;
ULONG SanityCheck;
// selective suspend support
PIRP PendingIdleIrp;
PUSB_IDLE_CALLBACK_INFO IdleCallbackInfo;
PIO_WORKITEM IoWorkItem;
IO_STATUS_BLOCK StatusBlock;
#ifdef SPINLOCK_TRACKING
LONG CancelSpinLockCount;
LONG SpinLockCount;
LONG WaitingOnCancelSpinLock;
LONG WaitingOnSpinLock;
#endif
#ifdef WMI_SUPPORT
//
// WMI Information
//
WMILIB_CONTEXT WmiLibInfo;
//
// Name to use as WMI identifier
//
UNICODE_STRING WmiIdentifier;
#endif
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _USBSER_IMMEDIATE_READ_PACKET {
//
// List of packets
//
LIST_ENTRY ImmediateReadQueue;
//
// Length of data
//
ULONG BufferLen;
//
// Buffer itself, leave last in struct
//
UCHAR Buffer;
} USBSER_IMMEDIATE_READ_PACKET, *PUSBSER_IMMEDIATE_READ_PACKET;
typedef struct _USBSER_WRITE_PACKET {
//
// Device extension for this write
//
PDEVICE_EXTENSION DeviceExtension;
//
// Irp this packet belongs with
//
PIRP Irp;
//
// Write timer
//
KTIMER WriteTimer;
//
// Timeout value
//
LARGE_INTEGER WriteTimeout;
//
// TimerDPC
//
KDPC TimerDPC;
//
// Status
//
NTSTATUS Status;
//
// Urb for this write N.B.: size is variable, so leave last
//
URB Urb;
} USBSER_WRITE_PACKET, *PUSBSER_WRITE_PACKET;
typedef NTSTATUS (*PUSBSER_START_ROUTINE)(IN PDEVICE_EXTENSION);
typedef VOID (*PUSBSER_GET_NEXT_ROUTINE) (IN PIRP *CurrentOpIrp,
IN PLIST_ENTRY QueueToProcess,
OUT PIRP *NewIrp,
IN BOOLEAN CompleteCurrent,
PDEVICE_EXTENSION Extension);
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
NTSTATUS
UsbSer_Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_Create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_Close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_Write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID
UsbSer_Unload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS
UsbSer_PnPAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject);
NTSTATUS
UsbSer_PnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_Power(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_SystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSer_Cleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSerMajorNotSupported(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS
UsbSerStartOrQueue(IN PDEVICE_EXTENSION PDevExt, IN PIRP PIrp,
IN PLIST_ENTRY PQueue, IN PIRP *PPCurrentIrp,
IN PUSBSER_START_ROUTINE Starter);
VOID
UsbSerCancelQueued(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
NTSTATUS
UsbSerStartRead(IN PDEVICE_EXTENSION PDevExt);
VOID
UsbSerCancelCurrentRead(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
BOOLEAN
UsbSerGrabReadFromRx(IN PVOID Context);
VOID
UsbSerTryToCompleteCurrent(IN PDEVICE_EXTENSION PDevExt,
IN KIRQL IrqlForRelease, IN NTSTATUS StatusToUse,
IN PIRP *PpCurrentOpIrp,
IN PLIST_ENTRY PQueue OPTIONAL,
IN PKTIMER PIntervalTimer OPTIONAL,
IN PKTIMER PTotalTimer OPTIONAL,
IN PUSBSER_START_ROUTINE Starter OPTIONAL,
IN PUSBSER_GET_NEXT_ROUTINE PGetNextIrp OPTIONAL,
IN LONG RefType, IN BOOLEAN Complete);
VOID
UsbSerReadTimeout(IN PKDPC PDpc, IN PVOID DeferredContext,
IN PVOID SystemContext1, IN PVOID SystemContext2);
VOID
UsbSerIntervalReadTimeout(IN PKDPC PDpc, IN PVOID DeferredContext,
IN PVOID SystemContext1, IN PVOID SystemContext2);
VOID
UsbSerKillPendingIrps(PDEVICE_OBJECT PDevObj);
VOID
UsbSerCompletePendingWaitMasks(IN PDEVICE_EXTENSION DeviceExtension);
VOID
UsbSerKillAllReadsOrWrites(IN PDEVICE_OBJECT PDevObj,
IN PLIST_ENTRY PQueueToClean,
IN PIRP *PpCurrentOpIrp);
VOID
UsbSerRestoreModemSettings(PDEVICE_OBJECT PDevObj);
VOID
UsbSerProcessEmptyTransmit(IN PDEVICE_EXTENSION PDevExt);
VOID
UsbSerWriteTimeout(IN PKDPC Dpc, IN PVOID DeferredContext,
IN PVOID SystemContext1, IN PVOID SystemContext2);
NTSTATUS
UsbSerGiveWriteToUsb(IN PDEVICE_EXTENSION PDevExt, IN PIRP PIrp,
IN LARGE_INTEGER TotalTime);
VOID
UsbSerCancelWaitOnMask(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
NTSTATUS
UsbSerWriteComplete(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
IN PUSBSER_WRITE_PACKET PPacket);
NTSTATUS
UsbSerFlush(IN PDEVICE_OBJECT PDevObj, PIRP PIrp);
NTSTATUS
UsbSerTossWMIRequest(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
IN ULONG GuidIndex);
NTSTATUS
UsbSerSystemControlDispatch(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp);
NTSTATUS
UsbSerSetWmiDataItem(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
IN ULONG GuidIndex, IN ULONG InstanceIndex,
IN ULONG DataItemId,
IN ULONG BufferSize, IN PUCHAR PBuffer);
NTSTATUS
UsbSerSetWmiDataBlock(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
IN ULONG GuidIndex, IN ULONG InstanceIndex,
IN ULONG BufferSize,
IN PUCHAR PBuffer);
NTSTATUS
UsbSerQueryWmiDataBlock(IN PDEVICE_OBJECT PDevObj, IN PIRP PIrp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG InstanceCount,
IN OUT PULONG InstanceLengthArray,
IN ULONG OutBufferSize,
OUT PUCHAR PBuffer);
NTSTATUS
UsbSerQueryWmiRegInfo(IN PDEVICE_OBJECT PDevObj, OUT PULONG PRegFlags,
OUT PUNICODE_STRING PInstanceName,
OUT PUNICODE_STRING *PRegistryPath,
OUT PUNICODE_STRING MofResourceName,
OUT PDEVICE_OBJECT *Pdo);
//
// 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 USBSER_REF_RXBUFFER (0x00000001)
#define USBSER_REF_CANCEL (0x00000002)
#define USBSER_REF_TOTAL_TIMER (0x00000004)
#define USBSER_REF_INT_TIMER (0x00000008)
#ifdef SPINLOCK_TRACKING
#define ACQUIRE_CANCEL_SPINLOCK(DEVEXT, IRQL) \
{ \
ASSERT(DEVEXT->SpinLockCount == 0); \
DEVEXT->WaitingOnCancelSpinLock++; \
IoAcquireCancelSpinLock(IRQL); \
DEVEXT->CancelSpinLockCount++; \
DEVEXT->WaitingOnCancelSpinLock--; \
ASSERT(DEVEXT->CancelSpinLockCount == 1); \
}
#define RELEASE_CANCEL_SPINLOCK(DEVEXT, IRQL) \
{ \
DEVEXT->CancelSpinLockCount--; \
ASSERT(DEVEXT->CancelSpinLockCount == 0); \
IoReleaseCancelSpinLock(IRQL); \
}
#define ACQUIRE_SPINLOCK(DEVEXT, LOCK, IRQL) \
{ \
DEVEXT->WaitingOnSpinLock++; \
KeAcquireSpinLock(LOCK, IRQL); \
DEVEXT->SpinLockCount++; \
DEVEXT->WaitingOnSpinLock--; \
ASSERT(DEVEXT->SpinLockCount == 1); \
}
#define RELEASE_SPINLOCK(DEVEXT, LOCK, IRQL) \
{ \
DEVEXT->SpinLockCount--; \
ASSERT(DEVEXT->SpinLockCount == 0); \
KeReleaseSpinLock(LOCK, IRQL); \
}
#else
#define ACQUIRE_CANCEL_SPINLOCK(DEVEXT, IRQL) IoAcquireCancelSpinLock(IRQL)
#define RELEASE_CANCEL_SPINLOCK(DEVEXT, IRQL) IoReleaseCancelSpinLock(IRQL)
#define ACQUIRE_SPINLOCK(DEVEXT, LOCK, IRQL) KeAcquireSpinLock(LOCK, IRQL)
#define RELEASE_SPINLOCK(DEVEXT, LOCK, IRQL) KeReleaseSpinLock(LOCK, IRQL)
#endif
#define USBSER_INIT_REFERENCE(Irp) { \
IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4 = NULL; \
}
#define USBSER_SET_REFERENCE(Irp,RefType) \
do { \
LONG _refType = (RefType); \
PUINT_PTR _arg4 = (PVOID)&IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4; \
*_arg4 |= _refType; \
} while (0)
#define USBSER_CLEAR_REFERENCE(Irp,RefType) \
do { \
LONG _refType = (RefType); \
PUINT_PTR _arg4 = (PVOID)&IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4; \
*_arg4 &= ~_refType; \
} while (0)
#define USBSER_REFERENCE_COUNT(Irp) \
((UINT_PTR)((IoGetCurrentIrpStackLocation((Irp))->Parameters.Others.Argument4)))
//
// These values are used by the routines that can be used
// to complete a read (other than interval timeout) to indicate
// to the interval timeout that it should complete.
//
#define SERIAL_COMPLETE_READ_CANCEL ((LONG)-1)
#define SERIAL_COMPLETE_READ_TOTAL ((LONG)-2)
#define SERIAL_COMPLETE_READ_COMPLETE ((LONG)-3)
#if DBG
#define USBSERDUMPRD ((ULONG)0x00000001)
#define USBSERDUMPWR ((ULONG)0x00000002)
#define USBSERCOMPEV ((ULONG)0x00000004)
#define USBSERTRACETM ((ULONG)0x00100000)
#define USBSERTRACECN ((ULONG)0x00200000)
#define USBSERTRACEPW ((ULONG)0x00400000)
#define USBSERTRACERD ((ULONG)0x01000000)
#define USBSERTRACEWR ((ULONG)0x02000000)
#define USBSERTRACEIOC ((ULONG)0x04000000)
#define USBSERTRACEOTH ((ULONG)0x08000000)
#define USBSERBUGCHECK ((ULONG)0x80000000)
#define USBSERTRACE ((ULONG)0x0F700000)
#define USBSERDBGALL ((ULONG)0xFFFFFFFF)
extern ULONG UsbSerSerialDebugLevel;
#define UsbSerSerialDump(LEVEL, STRING) \
do { \
ULONG _level = (LEVEL); \
if (UsbSerSerialDebugLevel & _level) { \
DbgPrint("UsbSer: "); \
DbgPrint STRING; \
} \
if (_level == USBSERBUGCHECK) { \
ASSERT(FALSE); \
} \
} while (0)
#else
#define UsbSerSerialDump(LEVEL,STRING) do {;} while (0)
#endif // DBG
#define USBSER_VENDOR_COMMAND 0
#define USBSER_CLASS_COMMAND 1
#endif // DRIVER
#endif // __USBSER_H__