专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » 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         {


标签:reactos
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: