首页 »编程综合 » reactos:reactos操作系统实现(95) »正文
reactos:reactos操作系统实现(95)
来源: 发布时间:星期一, 2009年9月28日 浏览:0次 评论:0
在PNP管理器里 最重要 处理 就是即插即用消息 下面来分析键盘 即插即用消息处理 实现 代码如下: #001 NTSTATUS NTAPI #002 i8042Pnp( #003 IN PDEVICE_OBJECT DeviceObject, #004 IN PIRP Irp) #005 { #006 PIO_STACK_LOCATION Stack; #007 ULONG MinorFunction; #008 I8042_DEVICE_TYPE DeviceType; #009 ULONG_PTR Information = 0; #010 NTSTATUS Status; #011 获取IRP 栈 #012 Stack = IoGetCurrentIrpStackLocation(Irp); 获取IRP次功能代码 #013 MinorFunction = Stack->MinorFunction; 获取设备类型 #014 DeviceType = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type; #015 根据即插即用次功能代码处理 #016 switch (MinorFunction) #017 { 分配资源并启动 个设备 #018 IRP_MN_START_DEVICE: /* 0x00 */ #019 { #020 TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); #021 如果设备类型不为物理设备类型 就处理 #022 /* Call lower driver ( any) */ #023 (DeviceType != PhysicalDeviceObject) #024 {
向前传送IRP 并等待回应 #025 Status = ForwardIrpAndWait(DeviceObject, Irp); 如果回应IRP成功 就 i8042PnpStartDevice 来分配资源 #026 (NT_SUCCESS(Status)) #027 Status = i8042PnpStartDevice( #028 DeviceObject, #029 Stack->Parameters.StartDevice.AllocatedResources, #030 Stack->Parameters.StartDevice.AllocatedResourcesTranslated); #031 } #032 #033 Status = STATUS_SUCCESS; #034 ; #035 } 查询是否有子设备 #036 IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x07 */ #037 { #038 switch (Stack->Parameters.QueryDeviceRelations.Type) #039 { PNP 管理器向设备发送 个带有 BusRelations 码 IRP_MN_QUERY_DEVICE_RELATIONS 请求来获得设备 子设备列表 这里回应 子设备列表为0个 #040 BusRelations: #041 { #042 PDEVICE_RELATIONS DeviceRelations; #043 #044 TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); #045 DeviceRelations = ExAllocatePool(PagedPool, (DEVICE_RELATIONS)); #046 (DeviceRelations) #047 { #048 DeviceRelations->Count = 0; #049 Information = (ULONG_PTR)DeviceRelations; #050 Status = STATUS_SUCCESS; #051 } #052 #053 Status = STATUS_INSUFFICIENT_RESOURCES; #054 ; #055 }
这里处理即插即用 删除子设备 IRP #056 RemovalRelations: #057 { #058 TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); #059 ForwardIrpAndForget(DeviceObject, Irp); #060 } 缺省 IRP处理 #061 default: #062 ERR_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", #063 Stack->Parameters.QueryDeviceRelations.Type); #064 ASSERT(FALSE); #065 ForwardIrpAndForget(DeviceObject, Irp); #066 } #067 ; #068 } 过滤系统请求 资源 #069 IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0x0d */ #070 { #071 TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); #072 /* Nothing to do */ #073 Status = Irp->IoStatus.Status; #074 ; #075 } #076 default: #077 { #078 ERR_(I8042PRT, "IRP_MJ_PNP / unknown minor function 0x%x\n", MinorFunction); #079 ASSERT(FALSE); #080 ForwardIrpAndForget(DeviceObject, Irp); #081 } #082 } #083
IRP完成设置 #084 Irp->IoStatus.Information = Information; #085 Irp->IoStatus.Status = Status; #086 IoCompleteRequest(Irp, IO_NO_INCREMENT); #087 Status; #088 } #089 接着来分析启动设备 消息 i8042PnpStartDevice 实现代码如下: #001 NTSTATUS #002 i8042PnpStartDevice( #003 IN PDEVICE_OBJECT DeviceObject, #004 IN PCM_RESOURCE_LIST AllocatedResources, #005 IN PCM_RESOURCE_LIST AllocatedResourcesTranslated) #006 { #007 PFDO_DEVICE_EXTENSION DeviceExtension; #008 PPORT_DEVICE_EXTENSION PortDeviceExtension; #009 PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor, ResourceDescriptorTranslated; #010 INTERRUPT_DATA InterruptData; #011 BOOLEAN FoundDataPort = FALSE; #012 BOOLEAN FoundControlPort = FALSE; #013 BOOLEAN FoundIrq = FALSE; #014 ULONG i; #015 NTSTATUS Status; #016 #017 TRACE_(I8042PRT, "i8042PnpStartDevice(%p)\n", DeviceObject); 获取设备扩展对象 #018 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 获取当前端口对象 #019 PortDeviceExtension = DeviceExtension->PortDeviceExtension; #020 #021 ASSERT(DeviceExtension->PnpState dsStopped); #022
即插即用管理器分配资源失败 因此直接返回 #023 (!AllocatedResources) #024 { #025 WARN_(I8042PRT, "No allocated resources sent to driver\n"); #026 STATUS_INSUFFICIENT_RESOURCES; #027 } 如果分配资源数量不对 就返回出错 #028 (AllocatedResources->Count != 1) #029 { #030 WARN_(I8042PRT, "Wrong number of allocated resources sent to driver\n"); #031 STATUS_INSUFFICIENT_RESOURCES; #032 } 判断分配资源 版本是否 样 如果不 样也需要返回出错 #033 (AllocatedResources->List[0].PartialResourceList.Version != 1 #034 || AllocatedResources->List[0].PartialResourceList.Revision != 1 #035 || AllocatedResourcesTranslated->List[0].PartialResourceList.Version != 1 #036 || AllocatedResourcesTranslated->List[0].PartialResourceList.Revision != 1) #037 { #038 WARN_(I8042PRT, "Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n", #039 AllocatedResources->List[0].PartialResourceList.Version, #040 AllocatedResources->List[0].PartialResourceList.Revision, #041 AllocatedResourcesTranslated->List[0].PartialResourceList.Version, #042 AllocatedResourcesTranslated->List[0].PartialResourceList.Revision); #043 STATUS_REVISION_MISMATCH; #044 } #045
获取操作系统分配资源 比如端口地址和使用内存 还有中断号等等 #046 /* Get Irq and optionally control port and data port */ #047 for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i) #048 { 资源描述结构 #049 ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i]; #050 ResourceDescriptorTranslated = &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i]; 根据资源类型来处理 #051 switch (ResourceDescriptor->Type) #052 { 分配 端口资源 #053 CmResourceTypePort: #054 { 找到端口资源 #055 (ResourceDescriptor->u.Port.Length 1) #056 { #057 /* We assume that the first ressource will #058 * be the control port and the second one #059 * will be the data port... #060 */ 先判断是否数据端口
#061 (!FoundDataPort) #062 { 保存系统分配 数据端口地址 #063 PortDeviceExtension->DataPort = ULongToPtr(ResourceDescriptor- #064 >u.Port.Start.u.LowPart); #065 INFO_(I8042PRT, "Found data port: %p\n", PortDeviceExtension->DataPort); #066 FoundDataPort = TRUE; #067 } #068 (!FoundControlPort) #069 { 保存系统分配 控制命令端口地址 #070 PortDeviceExtension->ControlPort = ULongToPtr(ResourceDescriptor- #071 >u.Port.Start.u.LowPart); #072 INFO_(I8042PRT, "Found control port: %p\n", PortDeviceExtension->ControlPort); #073 FoundControlPort = TRUE; #074 } #075 #076 { 其它是分配 端口地址
#077 WARN_(I8042PRT, "Too much I/O ranges provided: 0x%lx\n", ResourceDescriptor- #078 >u.Port.Length); #079 STATUS_INVALID_PARAMETER; #080 } #081 } #082 #083 WARN_(I8042PRT, "Invalid I/O range length: 0x%lx\n", ResourceDescriptor->u.Port.Length); #084 ; #085 } 这里处理系统分配 中断资源 #086 CmResourceTypeInterrupt: #087 { 如果已经分配了中断 就返回出错 #088 (FoundIrq) #089 STATUS_INVALID_PARAMETER; 保存中断资源 #090 InterruptData.Dirql = (KIRQL)ResourceDescriptorTranslated->u.Interrupt.Level; #091 InterruptData.Vector = ResourceDescriptorTranslated->u.Interrupt.Vector; #092 InterruptData.Affinity = ResourceDescriptorTranslated->u.Interrupt.Affinity;
中断模式 #093 (ResourceDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED) #094 InterruptData.InterruptMode = Latched; #095 #096 InterruptData.InterruptMode = LevelSensitive; 中断源是否共享 #097 InterruptData.ShareInterrupt = (ResourceDescriptorTranslated->ShareDisposition CmResourceShareShared); #098 INFO_(I8042PRT, "Found irq resource: %lu\n", ResourceDescriptor->u.Interrupt.Level); #099 FoundIrq = TRUE; #100 ; #101 } #102 default: #103 WARN_(I8042PRT, "Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type); #104 } #105 } #106 如果没有分配中断资源 就返回出错 #107 (!FoundIrq) #108 { #109 WARN_(I8042PRT, "Interrupt resource was not found in allocated resources list\n"); #110 STATUS_INSUFFICIENT_RESOURCES; #111 } #112 (DeviceExtension->Type Keyboard && (!FoundDataPort || !FoundControlPort)) #113 {
如果是键盘类型 但又没有分配数据端口和命令控制端口资源 也返回出错 #114 WARN_(I8042PRT, "Some required resources were not found in allocated resources list\n"); #115 STATUS_INSUFFICIENT_RESOURCES; #116 } #117 (DeviceExtension->Type Mouse && (FoundDataPort || FoundControlPort)) #118 { 如果是鼠标类型 但又没有分配数据端口和命令控制端口资源 也返回出错 #119 WARN_(I8042PRT, "Too much resources were provided in allocated resources list\n"); #120 STATUS_INVALID_PARAMETER; #121 } #122 根据区别类型来处理 #123 switch (DeviceExtension->Type) #124 { #125 Keyboard: #126 { 键盘类型处理 StartProcedure来处理键盘中断设置 并启动键盘 #127 RtlCopyMemory( #128 &PortDeviceExtension->KeyboardInterrupt, #129 &InterruptData, #130 (INTERRUPT_DATA)); #131 PortDeviceExtension->Flags |= KEYBOARD_STARTED; #132 Status = StartProcedure(PortDeviceExtension); #133 ; #134 } #135 Mouse: #136 {
相关文章
读者评论
发表评论
|
|