/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_USB_DRIVER_DEFINES_H__
#define ANDROID_USB_DRIVER_DEFINES_H__
/** \file
This file consists of constants, types and macros used (and useful) in driver
development.
*/
/** \name IRQL assertions
These assertions help to verify that code is running at expected IRQL
*/
///@{
/// Asserts that current IRQL is less than provided level
#define ASSERT_IRQL_LESS(irql_level) ASSERT(KeGetCurrentIrql() < irql_level)
/// Asserts that current IRQL is less or equal than provided level
#define ASSERT_IRQL_LESS_OR_EQUAL(irql_level) ASSERT(KeGetCurrentIrql() <= irql_level)
/// Asserts that current IRQL is the same as provided level
#define ASSERT_IRQL_IS(irql_level) ASSERT(irql_level == KeGetCurrentIrql())
/// Asserts that current IRQL is less than DISPATCH_LEVEL
#define ASSERT_IRQL_LOW() ASSERT_IRQL_LESS(DISPATCH_LEVEL)
/// Asserts that current IRQL is above APC_LEVEL
#define ASSERT_IRQL_HIGH() ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL)
/// Asserts that current IRQL is at PASSIVE_LEVEL
#define ASSERT_IRQL_PASSIVE() ASSERT_IRQL_IS(PASSIVE_LEVEL)
/// Asserts that current IRQL is at APC_LEVEL
#define ASSERT_IRQL_APC() ASSERT_IRQL_IS(APC_LEVEL)
/// Asserts that current IRQL is at DISPATCH_LEVEL
#define ASSERT_IRQL_DISPATCH() ASSERT_IRQL_IS(DISPATCH_LEVEL)
/// Asserts that current IRQL is at APC or DISPATCH_LEVEL
#define ASSERT_IRQL_APC_OR_DISPATCH() \
ASSERT((KeGetCurrentIrql() == APC_LEVEL) || (KeGetCurrentIrql() == DISPATCH_LEVEL))
/// Asserts that current IRQL is less or equal DISPATCH_LEVEL
#define ASSERT_IRQL_LOW_OR_DISPATCH() \
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL)
///@}
#if DBG
/** \brief Overrides DbgPrint to make sure that nothing gets printed
to debug output in release build.
*/
ULONG __cdecl GoogleDbgPrint(char* format, ...);
#else
#define GoogleDbgPrint(Arg) NOTHING
#endif
/// Invalid UCHAR value
#define INVALID_UCHAR (static_cast<UCHAR>(0xFF))
/// Invalid ULONG value
#define INVALID_ULONG (static_cast<ULONG>(-1))
/** Enum AndroidUsbWdfObjectType enumerates types of KMDF objects that
we extend in our driver.
*/
enum AndroidUsbWdfObjectType {
// We start enum with 1 insetead of 0 to protect orselves from a dangling
// or uninitialized context structures because KMDF will zero our extension
// when it gets created.
/// Device object context
AndroidUsbWdfObjectTypeDevice = 1,
/// File object context
AndroidUsbWdfObjectTypeFile,
/// Request object context
AndroidUsbWdfObjectTypeRequest,
/// Workitem object context
AndroidUsbWdfObjectTypeWorkitem,
/// Illegal (maximum) context id
AndroidUsbWdfObjectTypeMax
};
/** Structure AndroidUsbWdfObjectContext represents our context that extends
every KMDF object (device, file, pipe, etc).
*/
typedef struct TagAndroidUsbWdfObjectContext {
/// KMDF object type that is extended with this context
AndroidUsbWdfObjectType object_type;
/// Instance of the class that extends KMDF object with this context
class AndroidUsbWdfObject* wdf_object_ext;
} AndroidUsbWdfObjectContext;
// KMDF woodoo to register our extension and implement accessor method
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfObjectContext,
GetAndroidUsbWdfObjectContext)
/** Structure AndroidUsbWdfRequestContext represents our context that is
associated with every request recevied by the driver.
*/
typedef struct TagAndroidUsbWdfRequestContext {
/// KMDF object type that is extended with this context
/// (must be AndroidUsbWdfObjectTypeRequest)
AndroidUsbWdfObjectType object_type;
/// System time request has been first scheduled
// (time of the first WdfRequestSend is called for it)
LARGE_INTEGER sent_at;
/// KMDF descriptor for the memory allocated for URB
WDFMEMORY urb_mem;
/// MDL describing the transfer buffer
PMDL transfer_mdl;
/// Private MDL that we build in order to perform the transfer
PMDL mdl;
// Virtual address for the current segment of transfer.
void* virtual_address;
/// Number of bytes remaining to transfer
ULONG length;
/// Number of bytes requested to transfer
ULONG transfer_size;
/// Accummulated number of bytes transferred
ULONG num_xfer;
/// Initial timeout (in millisec) set for this request
ULONG initial_time_out;
// Read / Write selector
bool is_read;
// IOCTL selector
bool is_ioctl;
} AndroidUsbWdfRequestContext;
// KMDF woodoo to register our extension and implement accessor method
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfRequestContext,
GetAndroidUsbWdfRequestContext)
/** Structure AndroidUsbWorkitemContext represents our context that is
associated with workitems created by our driver.
*/
typedef struct TagAndroidUsbWorkitemContext {
/// KMDF object type that is extended with this context
/// (must be AndroidUsbWdfObjectTypeWorkitem)
AndroidUsbWdfObjectType object_type;
/// Pipe file object extension that enqueued this work item
class AndroidUsbPipeFileObject* pipe_file_ext;
} AndroidUsbWorkitemContext;
// KMDF woodoo to register our extension and implement accessor method
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWorkitemContext,
GetAndroidUsbWorkitemContext)
#endif // ANDROID_USB_DRIVER_DEFINES_H__