static irqreturn_t ipq_mi2s_irq(int intrsrc, void *data) { int dma_ch; uint32_t ret = IRQ_NONE; uint32_t has_xrun, pending; struct snd_pcm_substream *substream = data; struct snd_pcm_runtime *runtime = substream->runtime; struct ipq_lpass_runtime_data_t *prtd = (struct ipq_lpass_runtime_data_t *)runtime->private_data; if (prtd) dma_ch = prtd->lpaif_info.dma_ch; else return IRQ_NONE; pending = (intrsrc & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch))); has_xrun = (pending & UNDER_CH(dma_ch)); if (unlikely(has_xrun) && substream->runtime && snd_pcm_running(substream)) { pr_debug("%s %d: xrun warning\n", __func__, __LINE__); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); pending &= ~UNDER_CH(dma_ch); ret = IRQ_HANDLED; } if (pending & PER_CH(dma_ch)) { if (++prtd->pcm_stream_info.period_index >= runtime->periods) prtd->pcm_stream_info.period_index = 0; snd_pcm_period_elapsed(substream); pending &= ~PER_CH(dma_ch); ret = IRQ_HANDLED; } if (pending & UNDER_CH(dma_ch)) { snd_pcm_period_elapsed(substream); pr_debug("%s %d: xrun warning\n", __func__, __LINE__); ret = IRQ_HANDLED; } if (pending & ERR_CH(dma_ch)) { pr_debug("%s %d: Bus access warning\n", __func__, __LINE__); ret = IRQ_HANDLED; } return ret; }
NTSTATUS AllocW32Process(IN PEPROCESS Process, OUT PPROCESSINFO* W32Process) { PPROCESSINFO ppiCurrent; TRACE_CH(UserProcess, "In AllocW32Process(0x%p)\n", Process); /* Check that we were not called with an already existing Win32 process info */ ppiCurrent = PsGetProcessWin32Process(Process); if (ppiCurrent) return STATUS_SUCCESS; /* Allocate a new Win32 process info */ ppiCurrent = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ppiCurrent), USERTAG_PROCESSINFO); if (ppiCurrent == NULL) { ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n", HandleToUlong(Process->UniqueProcessId)); return STATUS_NO_MEMORY; } TRACE_CH(UserProcess, "Allocated ppi 0x%p for PID:0x%lx\n", ppiCurrent, HandleToUlong(Process->UniqueProcessId)); RtlZeroMemory(ppiCurrent, sizeof(*ppiCurrent)); PsSetProcessWin32Process(Process, ppiCurrent, NULL); IntReferenceProcessInfo(ppiCurrent); *W32Process = ppiCurrent; return STATUS_SUCCESS; }
static irqreturn_t lpa_if_irq(int intrsrc, void *data) { struct lpa_if *lpa_if = data; int dma_ch = 0; unsigned int pending; if (lpa_if) dma_ch = lpa_if->dma_ch; else { pr_err("invalid lpa_if\n"); return IRQ_NONE; } pending = (intrsrc & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch))); if (pending & UNDER_CH(dma_ch)) pr_err("under run\n"); if (pending & ERR_CH(dma_ch)) pr_err("DMA %x Master Error\n", dma_ch); if (pending & PER_CH(dma_ch)) { lpa_if->audio_buf[lpa_if->dma_buf].used = 0; pr_debug("dma_buf %d used %d\n", lpa_if->dma_buf, lpa_if->audio_buf[lpa_if->dma_buf].used); lpa_if->dma_buf++; lpa_if->dma_buf = lpa_if->dma_buf % lpa_if->cfg.buffer_count; if (lpa_if->dma_buf == lpa_if->cpu_buf) pr_err("Err:both dma_buf and cpu_buf are on same index\n"); wake_up(&lpa_if->wait); } return IRQ_HANDLED; }
NTSTATUS APIENTRY Win32kProcessCallback(struct _EPROCESS *Process, BOOLEAN Create) { PPROCESSINFO ppiCurrent, *pppi; NTSTATUS Status; ASSERT(Process->Peb); UserEnterExclusive(); if (Create) { SIZE_T ViewSize = 0; LARGE_INTEGER Offset; PVOID UserBase = NULL; PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters; /* We might be called with an already allocated win32 process */ ppiCurrent = PsGetProcessWin32Process(Process); if (ppiCurrent != NULL) { /* There is no more to do for us (this is a success code!) */ Status = STATUS_ALREADY_WIN32; goto Leave; } /* Allocate a new win32 process */ ppiCurrent = ExAllocatePoolWithTag(NonPagedPool, sizeof(PROCESSINFO), USERTAG_PROCESSINFO); if (ppiCurrent == NULL) { ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n", HandleToUlong(Process->UniqueProcessId)); Status = STATUS_NO_MEMORY; goto Leave; } RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO)); PsSetProcessWin32Process(Process, ppiCurrent, NULL); #if DBG DbgInitDebugChannels(); #if KDBG KdRosRegisterCliCallback(DbgGdiKdbgCliCallback); #endif #endif TRACE_CH(UserProcess,"Allocated ppi 0x%p for PID:0x%lx\n", ppiCurrent, HandleToUlong(Process->UniqueProcessId)); /* map the global heap into the process */ Offset.QuadPart = 0; Status = MmMapViewOfSection(GlobalUserHeapSection, PsGetCurrentProcess(), &UserBase, 0, 0, &Offset, &ViewSize, ViewUnmap, SEC_NO_CHANGE, PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */ if (!NT_SUCCESS(Status)) { TRACE_CH(UserProcess,"Failed to map the global heap! 0x%x\n", Status); goto Leave; } ppiCurrent->HeapMappings.Next = NULL; ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap; ppiCurrent->HeapMappings.UserMapping = UserBase; ppiCurrent->HeapMappings.Count = 1; InitializeListHead(&ppiCurrent->MenuListHead); InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList); InitializeListHead(&ppiCurrent->GDIDcAttrFreeList); InitializeListHead(&ppiCurrent->PrivateFontListHead); ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock); InitializeListHead(&ppiCurrent->DriverObjListHead); ExInitializeFastMutex(&ppiCurrent->DriverObjListLock); ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout(); if (!EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent)) { KeBugCheck(0); } KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE); /* map the gdi handle table to user land */ Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process); Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT; pParams = Process->Peb->ProcessParameters; ppiCurrent->peProcess = Process; /* setup process flags */ ppiCurrent->W32PF_flags = W32PF_THREADCONNECTED; if ( pParams && pParams->WindowFlags & STARTF_SCRNSAVER ) { ppiScrnSaver = ppiCurrent; ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER; } // Fixme check if this process is allowed. ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off. /* Create pools for GDI object attributes */ ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG'); ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG'); ppiCurrent->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG'); ASSERT(ppiCurrent->pPoolDcAttr); ASSERT(ppiCurrent->pPoolBrushAttr); ASSERT(ppiCurrent->pPoolRgnAttr); /* Add the process to the global list */ ppiCurrent->ppiNext = gppiList; gppiList = ppiCurrent; } else { /* Get the Win32 Process */ ppiCurrent = PsGetProcessWin32Process(Process); ASSERT(ppiCurrent); TRACE_CH(UserProcess, "Destroying ppi 0x%p\n", ppiCurrent); ppiCurrent->W32PF_flags |= W32PF_TERMINATED; if (ppiScrnSaver == ppiCurrent) ppiScrnSaver = NULL; if (ppiCurrent->InputIdleEvent) { EngFreeMem(ppiCurrent->InputIdleEvent); ppiCurrent->InputIdleEvent = NULL; } IntCleanupMenus(Process, ppiCurrent); IntCleanupCurIcons(Process, ppiCurrent); GDI_CleanupForProcess(Process); co_IntGraphicsCheck(FALSE); /* * Deregister logon application automatically */ if(LogonProcess == ppiCurrent) { LogonProcess = NULL; } /* Close the startup desktop */ if(ppiCurrent->rpdeskStartup) ObDereferenceObject(ppiCurrent->rpdeskStartup); if(ppiCurrent->hdeskStartup) ZwClose(ppiCurrent->hdeskStartup); /* Close the current window station */ UserSetProcessWindowStation(NULL); /* Destroy GDI pools */ GdiPoolDestroy(ppiCurrent->pPoolDcAttr); GdiPoolDestroy(ppiCurrent->pPoolBrushAttr); GdiPoolDestroy(ppiCurrent->pPoolRgnAttr); if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL; pppi = &gppiList; while (*pppi != NULL && *pppi != ppiCurrent) pppi = &(*pppi)->ppiNext; ASSERT(*pppi == ppiCurrent); *pppi = ppiCurrent->ppiNext; TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent); #if DBG if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL)) { DbgUserDumpHandleTable(); } #endif /* Free the PROCESSINFO */ PsSetProcessWin32Process(Process, NULL, ppiCurrent); ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO); } Status = STATUS_SUCCESS; Leave: UserLeave(); return Status; }
NTSTATUS NTAPI UserCreateThreadInfo(struct _ETHREAD *Thread) { struct _EPROCESS *Process; PCLIENTINFO pci; PTHREADINFO ptiCurrent; int i; NTSTATUS Status = STATUS_SUCCESS; PTEB pTeb; LARGE_INTEGER LargeTickCount; Process = Thread->ThreadsProcess; pTeb = NtCurrentTeb(); ASSERT(pTeb); ptiCurrent = ExAllocatePoolWithTag(NonPagedPool, sizeof(THREADINFO), USERTAG_THREADINFO); if (ptiCurrent == NULL) { ERR_CH(UserThread, "Failed to allocate pti for TID %p\n", Thread->Cid.UniqueThread); return STATUS_NO_MEMORY; } TRACE_CH(UserThread,"Create pti 0x%p eThread 0x%p\n", ptiCurrent, Thread); RtlZeroMemory(ptiCurrent, sizeof(THREADINFO)); /* Initialize the THREADINFO */ PsSetThreadWin32Thread(Thread, ptiCurrent, NULL); IntReferenceThreadInfo(ptiCurrent); ptiCurrent->pEThread = Thread; ptiCurrent->ppi = PsGetCurrentProcessWin32Process(); pTeb->Win32ThreadInfo = ptiCurrent; ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo; TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread); InitializeListHead(&ptiCurrent->WindowListHead); InitializeListHead(&ptiCurrent->W32CallbackListHead); InitializeListHead(&ptiCurrent->PostedMessagesListHead); InitializeListHead(&ptiCurrent->SentMessagesListHead); InitializeListHead(&ptiCurrent->DispatchingMessagesHead); InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead); InitializeListHead(&ptiCurrent->PtiLink); for (i = 0; i < NB_HOOKS; i++) { InitializeListHead(&ptiCurrent->aphkStart[i]); } ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList; ptiCurrent->ppi->ptiList = ptiCurrent; ptiCurrent->ppi->cThreads++; ptiCurrent->hEventQueueClient = NULL; Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE); if (!NT_SUCCESS(Status)) { goto error; } Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, *ExEventObjectType, KernelMode, (PVOID*)&ptiCurrent->pEventQueueServer, NULL); if (!NT_SUCCESS(Status)) { ZwClose(ptiCurrent->hEventQueueClient); ptiCurrent->hEventQueueClient = NULL; goto error; } KeQueryTickCount(&LargeTickCount); ptiCurrent->timeLast = LargeTickCount.u.LowPart; ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent); if(ptiCurrent->MessageQueue == NULL) { ERR_CH(UserThread,"Failed to allocate message loop\n"); Status = STATUS_NO_MEMORY; goto error; } ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout(); if (ptiCurrent->KeyboardLayout) UserReferenceObject(ptiCurrent->KeyboardLayout); ptiCurrent->TIF_flags &= ~TIF_INCLEANUP; if (Process == gpepCSRSS) /* If this thread is owned by CSRSS, mark it as such */ ptiCurrent->TIF_flags |= TIF_CSRSSTHREAD; ptiCurrent->pcti = &ptiCurrent->cti; /* Initialize the CLIENTINFO */ pci = (PCLIENTINFO)pTeb->Win32ClientInfo; RtlZeroMemory(pci, sizeof(CLIENTINFO)); pci->ppi = ptiCurrent->ppi; pci->fsHooks = ptiCurrent->fsHooks; pci->dwTIFlags = ptiCurrent->TIF_flags; if (ptiCurrent->KeyboardLayout) { pci->hKL = ptiCurrent->KeyboardLayout->hkl; pci->CodePage = ptiCurrent->KeyboardLayout->CodePage; } /* Assign a default window station and desktop to the process */ /* Do not try to open a desktop or window station before winlogon initializes */ if(ptiCurrent->ppi->hdeskStartup == NULL && LogonProcess != NULL) { HWINSTA hWinSta = NULL; HDESK hDesk = NULL; UNICODE_STRING DesktopPath; PDESKTOP pdesk; PRTL_USER_PROCESS_PARAMETERS ProcessParams; /* * inherit the thread desktop and process window station (if not yet inherited) from the process startup * info structure. See documentation of CreateProcess() */ ProcessParams = pTeb->ProcessEnvironmentBlock->ProcessParameters; Status = STATUS_UNSUCCESSFUL; if(ProcessParams && ProcessParams->DesktopInfo.Length > 0) { Status = IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath, &ProcessParams->DesktopInfo); } if(!NT_SUCCESS(Status)) { RtlInitUnicodeString(&DesktopPath, NULL); } Status = IntParseDesktopPath(Process, &DesktopPath, &hWinSta, &hDesk); if (DesktopPath.Buffer) ExFreePoolWithTag(DesktopPath.Buffer, TAG_STRING); if(!NT_SUCCESS(Status)) { ERR_CH(UserThread, "Failed to assign default dekstop and winsta to process\n"); goto error; } if(!UserSetProcessWindowStation(hWinSta)) { Status = STATUS_UNSUCCESSFUL; ERR_CH(UserThread,"Failed to set initial process winsta\n"); goto error; } /* Validate the new desktop. */ Status = IntValidateDesktopHandle(hDesk, UserMode, 0, &pdesk); if(!NT_SUCCESS(Status)) { ERR_CH(UserThread,"Failed to validate initial desktop handle\n"); goto error; } /* Store the parsed desktop as the initial desktop */ ptiCurrent->ppi->hdeskStartup = hDesk; ptiCurrent->ppi->rpdeskStartup = pdesk; } if (ptiCurrent->ppi->hdeskStartup != NULL) { if (!IntSetThreadDesktop(ptiCurrent->ppi->hdeskStartup, FALSE)) { ERR_CH(UserThread,"Failed to set thread desktop\n"); Status = STATUS_UNSUCCESSFUL; goto error; } } /* mark the thread as fully initialized */ ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED; if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) && (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi )) { ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; } ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; TRACE_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent); return STATUS_SUCCESS; error: ERR_CH(UserThread,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread); UserDestroyThreadInfo(Thread); return Status; }