Module Name: src Committed By: riastradh Date: Sun Dec 19 00:25:53 UTC 2021
Modified Files: src/sys/external/bsd/drm2/drm: files.drmkms Added Files: src/sys/external/bsd/drm2/drm: drm_gem_framebuffer_helper.c Log Message: Local reimplementation of GPL drm_gem_framebuffer_helper.c. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 \ src/sys/external/bsd/drm2/drm/drm_gem_framebuffer_helper.c cvs rdiff -u -r1.36 -r1.37 src/sys/external/bsd/drm2/drm/files.drmkms Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/drm/files.drmkms diff -u src/sys/external/bsd/drm2/drm/files.drmkms:1.36 src/sys/external/bsd/drm2/drm/files.drmkms:1.37 --- src/sys/external/bsd/drm2/drm/files.drmkms:1.36 Sun Dec 19 00:25:34 2021 +++ src/sys/external/bsd/drm2/drm/files.drmkms Sun Dec 19 00:25:53 2021 @@ -1,4 +1,4 @@ -# $NetBSD: files.drmkms,v 1.36 2021/12/19 00:25:34 riastradh Exp $ +# $NetBSD: files.drmkms,v 1.37 2021/12/19 00:25:53 riastradh Exp $ include "external/bsd/drm2/linux/files.drmkms_linux" @@ -96,7 +96,6 @@ file external/bsd/drm2/dist/drm/drm_form file external/bsd/drm2/dist/drm/drm_fourcc.c drmkms file external/bsd/drm2/dist/drm/drm_framebuffer.c drmkms file external/bsd/drm2/dist/drm/drm_gem.c drmkms -file external/bsd/drm2/dist/drm/drm_gem_framebuffer_helper.c drmkms file external/bsd/drm2/dist/drm/drm_hashtab.c drmkms file external/bsd/drm2/dist/drm/drm_hdcp.c drmkms file external/bsd/drm2/dist/drm/drm_ioctl.c drmkms @@ -129,6 +128,7 @@ file external/bsd/drm2/dist/drm/drm_vm.c file external/bsd/drm2/dist/drm/drm_writeback.c drmkms file external/bsd/drm2/drm/drm_cache.c drmkms file external/bsd/drm2/drm/drm_fops.c drmkms +file external/bsd/drm2/drm/drm_gem_framebuffer_helper.c drmkms file external/bsd/drm2/drm/drm_lock.c drmkms file external/bsd/drm2/drm/drm_memory.c drmkms file external/bsd/drm2/drm/drm_scatter.c drmkms Added files: Index: src/sys/external/bsd/drm2/drm/drm_gem_framebuffer_helper.c diff -u /dev/null src/sys/external/bsd/drm2/drm/drm_gem_framebuffer_helper.c:1.1 --- /dev/null Sun Dec 19 00:25:53 2021 +++ src/sys/external/bsd/drm2/drm/drm_gem_framebuffer_helper.c Sun Dec 19 00:25:53 2021 @@ -0,0 +1,157 @@ +/* $NetBSD: drm_gem_framebuffer_helper.c,v 1.1 2021/12/19 00:25:53 riastradh Exp $ */ + +/*- + * Copyright (c) 2018 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Taylor R. Campbell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: drm_gem_framebuffer_helper.c,v 1.1 2021/12/19 00:25:53 riastradh Exp $"); + +#include <linux/err.h> +#include <linux/slab.h> + +#include <drm/drm_framebuffer.h> +#include <drm/drm_gem.h> + +#include <uapi/drm/drm_mode.h> + +/* + * drm_gem_fb_destroy(fb) + * + * Release the objects in, clean up and, kfree a framebuffer + * allocated with drm_gem_fb_create_with_funcs. + * + * Fit for use as struct drm_framebuffer_funcs::destroy. Caller + * must guarantee that the struct drm_framebuffer is allocated + * with kmalloc. + */ +void +drm_gem_fb_destroy(struct drm_framebuffer *fb) +{ + unsigned plane; + + for (plane = 0; plane < __arraycount(fb->obj); plane++) + drm_gem_object_put_unlocked(fb->obj[plane]); + drm_framebuffer_cleanup(fb); + kfree(fb); +} + +/* + * drm_gem_fb_create_handle(fb, file, handlep) + * + * Create a GEM handle for the object of the first plane (plane=0) + * of fb in the specified drm file namespace, and store it in + * *handlep. + * + * Returns 0 on success, negative error on failure. + */ +int +drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file, + unsigned *handlep) +{ + + return drm_gem_handle_create(file, fb->obj[0], handlep); +} + +/* + * drm_gem_fb_create_with_funcs(dev, file, mode_cmd, funcs) + * + * Create a framebuffer in the specified drm device from the given + * mode command, resolving mode_cmd's handles in the specified drm + * file. + * + * Returns pointer on success, ERR_PTR on failure. + * + * ENOENT missing handle + * EINVAL wrong size object, invalid mode format + */ +struct drm_framebuffer * +drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd, + const struct drm_framebuffer_funcs *funcs) +{ + struct drm_framebuffer *fb; + unsigned plane; + int ret; + + /* Allocate a framebuffer object with kmalloc. */ + fb = kmalloc(sizeof(*fb), GFP_KERNEL); + if (fb == NULL) { + ret = -ENOMEM; + goto fail0; + } + + /* + * Fill framebuffer parameters from mode_cmd. If they're not + * valid, fail with EINVAL. + */ + drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); + if (fb->format == NULL) { + ret = -EINVAL; + goto fail1; + } + + /* Get the object for each plane. */ + for (plane = 0; plane < fb->format->num_planes; plane++) { + unsigned vsub = (plane > 0 ? info->vsub : 1); /* XXX ? */ + unsigned hsub = (plane > 0 ? info->hsub : 1); /* XXX ? */ + unsigned handle = mode_cmd->handles[plane]; + unsigned size; + + /* Look up the object for this plane. */ + fb->obj[plane] = drm_gem_object_lookup(file, handle); + if (fb->obj[plane] == NULL) { + ret = -ENOENT; + goto fail2; + } + + /* Confirm the object is large enough to handle it. */ + size = (mode_cmd->height/vsub - 1)*mode_cmd->pitches[plane] + + (mode_cmd->width/hsub)*fb->format->cpp[plane] + + mode_cmd->offsets[plane]; + if (fb->obj[plane]->size < size) { + ret = -EINVAL; + plane++; /* free this one too */ + goto fail2; + } + } + + /* Initialize the framebuffer. */ + ret = drm_framebuffer_init(dev, fb, funcs); + if (ret) + goto fail2; + + /* Success! */ + return fb; + +fail2: while (plane --> 0) + drm_gem_object_put_unlocked(fb->obj[plane]); +fail1: kmem_free(fb, sizeof(*fb)); +fail0: KASSERT(ret); + return ERR_PTR(ret); +}