NTSTATUS BusDogTraceFifoInit( WDFDRIVER Driver ) { NTSTATUS status = STATUS_SUCCESS; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE (); // // Init our trace fifo and create a lock for it // RtlZeroMemory(&BusDogTraceFifo.TraceItems[0], BUSDOG_FILTER_TRACE_FIFO_LENGTH * sizeof(PBUSDOG_FILTER_TRACE_FIFO_ITEM)); BusDogTraceFifo.WriteIndex = 0; BusDogTraceFifo.ReadIndex = 0; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = Driver; status = WdfSpinLockCreate(&attributes, &BusDogTraceFifoLock); if (!NT_SUCCESS(status)) { BusDogPrint(BUSDOG_DEBUG_ERROR, "WdfWaitLockCreate failed with status 0x%x\n", status); } return status; }
NTSTATUS UfxClientDeviceCreate( _In_ WDFDRIVER Driver, _In_ PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: Worker routine called to create a device and its software resources. Arguments: Driver - WDF driver object DeviceInit - Pointer to an opaque init structure. Memory for this structure will be freed by the framework when the WdfDeviceCreate succeeds. So don't access the structure after that point. Return Value: Appropriate NTSTATUS value --*/ { WDF_OBJECT_ATTRIBUTES DeviceAttributes; WDFDEVICE WdfDevice; NTSTATUS Status; WDF_PNPPOWER_EVENT_CALLBACKS PnpCallbacks; WDF_DMA_ENABLER_CONFIG DmaConfig; PCONTROLLER_CONTEXT ControllerContext; PAGED_CODE(); TraceEntry(); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&DeviceAttributes, CONTROLLER_CONTEXT); // // Do UFX-specific initialization // Status = UfxFdoInit(Driver, DeviceInit, &DeviceAttributes); CHK_NT_MSG(Status, "Failed UFX initialization"); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PnpCallbacks); PnpCallbacks.EvtDevicePrepareHardware = OnEvtDevicePrepareHardware; PnpCallbacks.EvtDeviceReleaseHardware = OnEvtDeviceReleaseHardware; PnpCallbacks.EvtDeviceD0Entry = OnEvtDeviceD0Entry; PnpCallbacks.EvtDeviceD0Exit = OnEvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &PnpCallbacks); Status = WdfDeviceCreate(&DeviceInit, &DeviceAttributes, &WdfDevice); CHK_NT_MSG(Status, "Failed to create wdf device"); ControllerContext = DeviceGetControllerContext(WdfDevice); KeInitializeEvent(&ControllerContext->DetachEvent, NotificationEvent, FALSE); WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&ControllerContext->IdleSettings, IdleCanWakeFromS0); ControllerContext->IdleSettings.IdleTimeoutType = SystemManagedIdleTimeoutWithHint; ControllerContext->IdleSettings.IdleTimeout = IDLE_TIMEOUT; ControllerContext->IdleSettings.DxState = PowerDeviceD3; Status = WdfDeviceAssignS0IdleSettings(WdfDevice, &ControllerContext->IdleSettings); LOG_NT_MSG(Status, "Failed to set S0 Idle Settings"); // // Create and initialize device's default queue // Status = DefaultQueueCreate(WdfDevice); CHK_NT_MSG(Status, "Failed to intialize default queue"); // // Set alignment required by controller // WdfDeviceSetAlignmentRequirement(WdfDevice, UFX_CLIENT_ALIGNMENT); // // Create and Initialize DMA Enabler object for the device. // WDF_DMA_ENABLER_CONFIG_INIT( &DmaConfig, WdfDmaProfileScatterGatherDuplex, MAX_DMA_LENGTH); // // Version 3 is required to perform multiple // simultaneous transfers. // DmaConfig.WdmDmaVersionOverride = 3; Status = WdfDmaEnablerCreate( WdfDevice, &DmaConfig, WDF_NO_OBJECT_ATTRIBUTES, &ControllerContext->DmaEnabler); CHK_NT_MSG(Status, "Failed to create DMA enabler object"); // // Create UFXDEVICE object // Status = UfxDevice_DeviceCreate(WdfDevice); CHK_NT_MSG(Status, "Failed to create UFX Device object"); // // Create DPC Lock // Status = WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &ControllerContext->DpcLock); CHK_NT_MSG(Status, "Failed to create DPC lock"); Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &ControllerContext->InitializeDefaultEndpointLock); CHK_NT_MSG(Status, "Failed to create Ep0 init lock"); End: TraceExit(); return Status; }
NTSTATUS VIOSerialDeviceListCreatePdo( IN WDFCHILDLIST DeviceList, IN PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, IN PWDFDEVICE_INIT ChildInit ) { PVIOSERIAL_PORT pport = NULL; NTSTATUS status = STATUS_SUCCESS; WDFDEVICE hChild = NULL; WDF_OBJECT_ATTRIBUTES attributes; WDF_PNPPOWER_EVENT_CALLBACKS PnpPowerCallbacks; WDF_DEVICE_PNP_CAPABILITIES pnpCaps; WDF_DEVICE_STATE deviceState; WDF_IO_QUEUE_CONFIG queueConfig; PRAWPDO_VIOSERIAL_PORT rawPdo = NULL; WDF_FILEOBJECT_CONFIG fileConfig; DECLARE_CONST_UNICODE_STRING(deviceId, PORT_DEVICE_ID ); DECLARE_CONST_UNICODE_STRING(deviceLocation, L"RedHat VIOSerial Port" ); DECLARE_UNICODE_STRING_SIZE(buffer, DEVICE_DESC_LENGTH); UNREFERENCED_PARAMETER(DeviceList); PAGED_CODE(); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__); pport = CONTAINING_RECORD(IdentificationDescription, VIOSERIAL_PORT, Header ); WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_SERIAL_PORT); WdfDeviceInitSetIoType(ChildInit, WdfDeviceIoDirect); do { WdfDeviceInitSetExclusive(ChildInit, TRUE); status = WdfPdoInitAssignRawDevice(ChildInit, &GUID_DEVCLASS_PORT_DEVICE); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfPdoInitAssignRawDevice failed - 0x%x\n", status); break; } status = WdfDeviceInitAssignSDDLString(ChildInit, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfDeviceInitAssignSDDLString failed - 0x%x\n", status); break; } status = WdfPdoInitAssignDeviceID(ChildInit, &deviceId); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfPdoInitAssignDeviceID failed - 0x%x\n", status); break; } status = WdfPdoInitAddHardwareID(ChildInit, &deviceId); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfPdoInitAddHardwareID failed - 0x%x\n", status); break; } status = RtlUnicodeStringPrintf( &buffer, L"%02u", pport->PortId ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "RtlUnicodeStringPrintf failed - 0x%x\n", status); break; } status = WdfPdoInitAssignInstanceID(ChildInit, &buffer); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfPdoInitAssignInstanceID failed - 0x%x\n", status); break; } status = RtlUnicodeStringPrintf( &buffer, L"vport%up%u", pport->DeviceId, pport->PortId ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "RtlUnicodeStringPrintf failed 0x%x\n", status); break; } status = WdfPdoInitAddDeviceText( ChildInit, &buffer, &deviceLocation, 0x409 ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfPdoInitAddDeviceText failed 0x%x\n", status); break; } WdfPdoInitSetDefaultLocale(ChildInit, 0x409); WDF_FILEOBJECT_CONFIG_INIT( &fileConfig, VIOSerialPortCreate, VIOSerialPortClose, WDF_NO_EVENT_CALLBACK ); WdfDeviceInitSetFileObjectConfig( ChildInit, &fileConfig, WDF_NO_OBJECT_ATTRIBUTES ); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PnpPowerCallbacks); PnpPowerCallbacks.EvtDeviceD0Entry = VIOSerialPortEvtDeviceD0Entry; PnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled = VIOSerialPortEvtDeviceD0ExitPreInterruptsDisabled; PnpPowerCallbacks.EvtDeviceD0Exit = VIOSerialPortEvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(ChildInit, &PnpPowerCallbacks); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, RAWPDO_VIOSERIAL_PORT); attributes.SynchronizationScope = WdfSynchronizationScopeDevice; attributes.ExecutionLevel = WdfExecutionLevelPassive; status = WdfDeviceCreate( &ChildInit, &attributes, &hChild ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfDeviceCreate failed 0x%x\n", status); break; } rawPdo = RawPdoSerialPortGetData(hChild); rawPdo->port = pport; pport->Device = hChild; WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential ); queueConfig.EvtIoDeviceControl = VIOSerialPortDeviceControl; status = WdfIoQueueCreate(hChild, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &pport->IoctlQueue ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfIoQueueCreate failed (IoCtrl Queue): 0x%x\n", status); break; } status = WdfDeviceConfigureRequestDispatching( hChild, pport->IoctlQueue, WdfRequestTypeDeviceControl ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "DeviceConfigureRequestDispatching failed (IoCtrl Queue): 0x%x\n", status); break; } WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential); queueConfig.EvtIoRead = VIOSerialPortRead; queueConfig.EvtIoStop = VIOSerialPortIoStop; status = WdfIoQueueCreate(hChild, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &pport->ReadQueue ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfIoQueueCreate (Read Queue) failed 0x%x\n", status); break; } status = WdfDeviceConfigureRequestDispatching( hChild, pport->ReadQueue, WdfRequestTypeRead ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "DeviceConfigureRequestDispatching failed (Read Queue): 0x%x\n", status); break; } WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential); queueConfig.AllowZeroLengthRequests = WdfFalse; queueConfig.EvtIoWrite = VIOSerialPortWrite; status = WdfIoQueueCreate(hChild, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &pport->WriteQueue); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfIoQueueCreate failed (Write Queue): 0x%x\n", status); break; } status = WdfDeviceConfigureRequestDispatching( hChild, pport->WriteQueue, WdfRequestTypeWrite ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "DeviceConfigureRequestDispatching failed (Write Queue): 0x%x\n", status); break; } WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps); pnpCaps.NoDisplayInUI = WdfTrue; pnpCaps.Removable = WdfTrue; pnpCaps.EjectSupported = WdfTrue; pnpCaps.SurpriseRemovalOK= WdfTrue; pnpCaps.Address = pport->DeviceId; pnpCaps.UINumber = pport->PortId; WdfDeviceSetPnpCapabilities(hChild, &pnpCaps); WDF_DEVICE_STATE_INIT(&deviceState); deviceState.DontDisplayInUI = WdfTrue; WdfDeviceSetDeviceState(hChild, &deviceState); status = WdfDeviceCreateDeviceInterface( hChild, &GUID_VIOSERIAL_PORT, NULL ); if (!NT_SUCCESS (status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfDeviceCreateDeviceInterface failed 0x%x\n", status); break; } WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = hChild; status = WdfSpinLockCreate( &attributes, &pport->InBufLock ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfSpinLockCreate failed 0x%x\n", status); break; } WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = hChild; status = WdfSpinLockCreate( &attributes, &pport->OutVqLock ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfSpinLockCreate failed 0x%x\n", status); break; } } while (0); if (!NT_SUCCESS(status)) { // We can send this before PDO is PRESENT since the device won't send any response. VIOSerialSendCtrlMsg(pport->BusDevice, pport->PortId, VIRTIO_CONSOLE_PORT_READY, 0); } TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s status 0x%x\n", __FUNCTION__, status); return status; }
NTSTATUS VIOSerialEvtDevicePrepareHardware( IN WDFDEVICE Device, IN WDFCMRESLIST ResourcesRaw, IN WDFCMRESLIST ResourcesTranslated) { int nListSize = 0; PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDescriptor; WDF_INTERRUPT_INFO interruptInfo; int i = 0; PPORTS_DEVICE pContext = GetPortsDevice(Device); bool bPortFound = FALSE; NTSTATUS status = STATUS_SUCCESS; UINT nr_ports, max_queues, size_to_allocate; UNREFERENCED_PARAMETER(ResourcesRaw); PAGED_CODE(); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "<--> %s\n", __FUNCTION__); max_queues = 64; // 2 for each of max 32 ports size_to_allocate = VirtIODeviceSizeRequired((USHORT)max_queues); pContext->pIODevice = (VirtIODevice *)ExAllocatePoolWithTag( NonPagedPool, size_to_allocate, VIOSERIAL_DRIVER_MEMORY_TAG); if (NULL == pContext->pIODevice) { return STATUS_INSUFFICIENT_RESOURCES; } nListSize = WdfCmResourceListGetCount(ResourcesTranslated); for (i = 0; i < nListSize; i++) { if(pResDescriptor = WdfCmResourceListGetDescriptor(ResourcesTranslated, i)) { switch(pResDescriptor->Type) { case CmResourceTypePort : pContext->bPortMapped = (pResDescriptor->Flags & CM_RESOURCE_PORT_IO) ? FALSE : TRUE; pContext->PortBasePA = pResDescriptor->u.Port.Start; pContext->uPortLength = pResDescriptor->u.Port.Length; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "IO Port Info [%08I64X-%08I64X]\n", pResDescriptor->u.Port.Start.QuadPart, pResDescriptor->u.Port.Start.QuadPart + pResDescriptor->u.Port.Length); if (pContext->bPortMapped ) { pContext->pPortBase = MmMapIoSpace(pContext->PortBasePA, pContext->uPortLength, MmNonCached); if (!pContext->pPortBase) { TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "%s>>> Failed to map IO port!\n", __FUNCTION__); return STATUS_INSUFFICIENT_RESOURCES; } } else { pContext->pPortBase = (PVOID)(ULONG_PTR)pContext->PortBasePA.QuadPart; } bPortFound = TRUE; break; case CmResourceTypeInterrupt: break; } } } if(!bPortFound) { TraceEvents(TRACE_LEVEL_ERROR, DBG_HW_ACCESS, "%s>>> %s", __FUNCTION__, "IO port wasn't found!\n"); return STATUS_DEVICE_CONFIGURATION_ERROR; } WDF_INTERRUPT_INFO_INIT(&interruptInfo); WdfInterruptGetInfo(pContext->WdfInterrupt, &interruptInfo); VirtIODeviceInitialize(pContext->pIODevice, (ULONG_PTR)pContext->pPortBase, size_to_allocate); VirtIODeviceSetMSIXUsed(pContext->pIODevice, interruptInfo.MessageSignaled); VirtIODeviceReset(pContext->pIODevice); VirtIODeviceAddStatus(pContext->pIODevice, VIRTIO_CONFIG_S_ACKNOWLEDGE); pContext->consoleConfig.max_nr_ports = 1; if(pContext->isHostMultiport = VirtIODeviceGetHostFeature(pContext->pIODevice, VIRTIO_CONSOLE_F_MULTIPORT)) { TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "We have multiport host\n"); VirtIODeviceEnableGuestFeature(pContext->pIODevice, VIRTIO_CONSOLE_F_MULTIPORT); VirtIODeviceGet(pContext->pIODevice, FIELD_OFFSET(CONSOLE_CONFIG, max_nr_ports), &pContext->consoleConfig.max_nr_ports, sizeof(pContext->consoleConfig.max_nr_ports)); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "VirtIOConsoleConfig->max_nr_ports %d\n", pContext->consoleConfig.max_nr_ports); if (pContext->consoleConfig.max_nr_ports > pContext->pIODevice->maxQueues / 2) { pContext->consoleConfig.max_nr_ports = pContext->pIODevice->maxQueues / 2; TraceEvents(TRACE_LEVEL_WARNING, DBG_PNP, "VirtIOConsoleConfig->max_nr_ports limited to %d\n", pContext->consoleConfig.max_nr_ports); } } if(pContext->isHostMultiport) { WDF_OBJECT_ATTRIBUTES attributes; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = Device; status = WdfSpinLockCreate( &attributes, &pContext->CVqLock ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "WdfSpinLockCreate failed 0x%x\n", status); return status; } } else { //FIXME // VIOSerialAddPort(Device, 0); } nr_ports = pContext->consoleConfig.max_nr_ports; pContext->in_vqs = (struct virtqueue**)ExAllocatePoolWithTag( NonPagedPool, nr_ports * sizeof(struct virtqueue*), VIOSERIAL_DRIVER_MEMORY_TAG); if(pContext->in_vqs == NULL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,"ExAllocatePoolWithTag failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } memset(pContext->in_vqs, 0, nr_ports * sizeof(struct virtqueue*)); pContext->out_vqs = (struct virtqueue**)ExAllocatePoolWithTag( NonPagedPool, nr_ports * sizeof(struct virtqueue*), VIOSERIAL_DRIVER_MEMORY_TAG ); if(pContext->out_vqs == NULL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT, "ExAllocatePoolWithTag failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } memset(pContext->out_vqs, 0, nr_ports * sizeof(struct virtqueue*)); pContext->DeviceOK = TRUE; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "<-- %s\n", __FUNCTION__); return status; }
NTSTATUS kmdf1394_EvtDeviceAdd ( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit) /*++ Routine Description: EvtDeviceAdd is called by the framework in response to AddDevice call from the PnP manager. Arguments: Driver - Handle to a framework driver object created in DriverEntry DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure. Return Value: NTSTATUS --*/ { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES fdoAttributes,lockAttributes; WDFDEVICE device; WDF_DEVICE_PNP_CAPABILITIES pnpCaps; WDF_IO_QUEUE_CONFIG ioQueueConfig; UNREFERENCED_PARAMETER (Driver); PAGED_CODE(); Enter(); // // Zero out the PnpPowerCallbacks structure. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); // // Set Callbacks for any of the functions we are interested in. // If no callback is set, Framework will take the default action // by itself. // // These two callbacks set up and tear down hardware state, // specifically that which only has to be done once. // pnpPowerCallbacks.EvtDevicePrepareHardware = kmdf1394_EvtPrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = kmdf1394_EvtReleaseHardware; pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup = \ kmdf1394_EvtDeviceSelfManagedIoCleanup; pnpPowerCallbacks.EvtDeviceD0Entry = kmdf1394_EvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = kmdf1394_EvtDeviceD0Exit; // // Register the PnP and power callbacks. Power policy related callbacks // will be registered// later in SotwareInit. // WdfDeviceInitSetPnpPowerEventCallbacks (DeviceInit, &pnpPowerCallbacks); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceInitSetPnpPowerEventCallbacks failed %!STATUS!\n", ntStatus); return ntStatus; } // // We'll allow multiple handles to be opened to this device driver // so we'll set exclusivity to FALSE. // WdfDeviceInitSetExclusive (DeviceInit, FALSE); // // Specify the size and type of device context. // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE (&fdoAttributes, DEVICE_EXTENSION); ntStatus = WdfDeviceCreate (&DeviceInit, &fdoAttributes, &device); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceInitialize failed %!STATUS!\n", ntStatus); return ntStatus; } deviceExtension = GetDeviceContext (device); deviceExtension->WdfDevice = device; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n", WdfDeviceWdmGetPhysicalDevice (device), WdfDeviceWdmGetDeviceObject (device), WdfDeviceWdmGetAttachedDevice(device), deviceExtension); // // Tell the Framework that this device will need an interface so that // application can interact with it. // ntStatus = WdfDeviceCreateDeviceInterface ( device, (LPGUID) &GUID_KMDF_VDEV, NULL); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceCreateDeviceInterface failed %!STATUS!\n", ntStatus); return ntStatus; } // // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so // that you don't get the popup in usermode (on Win2K) when you surprise // remove the device. // WDF_DEVICE_PNP_CAPABILITIES_INIT (&pnpCaps); pnpCaps.SurpriseRemovalOK = WdfTrue; WdfDeviceSetPnpCapabilities (device, &pnpCaps); // // save the device object we created as our physical device object // deviceExtension->PhysicalDeviceObject = \ WdfDeviceWdmGetPhysicalDevice (device); if (NULL == deviceExtension->PhysicalDeviceObject) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceWdmGetPhysicalDevice: NULL DeviceObject\n"); return STATUS_UNSUCCESSFUL; } // // This is our default IoTarget representing the deviceobject // we are attached to. // deviceExtension->StackIoTarget = WdfDeviceGetIoTarget(device); deviceExtension->StackDeviceObject = WdfDeviceWdmGetAttachedDevice(device); if (NULL == deviceExtension->StackDeviceObject) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceWdmGetAttachedDevice: NULL DeviceObject\n"); return STATUS_UNSUCCESSFUL; } // // Create a automanaged queue for dispatching ioctl requests. // All other requests are automatically failed by the framework. // By creating an automanaged queue we don't have to worry about // PNP/Power synchronization. // A default queue gets all the requests that are not // configure-fowarded using WdfDeviceConfigureRequestDispatching. // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE ( &ioQueueConfig, WdfIoQueueDispatchParallel); ioQueueConfig.EvtIoDeviceControl = kmdf1394_EvtIoDeviceControl; __analysis_assume(ioQueueConfig.EvtIoStop != 0); ntStatus = WdfIoQueueCreate ( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->IoctlQueue); __analysis_assume(ioQueueConfig.EvtIoStop == 0); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfIoQueueCreate failed %!STATUS!\n", ntStatus); return ntStatus; } // // Create an additional queue to hold bus reset requests. // WDF_IO_QUEUE_CONFIG_INIT (&ioQueueConfig, WdfIoQueueDispatchManual); __analysis_assume(ioQueueConfig.EvtIoStop != 0); ntStatus = WdfIoQueueCreate ( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->BusResetRequestsQueue); __analysis_assume(ioQueueConfig.EvtIoStop == 0); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "Error Creating Reset Request Queue %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate (&lockAttributes,&deviceExtension->CromSpinLock); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate CromSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate ( &lockAttributes, &deviceExtension->AsyncSpinLock); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate AsyncSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate ( &lockAttributes, &deviceExtension->IsochSpinLock ); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate IsochSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate ( &lockAttributes, &deviceExtension->IsochResourceSpinLock); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate IsochResourceSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } InitializeListHead (&deviceExtension->CromData); InitializeListHead (&deviceExtension->AsyncAddressData); InitializeListHead (&deviceExtension->IsochDetachData); InitializeListHead (&deviceExtension->IsochResourceData); ExitS(ntStatus); return(ntStatus); } // kmdf1394_PnpAddDevice
NTSTATUS BthEchoConnectionObjectInit( _In_ WDFOBJECT ConnectionObject, _In_ PBTHECHOSAMPLE_DEVICE_CONTEXT_HEADER DevCtxHdr ) /*++ Description: This routine initializes connection object. It is invoked by BthEchoConnectionObjectCreate. Arguments: ConnectionObject - Object to initialize DevCtxHdr - Device context header Return Value: NTSTATUS Status code. --*/ { NTSTATUS status; WDF_OBJECT_ATTRIBUTES attributes; PBTHECHO_CONNECTION connection = GetConnectionObjectContext(ConnectionObject); connection->DevCtxHdr = DevCtxHdr; connection->ConnectionState = ConnectionStateInitialized; // // Initialize spinlock // WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = ConnectionObject; status = WdfSpinLockCreate( &attributes, &connection->ConnectionLock ); if (!NT_SUCCESS(status)) { goto exit; } // // Create connect/disconnect request // status = WdfRequestCreate( &attributes, DevCtxHdr->IoTarget, &connection->ConnectDisconnectRequest ); if (!NT_SUCCESS(status)) { return status; } // // Initialize event // KeInitializeEvent(&connection->DisconnectEvent, NotificationEvent, TRUE); // // Initalize list entry // InitializeListHead(&connection->ConnectionListEntry); connection->ConnectionState = ConnectionStateInitialized; exit: return status; }
NTSTATUS BalloonDeviceAdd( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit) { NTSTATUS status = STATUS_SUCCESS; WDFDEVICE device; PDEVICE_CONTEXT devCtx = NULL; WDF_INTERRUPT_CONFIG interruptConfig; WDF_OBJECT_ATTRIBUTES attributes; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; UNREFERENCED_PARAMETER(Driver); PAGED_CODE(); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = BalloonEvtDevicePrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = BalloonEvtDeviceReleaseHardware; pnpPowerCallbacks.EvtDeviceD0Entry = BalloonEvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = BalloonEvtDeviceD0Exit; pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled = BalloonEvtDeviceD0ExitPreInterruptsDisabled; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); attributes.EvtCleanupCallback = BalloonEvtDeviceContextCleanup; status = WdfDeviceCreate(&DeviceInit, &attributes, &device); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfDeviceCreate failed with status 0x%08x\n", status); return status; } devCtx = GetDeviceContext(device); WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, BalloonInterruptIsr, BalloonInterruptDpc); interruptConfig.EvtInterruptEnable = BalloonInterruptEnable; interruptConfig.EvtInterruptDisable = BalloonInterruptDisable; status = WdfInterruptCreate(device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &devCtx->WdfInterrupt); if (!NT_SUCCESS (status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfInterruptCreate failed: 0x%08x\n", status); return status; } status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_BALLOON, NULL); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfDeviceCreateDeviceInterface failed with status 0x%08x\n", status); return status; } devCtx->bShutDown = FALSE; devCtx->num_pages = 0; devCtx->PageListHead.Next = NULL; ExInitializeNPagedLookasideList( &devCtx->LookAsideList, NULL, NULL, 0, sizeof(PAGE_LIST_ENTRY), BALLOON_MGMT_POOL_TAG, 0 ); devCtx->bListInitialized = TRUE; devCtx->pfns_table = (PPFN_NUMBER) ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE, BALLOON_MGMT_POOL_TAG ); if(devCtx->pfns_table == NULL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,"ExAllocatePoolWithTag failed\n"); status = STATUS_INSUFFICIENT_RESOURCES; return status; } devCtx->MemStats = (PBALLOON_STAT) ExAllocatePoolWithTag( NonPagedPool, sizeof (BALLOON_STAT) * VIRTIO_BALLOON_S_NR, BALLOON_MGMT_POOL_TAG ); if(devCtx->MemStats == NULL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,"ExAllocatePoolWithTag failed\n"); status = STATUS_INSUFFICIENT_RESOURCES; return status; } RtlFillMemory (devCtx->MemStats, sizeof (BALLOON_STAT) * VIRTIO_BALLOON_S_NR, -1); KeInitializeEvent(&devCtx->HostAckEvent, SynchronizationEvent, FALSE ); WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfSpinLockCreate( &attributes, &devCtx->StatQueueLock ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfSpinLockCreate failed 0x%x\n", status); return status; } status = WdfSpinLockCreate( &attributes, &devCtx->InfDefQueueLock ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfSpinLockCreate failed 0x%x\n", status); return status; } status = StatInitializeWorkItem(device); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "StatInitializeWorkItem failed with status 0x%08x\n", status); return status; } KeInitializeEvent(&devCtx->WakeUpThread, SynchronizationEvent, FALSE ); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__); return status; }
_Use_decl_annotations_ NTSTATUS OnDeviceAdd( WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: OnDeviceAdd is called by the framework in response to AddDevice call from the PnP manager. We create and initialize a device object to represent a new instance of the device. Arguments: Driver - Handle to a framework driver object created in DriverEntry DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure Return Value: Status --*/ { PAGED_CODE(); UNREFERENCED_PARAMETER(Driver); WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES objectAttributes; PDEVICE_CONTEXT deviceContext; WDFDEVICE device; NTSTATUS status; DECLARE_UNICODE_STRING_SIZE(symbolicLinkName, 128); // // Set PnP callbacks. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = PrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = ReleaseHardware; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); // // PWM only allows exclusive access. // WdfDeviceInitSetExclusive(DeviceInit, TRUE); // // Create device object. // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttributes, DEVICE_CONTEXT); objectAttributes.EvtCleanupCallback = OnDeviceContextCleanup; status = WdfDeviceCreate(&DeviceInit, &objectAttributes, &device); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create device (0x%08x)", status); goto Exit; } deviceContext = GetContext(device); // // Prepare config spin lock. // WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); status = WdfSpinLockCreate(&objectAttributes, &deviceContext->pwmLock); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create config spin lock (0x%08x)", status); goto Exit; } // // Prepare notification list spin lock. // WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); status = WdfSpinLockCreate(&objectAttributes, &deviceContext->notificationListLock); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create notification list spin lock (0x%08x)", status); goto Exit; } // // Prepare interrupt object. // WDF_INTERRUPT_CONFIG interruptConfig; WDF_INTERRUPT_CONFIG_INIT( &interruptConfig, DmaIsr, DmaDpc ); status = WdfInterruptCreate( device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->interruptObj ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create interrupt object (0x%08x)", status); goto Exit; } // // Create queues to handle IO. // WDF_IO_QUEUE_CONFIG queueConfig; WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &queueConfig, WdfIoQueueDispatchParallel); queueConfig.EvtIoDeviceControl = OnIoDeviceControl; queueConfig.PowerManaged = WdfFalse; status = WdfIoQueueCreate( device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceContext->queueObj ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create IO queue (0x%08x)", status); goto Exit; } // // Create a symbolic link. // status = RtlUnicodeStringInit(&symbolicLinkName, BCM_PWM_SYMBOLIC_NAME); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not process the symbolic name (0x%08x)", status); goto Exit; } status = WdfDeviceCreateSymbolicLink( device, &symbolicLinkName ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_INIT, "Can not create a symbolic name (0x%08x)", status); goto Exit; } Exit: return status; }
NTSTATUS t1394_EvtDeviceAdd( /*IN*/WDFDRIVER Driver, /*IN*/PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: EvtDeviceAdd is called by the framework in response to AddDevice call from the PnP manager. Arguments: Driver - Handle to a framework driver object created in DriverEntry DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure. Return Value: NTSTATUS --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension; PNODE_DEVICE_EXTENSION pNodeExt; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES fdoAttributes,lockAttributes; WDFDEVICE device; WDF_DEVICE_PNP_CAPABILITIES pnpCaps; WDF_IO_QUEUE_CONFIG ioQueueConfig; WDF_IO_TARGET_OPEN_PARAMS openParams; //UNREFERENCED_PARAMETER(Driver); //ENTER("t1394_PnpAddDevice"); // // Zero out the PnpPowerCallbacks structure. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); // // Set Callbacks for any of the functions we are interested in. // If no callback is set, Framework will take the default action // by itself. // // These two callbacks set up and tear down hardware state, // specifically that which only has to be done once. // pnpPowerCallbacks.EvtDevicePrepareHardware = t1394_EvtPrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = t1394_EvtReleaseHardware; pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup = t1394_EvtDeviceSelfManagedIoCleanup; pnpPowerCallbacks.EvtDeviceD0Entry = t1394_EvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = t1394_EvtDeviceD0Exit; // // Register the PnP and power callbacks. Power policy related callbacks // will be registered// later in SotwareInit. // WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); if ( !NT_SUCCESS(status)) { //TRACE(TL_ERROR, ("WdfDeviceInitSetPnpPowerEventCallbacks failed %x\n", // status)); return status; } WdfDeviceInitSetExclusive(DeviceInit, FALSE); // // Specify the size and type of device context. // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, DEVICE_EXTENSION); status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device); if ( !NT_SUCCESS(status)) { //TRACE(TL_ERROR, ("WdfDeviceInitialize failed %x\n", status)); return status; } deviceExtension = GetDeviceContext (device); deviceExtension->WdfDevice = device; //TRACE(TL_TRACE, ("PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n", // WdfDeviceWdmGetPhysicalDevice (device), // WdfDeviceWdmGetDeviceObject (device), // WdfDeviceWdmGetAttachedDevice(device), // deviceExtension)); // // Tell the Framework that this device will need an interface so that // application can interact with it. // status = WdfDeviceCreateDeviceInterface( device, #if defined(_1394VDEV_DRIVER_) (LPGUID) &GUID_1394VDEV, #else (LPGUID) &GUID_1394DIAG, #endif NULL ); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfDeviceCreateDeviceInterface failed %x\n", status)); return status; } // // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so // that you don't get the popup in usermode (on Win2K) when you surprise // remove the device. // WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps); pnpCaps.SurpriseRemovalOK = WdfTrue; WdfDeviceSetPnpCapabilities(device, &pnpCaps); // save the device object we created as our physical device object deviceExtension->PhysicalDeviceObject = WdfDeviceWdmGetPhysicalDevice (device); if (deviceExtension->PhysicalDeviceObject == NULL) { //TRACE(TL_ERROR, ("WdfDeviceWdmGetPhysicalDevice: NULL DeviceObject\n")); return STATUS_UNSUCCESSFUL; } // // This is our default IoTarget representing the deviceobject // we are attached to. // deviceExtension->StackIoTarget = WdfDeviceGetIoTarget(device); deviceExtension->StackDeviceObject = WdfDeviceWdmGetAttachedDevice(device); if (deviceExtension->StackDeviceObject == NULL) { //TRACE(TL_ERROR, ("WdfDeviceWdmGetAttachedDevice: NULL DeviceObject\n")); return STATUS_UNSUCCESSFUL; } // Patch: this code is not in DDK 7600.16385.1 { // // Get the port device object from the passed in PhysicalDeviceObject // created by the 1394 stack for us. // Note: we can't use the top of the stack and get its device extension // in case there is a filter driver between us and our PDO. // //pNodeExt = WdfDeviceWdmGetPhysicalDevice(device)->DeviceExtension; //deviceExtension->PortDeviceObject = pNodeExt->PortDeviceObject; // Patch: this code is not in DDK 7600.16385.1 } //TRACE(TL_TRACE, ("PortDeviceObject = 0x%x\n", // deviceExtension->PortDeviceObject)); // // Create a automanaged queue for dispatching ioctl requests. // All other requests are automatically failed by the framework. // By creating an automanaged queue we don't have to worry about // PNP/Power synchronization. // A default queue gets all the requests that are not // configure-fowarded using WdfDeviceConfigureRequestDispatching. // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &ioQueueConfig, WdfIoQueueDispatchParallel ); ioQueueConfig.EvtIoDeviceControl = t1394_EvtIoDeviceControl; status = WdfIoQueueCreate( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->IoctlQueue // queue handle ); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfIoQueueCreate failed 0x%x\n", status)); return status; } // // Create an additional queue to hold bus reset requests. // WDF_IO_QUEUE_CONFIG_INIT( &ioQueueConfig, WdfIoQueueDispatchManual ); status = WdfIoQueueCreate ( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->BusResetRequestsQueue ); if(!NT_SUCCESS (status)){ //TRACE(TL_ERROR, ("Error Creating Reset Request Queue 0x%x\n", // status)); return status; } // // Create another IoTarget representing PortDeviceObject so that // we can send async requests in rawmode directly to the port device. // WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(&openParams, pNodeExt->PortDeviceObject); status = WdfIoTargetCreate(device, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->PortDeviceIoTarget); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfIoTargetCreate failed 0x%x\n", status)); return status; } status = WdfIoTargetOpen(deviceExtension->PortDeviceIoTarget, &openParams); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfIoTargetCreate failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; // initialize the spinlock/list to store the bus reset irps... status = WdfSpinLockCreate(&lockAttributes,&deviceExtension->CromSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate CromSpinLock " // "failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfSpinLockCreate(&lockAttributes, &deviceExtension->AsyncSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate AsyncSpinLock " // "failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfSpinLockCreate(&lockAttributes, &deviceExtension->IsochSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate IsochSpinLock " // "failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfSpinLockCreate(&lockAttributes, &deviceExtension->IsochResourceSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate IsochResourceSpinLock " // "failed 0x%x\n", status)); return status; } InitializeListHead(&deviceExtension->CromData); InitializeListHead(&deviceExtension->AsyncAddressData); InitializeListHead(&deviceExtension->IsochDetachData); InitializeListHead(&deviceExtension->IsochResourceData); //EXIT("t1394_PnpAddDevice", status); return(status); } // t1394_PnpAddDevice
NTSTATUS VioCryptDeviceAdd(IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit) { NTSTATUS status; WDFDEVICE device; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES attributes; WDFQUEUE queue; WDF_IO_QUEUE_CONFIG queueConfig; WDF_INTERRUPT_CONFIG interruptConfig; PDEVICE_CONTEXT context; UNREFERENCED_PARAMETER(Driver); Trace(TRACE_LEVEL_VERBOSE, "[%s] -->", __FUNCTION__); PAGED_CODE(); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = VioCryptDevicePrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = VioCryptDeviceReleaseHardware; pnpPowerCallbacks.EvtDeviceD0Entry = VioCryptDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = VioCryptDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); attributes.EvtCleanupCallback = VioCryptDeviceContextCleanup; status = WdfDeviceCreate(&DeviceInit, &attributes, &device); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "[%s] WdfDeviceCreate failed: status %X", __FUNCTION__, status); return status; } context = GetDeviceContext(device); RtlZeroMemory(context, sizeof(*context)); InitializeListHead(&context->PendingBuffers); WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, VioCryptInterruptIsr, VioCryptInterruptDpc); interruptConfig.EvtInterruptEnable = VioCryptInterruptEnable; interruptConfig.EvtInterruptDisable = VioCryptInterruptDisable; status = WdfInterruptCreate(device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &context->WdfInterrupt); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "[%s] WdfInterruptCreate failed: status %X", __FUNCTION__, status); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfSpinLockCreate(&attributes, &context->VirtQueueLock); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "[%s] WdfSpinLockCreate failed: status %X", __FUNCTION__, status); return status; } status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_VIOCRYPT, NULL); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "[%s] WdfDeviceCreateDeviceInterface failed: status %X", __FUNCTION__, status); return status; } WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential); queueConfig.EvtIoDeviceControl = VioCryptIoControl; queueConfig.EvtIoStop = VioCryptIoStop; queueConfig.AllowZeroLengthRequests = FALSE; status = WdfIoQueueCreate(device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "[%s] WdfIoQueueCreate failed: status %X", __FUNCTION__, status); return status; } status = WdfDeviceConfigureRequestDispatching(device, queue, WdfRequestTypeDeviceControl); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "[%s] WdfDeviceConfigureRequestDispatching failed: status %X", __FUNCTION__, status); return status; } Trace(TRACE_LEVEL_VERBOSE, "[%s] <--", __FUNCTION__); return status; }