static void gx_print_segment(const segment * pseg) { double px = fixed2float(pseg->pt.x); double py = fixed2float(pseg->pt.y); char out[80]; sprintf(out, "0x%lx<0x%lx,0x%lx>:%u", (ulong) pseg, (ulong) pseg->prev, (ulong) pseg->next, pseg->notes); switch (pseg->type) { case s_start:{ const subpath *const psub = (const subpath *)pseg; dprintf5(" %1.4f %1.4f moveto\t%% %s #curves=%d last=0x%lx\n", px, py, out, psub->curve_count, (ulong) psub->last); break; } case s_curve:{ const curve_segment *const pcur = (const curve_segment *)pseg; dprintf7(" %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f curveto\t%% %s\n", fixed2float(pcur->p1.x), fixed2float(pcur->p1.y), fixed2float(pcur->p2.x), fixed2float(pcur->p2.y), px, py, out); break; } case s_line: dprintf3(" %1.4f %1.4f lineto\t%% %s\n", px, py, out); break; case s_gap: dprintf3(" %1.4f %1.4f gapto\t%% %s\n", px, py, out); break; case s_dash:{ const dash_segment *const pd = (const dash_segment *)pseg; dprintf5(" %1.4f %1.4f %1.4f %1.4f dash\t%% %s\n", fixed2float(pd->pt.x), fixed2float(pd->pt.y), fixed2float(pd->tangent.x),fixed2float(pd->tangent.y), out); break; } case s_line_close:{ const line_close_segment *const plc = (const line_close_segment *)pseg; dprintf4(" closepath\t%% %s %1.4f %1.4f 0x%lx\n", out, px, py, (ulong) (plc->sub)); break; } default: dprintf4(" %1.4f %1.4f <type 0x%x>\t%% %s\n", px, py, pseg->type, out); } }
/* modified from gdevpcl.c, gdevmjc.c and gdevnpdl.c. */ static char * gdev_fmlbp_paper_size(gx_device_printer *dev) { static char paper[16]; int landscape = 0; /* portrait */ float height_inches = dev->height / dev->y_pixels_per_inch; float width_inches = dev->width / dev->x_pixels_per_inch; if (width_inches > height_inches){ /* landscape */ float t = width_inches; width_inches = height_inches; height_inches = t; landscape = 1; } sprintf(paper, "%s;%d", (height_inches >= 15.9 ? PAPER_SIZE_A3 : height_inches >= 11.8 ? (width_inches >= 9.2 ? PAPER_SIZE_B4 : PAPER_SIZE_LEGAL) : height_inches >= 11.1 ? PAPER_SIZE_A4 : height_inches >= 10.4 ? PAPER_SIZE_LETTER : height_inches >= 9.2 ? PAPER_SIZE_B5 : height_inches >= 7.6 ? PAPER_SIZE_A5 : PAPER_SIZE_HAGAKI), landscape); #ifdef FMLBP_DEBUG dprintf5("w=%d(%f) x h=%d(%f) -> %s\n", dev->width, width_inches, dev->height, height_inches, paper); #endif/*FMLBP_DEBUG*/ return paper; }
static void trace_drawing_color(const char *prefix, const gx_drawing_color *pdcolor) { dprintf1("%scolor=", prefix); if (pdcolor->type == gx_dc_type_none) dputs("none"); else if (pdcolor->type == gx_dc_type_null) dputs("null"); else if (pdcolor->type == gx_dc_type_pure) dprintf1("0x%lx", (ulong)pdcolor->colors.pure); else if (pdcolor->type == gx_dc_type_ht_binary) { int ci = pdcolor->colors.binary.b_index; dprintf5("binary(0x%lx, 0x%lx, %d/%d, index=%d)", (ulong)pdcolor->colors.binary.color[0], (ulong)pdcolor->colors.binary.color[1], pdcolor->colors.binary.b_level, (ci < 0 ? pdcolor->colors.binary.b_ht->order.num_bits : pdcolor->colors.binary.b_ht->components[ci].corder.num_bits), ci); } else if (pdcolor->type == gx_dc_type_ht_colored) { ulong plane_mask = pdcolor->colors.colored.plane_mask; int ci; dprintf1("colored(mask=%lu", plane_mask); for (ci = 0; plane_mask != 0; ++ci, plane_mask >>= 1) if (plane_mask & 1) { dprintf2(", (base=%u, level=%u)", pdcolor->colors.colored.c_base[ci], pdcolor->colors.colored.c_level[ci]); } else dputs(", -"); } else {
NTSTATUS SoundInitIoPort( IN OUT PGLOBAL_DEVICE_INFO pGDI, IN OUT PULONG Port ) { ULONG CurrentPort; int i; NTSTATUS Status; static CONST ULONG PortChoices[] = VALID_IO_PORTS; dprintf5((">>>> SoundInitIoPort(): Port = %8x", *Port)); Status = SoundPortValid(pGDI, Port); if (NT_SUCCESS(Status)) { return Status; } dprintf2(("No valid IO port found")); SoundSetErrorCode(pGDI->RegistryPathName, SOUND_CONFIG_NOCARD); return STATUS_DEVICE_CONFIGURATION_ERROR; }
NTSTATUS SoundInitHardwareConfig( IN OUT PGLOBAL_DEVICE_INFO pGDI, IN OUT PULONG Port, IN OUT PULONG InterruptNumber, IN OUT PULONG DmaChannel, IN OUT PULONG InputSource, IN ULONG DmaBufferSize ) { NTSTATUS Status; dprintf5(("SoundInitHardwareConfig(): Port = 0x%x", *Port)); dprintf5(("SoundInitHardwareConfig(): Interrupt = %d", *InterruptNumber)); dprintf5(("SoundInitHardwareConfig(): DMA Channel= %d", *DmaChannel)); dprintf5(("SoundInitHardwareConfig(): InputSource= %d", *InputSource)); dprintf5(("SoundInitHardwareConfig(): DmaBufSize = 0x%x", DmaBufferSize)); // Find port Status = SoundInitIoPort(pGDI, Port); if (!NT_SUCCESS(Status)) { return Status; } dprintf5(("SoundInitIoPort() Success!! Port = 0x%x", *Port)); // Find interrupt Status = SoundInitInterrupt(pGDI, InterruptNumber); if (!NT_SUCCESS(Status)) { return Status; } dprintf5(("SoundInitInterrupt() Success!! Int = %d", *InterruptNumber)); // Find DMA channel Status = SoundInitDmaChannel(pGDI, DmaChannel, DmaBufferSize); pGDI->DmaChannel = *DmaChannel; if (!NT_SUCCESS(Status)) { return Status; } dprintf5(("SoundInitDmaChannel() Success!! DMA chan = %d", *DmaChannel)); // Report all resources used Status = SoundReportResourceUsage(pGDI->DeviceObject[WaveInDevice], pGDI->BusType, pGDI->BusNumber, InterruptNumber, // Not use this value INTERRUPT_MODE, IRQ_SHARABLE, DmaChannel, Port, NUMBER_OF_SOUND_PORTS); if (!NT_SUCCESS(Status)) { return Status; } dprintf5(("SoundReportResourceUsage() Success!!")); // Check the input source if (*InputSource > INPUT_OUTPUT) { return STATUS_DEVICE_CONFIGURATION_ERROR; } // Now we know all our data we can set up the real hardware // The global device info now contains all device mappings etc if (!HwInitialize(&pGDI->WaveInfo, &pGDI->Hw, *DmaChannel, *InterruptNumber, *InputSource)) { SoundSetErrorCode(pGDI->RegistryPathName, SOUND_CONFIG_BADCARD); return STATUS_DEVICE_CONFIGURATION_ERROR; } dprintf5(("HwInitialize() Success!!")); return STATUS_SUCCESS; }
NTSTATUS SoundDmaChannelValid( IN OUT PGLOBAL_DEVICE_INFO pGDI, IN OUT PULONG DmaChannel, IN ULONG DmaBufferSize ) { NTSTATUS Status; DEVICE_DESCRIPTION DeviceDescription; // DMA adapter object // See if the hardware is happy // if (!pGDI->Hw.NoPCR && !HwIsDMAValid(&pGDI->Hw, *DmaChannel)) { return STATUS_DEVICE_CONFIGURATION_ERROR; } dprintf5(("HwIsDMAValid() Success!!")); // // Check we're going to be allowed to use this DmaChannel or whether // some other device thinks it owns this hardware // Status = SoundReportResourceUsage( pGDI->DeviceObject[WaveInDevice], // As good as any device to own it pGDI->BusType, pGDI->BusNumber, NULL, 0, FALSE, DmaChannel, NULL, 0); if (!NT_SUCCESS(Status)) { return Status; } // // See if we can get this channel // // // Zero the device description structure. // RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); // // Get the adapter object for this card. // DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; DeviceDescription.AutoInitialize = FALSE; DeviceDescription.DemandMode = !pGDI->SingleModeDMA; DeviceDescription.ScatterGather = FALSE; DeviceDescription.DmaChannel = *DmaChannel; DeviceDescription.InterfaceType = pGDI->BusType; DeviceDescription.DmaWidth = Width8Bits; DeviceDescription.DmaSpeed = Compatible; DeviceDescription.MaximumLength = DmaBufferSize; DeviceDescription.BusNumber = pGDI->BusNumber; return SoundGetCommonBuffer(&DeviceDescription, &pGDI->WaveInfo.DMABuf); }
NTSTATUS SoundPortValid( IN OUT PGLOBAL_DEVICE_INFO pGDI, IN OUT PULONG Port ) { NTSTATUS Status; dprintf5((">>> SoundPortValid(): Port = %8x", *Port)); // // Check we're going to be allowed to use this port or whether // some other device thinks it owns this hardware // Status = SoundReportResourceUsage( pGDI->DeviceObject[WaveInDevice], // As good as any device to own it pGDI->BusType, pGDI->BusNumber, NULL, 0, FALSE, NULL, Port, NUMBER_OF_SOUND_PORTS); if (!NT_SUCCESS(Status)) { return Status; } dprintf5(("SoundReportResourceUsage() Success!!")); // // Find where our device is mapped // pGDI->Hw.PortBase = SoundMapPortAddress( pGDI->BusType, pGDI->BusNumber, *Port, NUMBER_OF_SOUND_PORTS, &pGDI->MemType); dprintf4(("Mapped PortBase = %8x", pGDI->Hw.PortBase)); // // Finally we can check and see if the hardware is happy // if (HwIsIoValid(&pGDI->Hw)) { dprintf5(("HwIsIoValid() Success!!")); return STATUS_SUCCESS; } dprintf2(("HwIsIoValid() Faided!!")); // // Free any resources. (note we don't have to do // IoReportResourceUsage again because each one overwrites the // previous). // if (pGDI->MemType == 0) { MmUnmapIoSpace(pGDI->Hw.PortBase, NUMBER_OF_SOUND_PORTS); dprintf4(("Free IO space")); } pGDI->Hw.PortBase = NULL; return STATUS_DEVICE_CONFIGURATION_ERROR; }
NTSTATUS sndWaveRecord( IN OUT PLOCAL_DEVICE_INFO pLDI, IN OUT PIRP pIrp, IN PIO_STACK_LOCATION pIrpStack ) /*++ Routine Description: Add another buffer for recording. The wave header is the buffer parameter to the IOCTL. This routine just adds the buffer to the queue (of Irps) and returns - setting pending status. Arguments: pLDI - our local device information pIrp - The IO request packet we're processing pIrpStack - the current stack location Return Value: Irp Status. --*/ { NTSTATUS Status; Status = STATUS_PENDING; // // confirm we are doing this on an input device! // if (pLDI->DeviceType != WAVE_IN) { dprintf1("Attempt to record on output device"); return STATUS_NOT_SUPPORTED; } // // Inform debuggers that 0 length buffers are rather strange // if (pIrpStack->Parameters.Read.Length == 0) { dprintf1("Wave play buffer is zero length"); } // // Set return data length to 0 for now // pIrp->IoStatus.Information = 0; // // Put the request in the queue. // // // Acquire the spin lock // GlobalEnter(pLDI->pGlobalInfo); // // Set Irp status. Before we try and process it // pIrp->IoStatus.Status = STATUS_PENDING; Status = STATUS_PENDING; IoMarkIrpPending(pIrp); // // Add our buffer to the queue // InsertTailList(&pLDI->QueueHead, &pIrp->Tail.Overlay.ListEntry); dprintf5("irp added"); // // See if we can satisfy some requests straight away // if (pLDI->State == WAVE_DD_RECORDING) { sndFillInputBuffers(pLDI, UpperHalf + LowerHalf - pLDI->pGlobalInfo->NextHalf); } // // Ok to release the spin lock now // GlobalLeave(pLDI->pGlobalInfo); // // Mark this request as pending completion. // The Dpc deferred procedure call routine does the rest. // return Status; }
BOOLEAN SoundISR( IN PKINTERRUPT pInterrupt, IN PVOID Context ) /*++ Routine Description: Interrupt service routine for the soundblaster card. Arguments: pInterrupt - our interrupt Contest - Pointer to our global device info Return Value: TRUE if we handled the interrupt --*/ { PGLOBAL_DEVICE_INFO pGDI; BOOLEAN Result; UCHAR oldval; // pGDI = (PGLOBAL_DEVICE_INFO)Context; ASSERT(pGDI->Key == GDI_KEY); // dprintf1(( "I-1" )); dprintf5(("<")); // // Acknowledge the interrupt // HwInterruptAcknowledge(&pGDI->Hw); // Interrupt pin inactive if( pGDI->WaveInfo.Direction ){ if( pGDI->WaveInfo.MapOn ){ SoundFlushDMA( &pGDI->WaveInfo ); SoundMapDMA( &pGDI->WaveInfo ); } } // // See who the interrupt is for and request the // appropriate deferred routine // Result = TRUE; // // It is valid to test DMABusy because it is set ON before we start // interrupts if (pGDI->WaveInfo.DMABusy) { dprintf5((pGDI->WaveInfo.Direction ? "o" : "i")); // // Check to see if we're overrunning, don't queue a Dpc if // we are. // if (!pGDI->WaveInfo.DpcQueued) { pGDI->WaveInfo.DpcQueued = TRUE; // ASSERTMSG("Overrun count not zeroed by Dpc routine", // pGDI->WaveInfo.Overrun == 0); IoRequestDpc(pGDI->WaveInfo.DeviceObject, NULL, NULL); } else { // // Overrun ! // if (pGDI->WaveInfo.Overrun == 0) { dprintf2(("Wave overrun")); } pGDI->WaveInfo.Overrun++; } } else { #if DBG // We only get 10 valid interrupts when we test the interrupt // for validity in init.c. If we get lots more here there // may be a problem. sndBogusInterrupts++; if ((sndBogusInterrupts % 20) == 0) { dprintf(("%u bogus interrupts so far", sndBogusInterrupts - 10)); } #endif // DBG // // Set the return value to FALSE to say we didn't // handle the interrupt. // Result = FALSE; } dprintf5((">")); return Result; }
int search_bd_buf(char *buf, int len_bytes, unsigned long bd_offset_bytes, int *nr_populated_bdes) { unsigned long i; int total_entries = 0; dprintf3("%s(%p, %x, %lx, ...) buf end: %p\n", __func__, buf, len_bytes, bd_offset_bytes, buf + len_bytes); for (i = 0; i < len_bytes; i += sizeof(unsigned long)) { unsigned long bd_index = (bd_offset_bytes + i) / sizeof(unsigned long); unsigned long *bounds_dir_entry_ptr = (unsigned long *)&buf[i]; unsigned long bounds_dir_entry; unsigned long bd_for_vaddr; unsigned long bt_start; unsigned long bt_tail; int nr_entries; dprintf4("%s() loop i: %ld bounds_dir_entry_ptr: %p\n", __func__, i, bounds_dir_entry_ptr); bounds_dir_entry = *bounds_dir_entry_ptr; if (!bounds_dir_entry) { dprintf4("no bounds dir at index 0x%lx / 0x%lx " "start at offset:%lx %lx\n", bd_index, bd_index, bd_offset_bytes, i); continue; } dprintf3("found bounds_dir_entry: 0x%lx @ " "index 0x%lx buf ptr: %p\n", bounds_dir_entry, i, &buf[i]); /* mask off the enable bit: */ bounds_dir_entry &= ~0x1; (*nr_populated_bdes)++; dprintf4("nr_populated_bdes: %p\n", nr_populated_bdes); dprintf4("*nr_populated_bdes: %d\n", *nr_populated_bdes); bt_start = bounds_dir_entry; bt_tail = bounds_dir_entry + MPX_BOUNDS_TABLE_SIZE_BYTES - 1; if (!vaddr_mapped_by_range(bt_start)) { printf("bounds directory 0x%lx points to nowhere\n", bounds_dir_entry); mpx_dig_abort(); } if (!vaddr_mapped_by_range(bt_tail)) { printf("bounds directory end 0x%lx points to nowhere\n", bt_tail); mpx_dig_abort(); } /* * Each bounds directory entry controls 1MB of virtual address * space. This variable is the virtual address in the process * of the beginning of the area controlled by this bounds_dir. */ bd_for_vaddr = bd_index * (1UL<<20); nr_entries = dump_table(bounds_dir_entry, bd_for_vaddr, bounds_dir_global+bd_offset_bytes+i); total_entries += nr_entries; dprintf5("dir entry[%4ld @ %p]: 0x%lx %6d entries " "total this buf: %7d bd_for_vaddrs: 0x%lx -> 0x%lx\n", bd_index, buf+i, bounds_dir_entry, nr_entries, total_entries, bd_for_vaddr, bd_for_vaddr + (1UL<<20)); } dprintf3("%s(%p, %x, %lx, ...) done\n", __func__, buf, len_bytes, bd_offset_bytes); return total_entries; }
BOOLEAN StopDMA( IN PVOID Context ) /*++ Routine Description: This routine terminates DMA transfers and is synchronized with the controller interrupt. Arguments: Context - Supplies pointer to global device info. Return Value: Returns TRUE --*/ { PGLOBAL_DEVICE_INFO pGDI; UCHAR regval; PSOUND_REGISTERS pSoundRegisters; pGDI = (PGLOBAL_DEVICE_INFO)Context; pSoundRegisters = pGDI->SoundHardware.SoundVirtualBase; // // Decrement count of pending interrupts. // if (pGDI->Usage == SoundInterruptUsageWaveIn) { pGDI->SoundHardware.TcInterruptsPending -= 1; } else { pGDI->SoundHardware.TcInterruptsPending -= 1; // Kills both buffers } dprintf5("StopDma(): Decremented Intr pending %d ", pGDI->SoundHardware.TcInterruptsPending ); // // Turn off the input volume if we were recording // // if (pGDI->Usage == SoundInterruptUsageWaveIn) { // regval = READAUDIO_RICNTRL(&pSoundRegisters); // WRITEAUDIO_RICNTRL(&pSoundRegisters, (regval | MON_ATTN_MASK) ); //} // // Terminate transfer // // // Clear the enable bit or any outstanding interrupts. // regval = READAUDIO_DMACNTRL(&pSoundRegisters); WRITEAUDIO_DMACNTRL(&pSoundRegisters, (regval & ~(REC_ENABLE|PLAY_ENABLE))); regval = READAUDIO_CONFIG(&pSoundRegisters); WRITEAUDIO_CONFIG(&pSoundRegisters, (regval & ~(REC_OVF_INTR|PLAY_UND_INTR))); regval = READAUDIO_ENDIAN(&pSoundRegisters); WRITEAUDIO_ENDIAN(&pSoundRegisters, (regval & ~DMA_TCINTR)); return TRUE; }
VOID sndReStartDMA( IN PGLOBAL_DEVICE_INFO pGDI, IN int WhichBuffer ) /*++ Routine Description: Restart the DMA on a given channel Arguments: pGDI - Supplies pointer to global device info. WhichBuffer - which channel to use Return Value: Returns FALSE --*/ { ULONG length; length = pGDI->DmaHalfBufferSize; // // Increment count of pending interrupts. // pGDI->SoundHardware.TcInterruptsPending += 1; dprintf5("sndReStartDMA(): incremented pending interrupts %d", pGDI->SoundHardware.TcInterruptsPending); // // Program the DMA controller registers for the transfer // Set the direction of transfer by whether we're wave in or // wave out. // KeFlushIoBuffers( pGDI->pDMABufferMDL[WhichBuffer], (pGDI->Usage == SoundInterruptUsageWaveIn), TRUE); dprintf4("sndReStartDMA(): calling IoMapTransfer BUFFER = %d", WhichBuffer); if (pGDI->Usage == SoundInterruptUsageWaveIn) { IoMapTransfer(pGDI->pAdapterObject[(WhichBuffer) ? 3 : 2], pGDI->pDMABufferMDL[WhichBuffer], pGDI->pMRB[WhichBuffer], pGDI->DMABuffer[WhichBuffer].Buf, &length, (BOOLEAN)(pGDI->Usage != SoundInterruptUsageWaveIn)); } else { IoMapTransfer(pGDI->pAdapterObject[WhichBuffer], pGDI->pDMABufferMDL[WhichBuffer], pGDI->pMRB[WhichBuffer], pGDI->DMABuffer[WhichBuffer].Buf, &length, (BOOLEAN)(pGDI->Usage != SoundInterruptUsageWaveIn)); } }
VOID sndStartDMA( IN PGLOBAL_DEVICE_INFO pGDI, IN int PlayBack ) /*++ Routine Description: Allocate the adapter channel (this had better not wait !) Arguments: pGDI - Pointer to the global device data Return Value: None --*/ { ULONG DataLong; // // Test if DMA is already running // ASSERT(pGDI->DMABusy == FALSE); pGDI->DMABusy = TRUE; dprintf5("sndStartDMA()"); // // Program the DMA hardware (isn't this a bit illegal ?) // DataLong = 0; ((PDMA_CHANNEL_MODE)(&DataLong))->AccessTime = ACCESS_200NS; if (pGDI->BytesPerSample == 1) { ((PDMA_CHANNEL_MODE)(&DataLong))->TransferWidth = WIDTH_8BITS; } else { ((PDMA_CHANNEL_MODE)(&DataLong))->TransferWidth = WIDTH_16BITS; } if (PlayBack){ ((PDMA_CHANNEL_MODE)(&DataLong))->BurstMode = 0x01; WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_A].Mode.Long, DataLong); WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_B].Mode.Long, DataLong); } else { WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_A+2].Mode.Long, DataLong); WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_B+2].Mode.Long, DataLong); } // // Allocate an adapter channel. When the system allocates // the channel, processing will continue in the sndProgramDMA // routine below. // if (PlayBack) { dprintf4("Allocating adapter channel (buffer = 0)"); IoAllocateAdapterChannel(pGDI->pAdapterObject[0], pGDI->pWaveOutDevObj, BYTES_TO_PAGES(pGDI->DmaHalfBufferSize), sndProgramDMA, (PVOID)0); // Context } else { dprintf4("Allocating adapter channel (buffer = 2)"); IoAllocateAdapterChannel(pGDI->pAdapterObject[2], pGDI->pWaveInDevObj, BYTES_TO_PAGES(pGDI->DmaHalfBufferSize), sndProgramDMA, (PVOID)0); // Context } // // Execution will continue in sndProgramDMA when the // adapter has been allocated // }
PUCHAR SoundMapPortAddress( INTERFACE_TYPE BusType, ULONG BusNumber, ULONG PortBase, ULONG Length, PULONG MemType ) /*++ Routine Description : Map a physical device port address to an address we can pass to READ/WRITE_PORT_UCHAR/USHORT etc Arguments : BusType - type of bus BusNumber - bus number PortBase - The port start address Length - how many bytes of port space to map (needed by MmMapIoSpace) Return Value : The virtual port address --*/ { PHYSICAL_ADDRESS PortAddress; PHYSICAL_ADDRESS MappedAddress; *MemType = 0; // Memory Space PortAddress.LowPart = PortBase; PortAddress.HighPart = 0; dprintf5((">>>> PortBase = %8x", PortBase)); dprintf4(("HalTranslateBusAddress()2: Bustype = %d", BusType)); dprintf4(("HalTranslateBusAddress()2: BusNumber = %d", BusNumber)); dprintf4(("HalTranslateBusAddress()2: PortAddr.lo = 0x%16x", PortAddress.LowPart)); dprintf4(("HalTranslateBusAddress()2: PortAddr.hi = 0x%16x", PortAddress.HighPart)); dprintf4(("HalTranslateBusAddress()2: MemType = %d", *MemType)); HalTranslateBusAddress( BusType, BusNumber, PortAddress, MemType, &MappedAddress); dprintf4(("HalTranslateBusAddress()2: MemType(Out) = %d", *MemType)); dprintf4(("HalTranslateBusAddress()2: MapAddr(Out) = 0x%16x", MappedAddress)); if (*MemType == 0) { // // Map memory type IO space into our address space // return (PUCHAR)MmMapIoSpace(MappedAddress, Length, FALSE); } else { return (PUCHAR)MappedAddress.LowPart; } }
NTSTATUS SoundReportResourceUsage( IN PDEVICE_OBJECT DeviceObject, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN PULONG InterruptNumber OPTIONAL, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN InterruptShareDisposition, IN PULONG DmaChannel OPTIONAL, IN PULONG FirstIoPort OPTIONAL, IN ULONG IoPortLength ) /*++ Routine Description : Calls IoReportResourceUsage for the device and resources passed in. NOTE that this supercedes previous resources declared for this device. It is assumed that all resources owned by the device cannot be shared, except for level-sensitive interrupts which can be shared. Arguments : DeviceObject - The device which 'owns' the resources This can also be a pointer to a driver object BusType - The type of bus on which the device lives BusNumber - The bus number (of type BusType) where the device is InterruptNumber - The interrupt the devices uses (if any) DmaChannel - The DMA channel the device uses FirstIoPort - The start Io port for the device IoPortLength - The number of bytes of IO space the device uses (starting at FirstIoPort) Return Value : STATUS_SUCCESS if no problems The return from IoReportResourceUsage if this fails STATUS_DEVICE_CONFIGURATION_ERROR is IoReportResourceUsage reports a conflict --*/ { NTSTATUS Status; // // Our resource list to report back to the system // /* Compiler rejects this UCHAR ResBuffer[FIELD_OFFSET( CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[3].Type)]; */ UCHAR ResBuffer[3 * sizeof(CM_RESOURCE_LIST)]; BOOLEAN ResourceConflict; PCM_RESOURCE_LIST ResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; ResourceList = (PCM_RESOURCE_LIST)ResBuffer; Descriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; ResourceConflict = FALSE; // // Zero out any unused data // RtlZeroMemory(ResBuffer, sizeof(ResBuffer)); // // We assume there's only 1 bus so we only need one list. // Fill in the bus description // ResourceList->Count = 1; ResourceList->List[0].InterfaceType = BusType; ResourceList->List[0].BusNumber = BusNumber; // // If the device is using IO Ports add this to the list // if (ARGUMENT_PRESENT(FirstIoPort)) { PHYSICAL_ADDRESS PortAddress; ULONG MemType; PHYSICAL_ADDRESS MappedAddress; PortAddress.LowPart = *FirstIoPort; PortAddress.HighPart = 0; dprintf5((">>>> FirstPort = %8x", *FirstIoPort)); MemType = 0; dprintf4(("HalTranslateBusAddress(): Bustype = %d", BusType)); dprintf4(("HalTranslateBusAddress(): BusNumber = %d", BusNumber)); dprintf4(("HalTranslateBusAddress(): PortAddr.lo = 0x%8x", PortAddress.LowPart)); dprintf4(("HalTranslateBusAddress(): PortAddr.hi = 0x%8x", PortAddress.HighPart)); dprintf4(("HalTranslateBusAddress(): MemType = %d", MemType)); HalTranslateBusAddress( BusType, BusNumber, PortAddress, &MemType, &MappedAddress); dprintf4(("HalTranslateBusAddress(): MemType(Out) = %d", MemType)); dprintf4(("HalTranslateBusAddress(): MapAddr(Out) = 0x%16x", MappedAddress)); ResourceList->List[0].PartialResourceList.Count++; Descriptor->Type = CmResourceTypePort; Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; Descriptor->u.Port.Start.LowPart = *FirstIoPort; Descriptor->u.Port.Length = IoPortLength; Descriptor->Flags = MemType == 0 ? CM_RESOURCE_PORT_MEMORY : CM_RESOURCE_PORT_IO; // // Move on to next resource descriptor entry // Descriptor++; } // // Add interrupt information (if any) to the list // if (ARGUMENT_PRESENT(InterruptNumber)) { KAFFINITY Affinity; KIRQL InterruptRequestLevel; ULONG InterruptVector; // // Get the processor affinity and vector // dprintf4(("HalGetInterruptVector(): BusType = %d", BusType)); dprintf4(("HalGetInterruptVector(): BusNumber = %d", BusNumber)); dprintf4(("HalGetInterruptVector(): InterruptLevel = %d", INTERRUPT_LEVEL)); dprintf4(("HalGetInterruptVector(): InterruptNumber = %d", *InterruptNumber)); InterruptVector = HalGetInterruptVector(BusType, BusNumber, INTERRUPT_LEVEL, // InterruptLevel *InterruptNumber, // InterruptVector &InterruptRequestLevel, &Affinity); dprintf4(("HalGetInterruptVector(): InterruptLevel(Out) = %d", InterruptRequestLevel)); dprintf4(("HalGetInterruptVector(): Affinity(Out) = %d", Affinity)); dprintf4(("HalGetInterruptVector(): InterruptVector(ret)= %d", InterruptVector)); ResourceList->List[0].PartialResourceList.Count++; Descriptor->Type = CmResourceTypeInterrupt; Descriptor->ShareDisposition = (UCHAR)(InterruptShareDisposition ? CmResourceShareShared : CmResourceShareDeviceExclusive); Descriptor->Flags = InterruptMode == Latched ? CM_RESOURCE_INTERRUPT_LATCHED : CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; // Descriptor->u.Interrupt.Level = *InterruptNumber; Descriptor->u.Interrupt.Level = INTERRUPT_LEVEL; Descriptor->u.Interrupt.Vector = InterruptVector; Descriptor->u.Interrupt.Affinity = (ULONG)Affinity; // // Move on to next resource descriptor entry // Descriptor++; } // // Add DMA description if any // if (ARGUMENT_PRESENT(DmaChannel)) { ResourceList->List[0].PartialResourceList.Count++; Descriptor->Type = CmResourceTypeDma; Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; Descriptor->u.Dma.Channel = *DmaChannel; Descriptor->u.Dma.Port = 0; // ??? // // Move on to next resource descriptor entry // Descriptor++; } // // Report our resource usage and detect conflicts // switch (DeviceObject->Type) { case IO_TYPE_DEVICE: Status = IoReportResourceUsage(NULL, DeviceObject->DriverObject, NULL, 0, DeviceObject, ResourceList, (PUCHAR)Descriptor - (PUCHAR)ResourceList, FALSE, &ResourceConflict); break; case IO_TYPE_DRIVER: Status = IoReportResourceUsage(NULL, (PDRIVER_OBJECT)DeviceObject, ResourceList, (PUCHAR)Descriptor - (PUCHAR)ResourceList, NULL, NULL, 0, FALSE, &ResourceConflict); break; default: ASSERTMSG("SoundReportResourceUsage - invalid object", FALSE); } if (ResourceConflict) { dprintf1(("Resource conflict reported")); Status = STATUS_DEVICE_CONFIGURATION_ERROR; } return Status; }