ULONG u.Interrupt.Level The interrupt IRQL
ULONG u.Interrupt.Vector The interrupt vector
ULONG u.Interrupt.Affinity The set of processors to which the interrupt is dispatched.
USHORT Flags CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE CM_RESOURCE_INTERRUPT_LATCHED
DMA (Type==CmResourceTypeDma)
ULONG u.Dma.Channel System DMA controller channel
ULONG u.Dma.Port MCA type device port
USHORT Flags See the DDK
Other resource types
UCHAR Type CmResourceTypeDeviceSpecific CmResourceTypeBusNumber CmResourceTypeDevicePrivate CmResourceTypePcCardConfig

The RetrieveResources code shown in Listing 9.13 extracts and checks the resources that have been assigned for this device. It first checks whether any resources have been assigned. As Wdm2 does not need any resources, it simply returns STATUS_SUCCESS if there are no resources.

RetrieveResources then goes through the partial resource descriptor list checking for I/O Port, Memory, and Interrupt resource types. The assigned information is stored in the device extension and printed out using DebugPrint. Other resource types result in an error.

Listing 9.13 RetrievereSources routine

NTSTATUS RetrieveResources(IN PWDM2_DEVICE_EXTENSION dx, IN PCM_RESOURCE_LIST AllocatedResourcesTranslated) {

 if (AllocatedResourcesTranslated==NULL || AllocatedResourcesTranslated->Count==0) {

  DebugPrintMsg('RetrieveResources: No allocated translated resources');

  return STATUS_SUCCESS; // or whatever

 }

 // Get to actual resources

 PCM_PARTIAL_RESOURCE_LIST list = &AllocatedResourcesTranslated->List[0].PartialResourceList;

 PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = list->PartialDescriptors;

 ULONG NumResources = list->Count;

 DebugPrint('RetrieveResources: %d resource lists %d resources', AllocatedResourcesTranslated->Count, NumResources);

 bool GotError = false;

 // Clear dx

 dx->GotInterrupt = false;

 dx->GotPortOrMemory = false;

 dx->PortInIOSpace = false;

 dx->PortNeedsMapping = false;

 // Go through each allocated resource

 for (ULONG i=0; i<NumResources; i++,resource++) {

  switch (resource->Type) {

  case CmResourceTypePort:

   if (dx->GotPortOrMemory) {

    GotError = true;

    break;

   }

   dx->GotPortOrMemory = true;

   dx->PortStartAddress = resource->u.Port.Start;

   dx->PortLength = resource->u.Port.Length;

   dx->PortNeedsMapping = (resource->Flags & CM_RESOURCE_PORT_IO)==0;

   dx->PortInIOSpace = !dx->PortNeedsMapping;

   DebugPrint('RetrieveResources: Port %x%x Length %d NeedsMapping %c',

    dx->PortStartAddress.HighPart, dx->PortStartAddress.LowPart, dx->PortLength, dx->PortNeedsMapping);

   break;

  case CmResourceTypeInterrupt:

   dx->GotInterrupt = true;

   dx->Irql = (KIRQL)resource->u.Interrupt.Level;

   dx->Vector = resource->u.Interrupt.Vector;

   dx->Affinity = resource->u.Interrupt.Affinity;

   dx->Mode = (resource->Flags = CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;

   DebugPrint('RetrieveResources: Interrupt vector %x IRQL %d Affinity %d Mode %d',

    dx->Vector, dx->Irql, dx->Affinity, dx->Mode);

   break;

  case CmResourceTypeMemory:

   if (dx->GotPortOrMemory) { GotError = true; break; }

   dx->GotPortOrMemory = true;

   dx->PortStartAddress = resource->u.Memory.Start;

   dx->PortLength = resource->u.Memory.Length;

   dx->PortNeedsMapping = true;

   DebugPrint('RetrieveResources: Memory %x%x Length %d',

    dx->PortStartAddress.HighPart, dx->PortStartAddress.LowPart, dx->PortLength);

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×