drivers/gpu/drm/nouveau/nvkm/core/firmware.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/core/firmware.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/core/firmware.c
Extension
.c
Size
7434 bytes
Lines
310
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (fw->img) {
			memcpy(fw->img, src, fw->len);
			fw->phys = addr;
		}

		sg_init_one(&fw->mem.sgl, fw->img, len);
		sg_dma_address(&fw->mem.sgl) = fw->phys;
		sg_dma_len(&fw->mem.sgl) = len;
	}
		break;
	case NVKM_FIRMWARE_IMG_SGT:
		len = ALIGN(fw->len, PAGE_SIZE);

		fw->img = vmalloc(len);
		if (fw->img) {
			int pages = len >> PAGE_SHIFT;
			int ret = 0;

			memcpy(fw->img, src, fw->len);

			ret = sg_alloc_table(&fw->mem.sgt, pages, GFP_KERNEL);
			if (ret == 0) {
				struct scatterlist *sgl;
				u8 *data = fw->img;
				int i;

				for_each_sgtable_sg(&fw->mem.sgt, sgl, i) {
					struct page *page = vmalloc_to_page(data);

					if (!page) {
						ret = -EFAULT;
						break;
					}

					sg_set_page(sgl, page, PAGE_SIZE, 0);
					data += PAGE_SIZE;
				}

				if (ret == 0) {
					ret = dma_map_sgtable(fw->device->dev, &fw->mem.sgt,
							      DMA_TO_DEVICE, 0);
				}

				if (ret)
					sg_free_table(&fw->mem.sgt);
			}

			if (ret) {
				vfree(fw->img);
				fw->img = NULL;
			}
		}
		break;
	default:
		WARN_ON(1);
		return -EINVAL;
	}

	if (!fw->img)
		return -ENOMEM;

	nvkm_memory_ctor(&nvkm_firmware_mem, &fw->mem.memory);
	return 0;
}

Annotation

Implementation Notes