流微型驱动开发指南介绍

流微型驱动开发指南介绍

二、Stream Class Minidriver之间的接口

 

流类接口(Stream Class Interface)主要由介于Class DriverMinidriver之间的一系列的函数调用组成。Class Driver对请求的流程(Request Flow)进行控制,当有必要对适配器硬件进行存取时,它就调用适配器的MinidriverClass Driver还负责对多处理器和中断同步作出响应。当Class DriverMinidriver都初始化完毕之后,Minidriver将处于一个被动的地位,它只能被Class Driver所调用,而绝大多数的调用都是非常低级的服务请求。

Minidriver来说,对命令和信息(Commands and Information)进行控制的最基本的机制就是流请求块(Streaming Request Block)。每个Minidriver都有一系列的SRB来对其某个特定的功能进行访问,而且一般说来,设备所支持的每种数据流都有相应的SRB与之对应。这些信息(SRB)通过操作系统控制的DMA缓冲区(它是一个环形队列)传递给设备。

一个SRB由一个命令码字段,以及与该命令码相关联的其他数据所组成。结构体HW_STREAM_REQUEST_BLOCK包含了和特定的SRB相关的所有信息。我们常常把这个结构体就简称为SRB,它体内还包含了一些作为对命令码的补充信息的其他参数。结构体HW_STREAM_REQUEST_BLOCK的定义如下:

typedef struct _HW_STREAM_REQUEST_BLOCK

{

{

ULONG SizeOfThisPacket;

SRB_COMMAND Command;

NTSTATUS Status;

PHW_STREAM_OBJECT StreamObject;

PVOID HwDeviceExtension;

PVOID SRBExtension;

 

union _CommandData

{

PKSSTREAM_HEADER DataBufferArray;

PHW_STREAM_DESCRIPTOR StreamBuffer;

KSSTATE StreamState;

PSTREAM_PROPERTY_DESCRIPTOR PropertyInfo;

PKSDATAFORMAT OpenFormat;

struct _PORT_CONFIGURATION_INFORMATION * ConfigInfo;

HANDLE MasterClockHandle;

DEVICE_POWER_STATE DeviceState;

PSTREAM_DATA_INTERSECT_INFO IntersectInfo;

} CommandData;

 

ULONG NumberOfBuffers;

ULONG TimeoutCounter;

ULONG TimeoutOriginal;

struct _HW_STREAM_REQUEST_BLOCK* NextSRB;

PIRP Irp;

ULONG Flags;

PVOID HwInstanceExtension;

 

union

{

ULONG NumberOfBytesToTransfer;

ULONG ActualBytesTransferred;

};

 

PKSSCATTER_GATHER ScatterGatherBuffer

ULONG NumberOfPhysicalPages;

ULONG Reserved[2];

} HW_STREAM_REQUEST_BLOCK, *PHW_STREAM_REQUEST_BLOCK;

关于对以上其他参数的解释,参见DDK文档,这里不再赘述。

下图解释了流类(Stream Class)和Minidriver在初始化时所进行的交互动作。

·初始化适配器

所有的流式Minidriver函数并不一定非要和Minidriver的中断服务例程(Interrupt Service RoutineISR)同步,因而Minidriver的代码是不可重入的(Non-re-entrant,相应的概念叫做可重入代码,又叫做纯代码。关于可重入代码的概念,请参考西电版操作系统教材),亦即,当Minidriver正在执行一个线程的时候,不能再调用Minidriver内其他任何函数,包括中断服务例程在内。这种非可重入的特性即便在支持多处理器的Windows NT/2000系统下也是存在的,这样可以令Minidriver编写起来更加方便。为了达到这样的特性,流类驱动(Stream Class Driver)会在Minidriver体内任何例程被执行时,通过内核例程KeSynchronizeExecution屏蔽Streaming Minidriver的中断请求IRQ(和所有低优先级的IRQ)。如果想了解更多关于同步的信息,请参看MiniDriver同步一章。Streaming Minidriver可以在必要的时候调用WDM系统服务。但是,Minidriver自己并没有设备对象,他是利用ClassDriver的设备对象来完成系统调用的。绝大多数Minidriver是不需要进行WDM系统调用的,因为几乎所有必要的功能都已经被Class Driver所涵盖了,没有必要直接进行系统调用。

必须知道的是,当进行WDM系统服务调用时,所有的Minidriver的入口点都会在高于DISPATCH_LEVEL的中断优先级下被调用(注意不包括DISPATCH_LEVEL中断优先级)。但有一个例外,那就是StreamClassCallAtNewPriority例程,此函数允许在DISPATCH_LEVEL

PASSIVE_LEVEL中断优先级上进行系统服务调用,具体哪个优先级取决于调用时所指定的优先级别。如果要一劳永逸地修改这个对IRQL的调用限制,可以通过把HW_INITIALIZATION_DATA结构体中的BOOL型成员变量TurnOffSynchronization简单置为TRUE来实现之。

流微型驱动开发指南介绍