drivers/gpu/drm/imagination/pvr_drv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imagination/pvr_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/imagination/pvr_drv.c
Extension
.c
Size
42160 bytes
Lines
1539
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 (pvr_device_has_uapi_quirk(pvr_dev, umd_quirks_musthave[i])) {
			out[out_count++] = umd_quirks_musthave[i];
			out_musthave_count++;
		}
	}

	for (int i = 0; i < ARRAY_SIZE(umd_quirks); i++) {
		if (pvr_device_has_uapi_quirk(pvr_dev, umd_quirks[i]))
			out[out_count++] = umd_quirks[i];
	}

	if (!query.quirks)
		goto copy_out;
	if (query.count < out_count)
		return -E2BIG;

	if (copy_to_user(u64_to_user_ptr(query.quirks), out,
			 out_count * sizeof(u32))) {
		return -EFAULT;
	}

	query.musthave_count = out_musthave_count;

copy_out:
	query.count = out_count;
	err = PVR_UOBJ_SET(args->pointer, args->size, query);
	if (err < 0)
		return err;

	args->size = sizeof(query);
	return 0;
}

/**
 * pvr_dev_query_enhancements_get() - Unpack array of enhancements at the
 * address given in a struct drm_pvr_dev_query_enhancements, or gets the amount
 * of space required for it.
 * @pvr_dev: Device pointer.
 * @args: [IN] Device query arguments containing a pointer to a userspace
 *        struct drm_pvr_dev_query_enhancements.
 *
 * If the query object pointer is NULL, the size field is updated with the
 * expected size of the query object.
 * If the userspace pointer in the query object is NULL, or the count is
 * short, no data is copied.
 * The count field will be updated to that copied, or if either pointer is
 * NULL, that which would have been copied.
 * The size field in the query object will be updated to the size copied.
 *
 * Returns:
 *  * 0 on success, or if size/count is requested using a NULL pointer, or
 *  * -%EINVAL if args contained non-zero reserved fields, or
 *  * -%E2BIG if the indicated length of the allocation is less than is
 *    required to contain the copied data, or
 *  * -%EFAULT if local memory could not be copied to userspace.
 */
static int
pvr_dev_query_enhancements_get(struct pvr_device *pvr_dev,
			       struct drm_pvr_ioctl_dev_query_args *args)
{
	/*
	 * @FIXME - hardcoding of numbers here is intended as an
	 * intermediate step so the UAPI can be fixed, but requires a
	 * a refactor in the future to store them in a more appropriate
	 * location
	 */
	const u32 umd_enhancements[] = {
		35421,
		42064,
	};
	struct drm_pvr_dev_query_enhancements query;
	u32 out[ARRAY_SIZE(umd_enhancements)];
	size_t out_idx = 0;
	int err;

	if (!args->pointer) {
		args->size = sizeof(struct drm_pvr_dev_query_enhancements);
		return 0;
	}

	err = PVR_UOBJ_GET(query, args->size, args->pointer);

	if (err < 0)
		return err;
	if (query._padding_a)
		return -EINVAL;
	if (query._padding_c)
		return -EINVAL;

	for (int i = 0; i < ARRAY_SIZE(umd_enhancements); i++) {

Annotation

Implementation Notes