/*++ Copyright (c) 1995 Microsoft Corporation Module Name: devres.c Abstract: This module contains the high level device resources support routines. Author: Shie-Lin Tzong (shielint) Apr-25-1995 Adapted from Pci bus extender. Environment: Kernel mode only. Revision History: --*/ #include "busp.h" #pragma alloc_text(PAGE,MbCtlQueryDeviceId) #pragma alloc_text(PAGE,MbCtlQueryDeviceUniqueId) #pragma alloc_text(PAGE,MbCtlQueryDeviceResources) #pragma alloc_text(PAGE,MbCtlQueryDeviceResourceRequirements) #pragma alloc_text(PAGE,MbCtlSetDeviceResources) VOID MbCtlQueryDeviceUniqueId ( PDEVICE_DATA DeviceData, PHAL_DEVICE_CONTROL_CONTEXT Context ) /*++ Routine Description: This function returns the unique id for the particular device. Arguments: DeviceData - Device data information for the specificied device. Context - Device control context of the request. Return Value: The device control is completed --*/ { NTSTATUS status = STATUS_SUCCESS; PWCHAR deviceId; ULONG idNumber; PMB_BUS_EXTENSION busExtension; PAGED_CODE(); // // Set up device's unique id. // deviceId = (PWCHAR) Context->DeviceControl.Buffer; // // If the device is a docking station, we return its docking station // serial number. Else its device id/slot number is returned as the // unique id. // if (DeviceData->Flags & DEVICE_FLAGS_DOCKING_STATION) { busExtension = (PMB_BUS_EXTENSION)Context->Handler->BusData; idNumber = busExtension->DockingStationSerialNumber; } else { idNumber = DeviceDataSlot(DeviceData); } swprintf (deviceId, L"%04x", idNumber); #if DBG { ANSI_STRING ansiString; UNICODE_STRING unicodeString; RtlInitUnicodeString(&unicodeString, (PWCHAR)Context->DeviceControl.Buffer); RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); DbgPrint("Bus %x Slot %x Unique Id = %s\n", Context->Handler->BusNumber, DeviceDataSlot(DeviceData), ansiString.Buffer ); RtlFreeAnsiString(&ansiString); } #endif MbpCompleteDeviceControl (STATUS_SUCCESS, Context, DeviceData); } VOID MbCtlQueryDeviceId ( PDEVICE_DATA DeviceData, PHAL_DEVICE_CONTROL_CONTEXT Context ) /*++ Routine Description: This function returns the device id for the particular device. Arguments: DeviceData - Device data information for the specificied device. Context - Device control context of the request. Return Value: The device control is completed --*/ { NTSTATUS status; PWCHAR deviceId; ULONG idIndex; PAGED_CODE(); // // Determine which device ID the caller wants back // idIndex = *((PULONG) Context->DeviceControl.Buffer); // // Call worker routine to get the desired Id. // deviceId = (PWCHAR) Context->DeviceControl.Buffer; status = MbpGetCompatibleDeviceId(DeviceData->BusData, idIndex, (PWCHAR) deviceId); #if DBG if (NT_SUCCESS(status)) { ANSI_STRING ansiString; UNICODE_STRING unicodeString; RtlInitUnicodeString(&unicodeString, deviceId); RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE); DbgPrint("Bus %x Slot %x IdIndex %x Compatible Id = %s\n", Context->Handler->BusNumber, DeviceDataSlot(DeviceData), idIndex, ansiString.Buffer ); RtlFreeAnsiString(&ansiString); } #endif MbpCompleteDeviceControl (status, Context, DeviceData); } VOID MbCtlQueryDeviceResources ( PDEVICE_DATA DeviceData, PHAL_DEVICE_CONTROL_CONTEXT Context ) /*++ Routine Description: This function completes the QUERY_DEVICE_RESOURCES DeviceControl which returns the bus resources being used by the specified device Arguments: DeviceData - Device data information for the specificied slot Context - Device control context of the request Return Value: The device control is completed --*/ { ULONG length; PCM_RESOURCE_LIST cmResources; NTSTATUS status; PAGED_CODE(); status = MbpGetSlotResources(Context->RootHandler->BusNumber, DeviceData->BusData, &cmResources, &length); // // Return results // if (NT_SUCCESS(status)) { if (length == 0) { // // If resource info is not available, return an empty CM_RESOURCE_LIST // cmResources = (PCM_RESOURCE_LIST) ExAllocatePoolWithTag ( PagedPool, sizeof(CM_RESOURCE_LIST), 'bPnP'); if (!cmResources) { status = STATUS_INSUFFICIENT_RESOURCES; goto exitLocal; } else { cmResources->Count = 0; cmResources->List[0].InterfaceType = Context->RootHandler->InterfaceType; cmResources->List[0].BusNumber = Context->RootHandler->BusNumber; cmResources->List[0].PartialResourceList.Version = 0; cmResources->List[0].PartialResourceList.Revision = 0; cmResources->List[0].PartialResourceList.Count = 0; length = sizeof(CM_RESOURCE_LIST); } } if (length > *Context->DeviceControl.BufferLength) { status = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory (Context->DeviceControl.Buffer, cmResources, length); } *Context->DeviceControl.BufferLength = length; #if DBG if (NT_SUCCESS(status)) { MbpDumpCmResourceList(cmResources, DeviceDataSlot(DeviceData)); } #endif ExFreePool(cmResources); } exitLocal: MbpCompleteDeviceControl (status, Context, DeviceData); } VOID MbCtlQueryDeviceResourceRequirements ( PDEVICE_DATA DeviceData, PHAL_DEVICE_CONTROL_CONTEXT Context ) /*++ Routine Description: This function completes the QUERY_DEVICE_RESOURCE_REQUIREMENTS DeviceControl which returns the possible bus resources that this device may be satisfied with. Arguments: DeviceData - Device data information for the specificied slot Context - Device control context of the request Return Value: The device control is completed --*/ { ULONG length; PIO_RESOURCE_REQUIREMENTS_LIST ioResources; NTSTATUS status; PAGED_CODE(); status = MbpGetSlotResourceRequirements(Context->RootHandler->BusNumber, DeviceData->BusData, &ioResources, &length); // // Return results // if (NT_SUCCESS(status)) { if (length == 0) { // // If resource info is not available, return an empty CM_RESOURCE_LIST // ioResources = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePoolWithTag ( PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST), 'bPnP'); if (!ioResources) { status = STATUS_INSUFFICIENT_RESOURCES; goto exitLocal; } else { ioResources->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); ioResources->InterfaceType = Context->RootHandler->InterfaceType; ioResources->BusNumber = Context->RootHandler->BusNumber; ioResources->SlotNumber = DeviceDataSlot(DeviceData); ioResources->Reserved[0] = 0; ioResources->Reserved[1] = 0; ioResources->Reserved[2] = 0; ioResources->AlternativeLists = 0; ioResources->List[0].Version = 1; ioResources->List[0].Revision = 1; ioResources->List[0].Count = 0; length = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); } } if (length > *Context->DeviceControl.BufferLength) { status = STATUS_BUFFER_TOO_SMALL; } else { RtlCopyMemory (Context->DeviceControl.Buffer, ioResources, length); } *Context->DeviceControl.BufferLength = length; #if DBG if (NT_SUCCESS(status)) { MbpDumpIoResourceList(ioResources); } #endif ExFreePool(ioResources); } exitLocal: MbpCompleteDeviceControl (status, Context, DeviceData); } VOID MbCtlSetDeviceResources ( PDEVICE_DATA DeviceData, PHAL_DEVICE_CONTROL_CONTEXT Context ) /*++ Routine Description: This function completes the SET_DEVICE_RESOURCES DeviceControl which configures the device to the specified device setttings Arguments: DeviceData - Device data information for the specificied slot Context - Device control context of the request Return Value: The device control is completed --*/ { NTSTATUS status; PAGED_CODE(); // // Get the resource requirements list for the device // status = MbpSetSlotResources ( &DeviceData->BusData, (PCM_RESOURCE_LIST) Context->DeviceControl.Buffer, *Context->DeviceControl.BufferLength ); MbpCompleteDeviceControl (status, Context, DeviceData); }