drivers/gpu/drm/nouveau/nouveau_chan.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nouveau_chan.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/nouveau/nouveau_chan.c- Extension
.c- Size
- 16740 bytes
- Lines
- 580
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
nvif/push006c.hnvif/class.hnvif/cl0002.hnvif/if0020.hnouveau_drv.hnouveau_dma.hnouveau_bo.hnouveau_chan.hnouveau_fence.hnouveau_abi16.hnouveau_vmm.hnouveau_svm.h
Detected Declarations
function nouveau_channel_killfunction nouveau_channel_killedfunction nouveau_channel_idlefunction nouveau_channel_delfunction nouveau_channel_kickfunction nouveau_channel_waitfunction nouveau_channel_prepfunction nouveau_channel_ctorfunction nouveau_channel_initfunction nouveau_channel_newfunction nouveau_channels_finifunction nouveau_channels_init
Annotated Snippet
if (!ret) {
ret = nouveau_fence_wait(fence, false, false);
nouveau_fence_unref(&fence);
}
if (ret) {
NV_PRINTK(err, cli, "failed to idle channel %d [%s]\n",
chan->chid, cli->name);
return ret;
}
}
return 0;
}
void
nouveau_channel_del(struct nouveau_channel **pchan)
{
struct nouveau_channel *chan = *pchan;
if (chan) {
if (chan->fence)
nouveau_fence(chan->cli->drm)->context_del(chan);
if (nvif_object_constructed(&chan->user))
nouveau_svmm_part(chan->vmm->svmm, chan->inst);
nvif_object_dtor(&chan->blit);
nvif_object_dtor(&chan->nvsw);
nvif_object_dtor(&chan->gart);
nvif_object_dtor(&chan->vram);
nvif_event_dtor(&chan->kill);
nvif_object_dtor(&chan->user);
nvif_mem_dtor(&chan->mem_userd);
nouveau_vma_del(&chan->sema.vma);
nouveau_bo_unpin_del(&chan->sema.bo);
nvif_object_dtor(&chan->push.ctxdma);
nouveau_vma_del(&chan->push.vma);
nouveau_bo_unpin_del(&chan->push.buffer);
kfree(chan);
}
*pchan = NULL;
}
static void
nouveau_channel_kick(struct nvif_push *push)
{
struct nouveau_channel *chan = container_of(push, typeof(*chan), chan.push);
chan->dma.cur = chan->dma.cur + (chan->chan.push.cur - chan->chan.push.bgn);
FIRE_RING(chan);
chan->chan.push.bgn = chan->chan.push.cur;
}
static int
nouveau_channel_wait(struct nvif_push *push, u32 size)
{
struct nouveau_channel *chan = container_of(push, typeof(*chan), chan.push);
int ret;
chan->dma.cur = chan->dma.cur + (chan->chan.push.cur - chan->chan.push.bgn);
ret = RING_SPACE(chan, size);
if (ret == 0) {
chan->chan.push.bgn = chan->chan.push.mem.object.map.ptr;
chan->chan.push.bgn = chan->chan.push.bgn + chan->dma.cur;
chan->chan.push.cur = chan->chan.push.bgn;
chan->chan.push.end = chan->chan.push.bgn + size;
}
return ret;
}
static int
nouveau_channel_prep(struct nouveau_cli *cli,
u32 size, struct nouveau_channel **pchan)
{
struct nouveau_drm *drm = cli->drm;
struct nvif_device *device = &cli->device;
struct nv_dma_v0 args = {};
struct nouveau_channel *chan;
u32 target;
int ret;
chan = *pchan = kzalloc_obj(*chan);
if (!chan)
return -ENOMEM;
chan->cli = cli;
chan->vmm = nouveau_cli_vmm(cli);
atomic_set(&chan->killed, 0);
/* allocate memory for dma push buffer */
target = NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT;
if (nouveau_vram_pushbuf)
target = NOUVEAU_GEM_DOMAIN_VRAM;
Annotation
- Immediate include surface: `nvif/push006c.h`, `nvif/class.h`, `nvif/cl0002.h`, `nvif/if0020.h`, `nouveau_drv.h`, `nouveau_dma.h`, `nouveau_bo.h`, `nouveau_chan.h`.
- Detected declarations: `function nouveau_channel_kill`, `function nouveau_channel_killed`, `function nouveau_channel_idle`, `function nouveau_channel_del`, `function nouveau_channel_kick`, `function nouveau_channel_wait`, `function nouveau_channel_prep`, `function nouveau_channel_ctor`, `function nouveau_channel_init`, `function nouveau_channel_new`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.