--- Begin Message ---
Package: evdi
Version: 1.9.0+dfsg-1
Severity: normal
Tags: patch pending
Dear maintainer,
I've prepared an NMU for evdi (versioned as 1.12.0+dfsg-0.1) and uploaded it to
DELAYED/0 as there has been no activity for some time and it has been dropped
from testing.
Regards.
diff -Nru evdi-1.9.0+dfsg/debian/changelog evdi-1.12.0+dfsg/debian/changelog
--- evdi-1.9.0+dfsg/debian/changelog 2021-01-26 10:32:36.000000000 -0500
+++ evdi-1.12.0+dfsg/debian/changelog 2022-11-01 11:56:26.000000000 -0400
@@ -1,3 +1,12 @@
+evdi (1.12.0+dfsg-0.1) unstable; urgency=medium
+
+ * Non-maintainer upload.
+ * New upstream release (Closes: #994892, #1017058)
+ * Import patch to fix FTBFS in Linux >= 6.0 from upstream
+ * Add dh-dkms to build-depends
+
+ -- Harlan Lieberman-Berg <[email protected]> Tue, 01 Nov 2022 11:56:26
-0400
+
evdi (1.9.0+dfsg-1) unstable; urgency=medium
* new upstream release 1.9.0
diff -Nru evdi-1.9.0+dfsg/debian/control evdi-1.12.0+dfsg/debian/control
--- evdi-1.9.0+dfsg/debian/control 2021-01-26 10:32:36.000000000 -0500
+++ evdi-1.12.0+dfsg/debian/control 2022-11-01 11:56:26.000000000 -0400
@@ -2,7 +2,7 @@
Section: misc
Priority: optional
Maintainer: Hanno Stock <[email protected]>
-Build-Depends: debhelper-compat (= 13), dkms, dh-exec, libdrm-dev
+Build-Depends: debhelper-compat (= 13), dh-dkms, dkms, dh-exec, libdrm-dev
Standards-Version: 4.5.0
Rules-Requires-Root: no
Homepage: https://github.com/DisplayLink/evdi
diff -Nru evdi-1.9.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch
evdi-1.12.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch
--- evdi-1.9.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch 1969-12-31
19:00:00.000000000 -0500
+++ evdi-1.12.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch 2022-11-01
11:56:26.000000000 -0400
@@ -0,0 +1,53 @@
+From bdc258b25df4d00f222fde0e3c5003bf88ef17b5 Mon Sep 17 00:00:00 2001
+From: Adam Tazul <[email protected]>
+Date: Thu, 13 Oct 2022 10:50:00 +0100
+Subject: [PATCH] Add support for kernel 6.0 + a minor fix (#381)
+
+* Add support for kernel 6.0
+
+Fixes #376 by implementing @Crashdummyy's fix as posted
[here](https://github.com/DisplayLink/evdi/issues/376#issuecomment-1237450695)
+
+* Fixing the style used in evdi_painter.c
+
+* Update evdi_painter.c
+
+* drm_framebuffer is only included on 5.15 and later
+
+* drm_framebuffer is only included on 6.0.0 and later
+
+* drm_framebuffer is only included on 6.0.0 and later
+
+* drm_framebuffer is only included on 6.0.0 and later
+
+* drm_framebuffer is only included on 5.15.0 and later
+---
+ module/evdi_drm_drv.h | 2 +-
+ module/evdi_painter.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+Index: evdi/module/evdi_drm_drv.h
+===================================================================
+--- evdi.orig/module/evdi_drm_drv.h
++++ evdi/module/evdi_drm_drv.h
+@@ -26,7 +26,7 @@
+ #include <drm/drmP.h>
+ #endif
+ #if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+-#include <drm/drm_legacy.h>
++#include <drm/drm_framebuffer.h>
+ #else
+ #include <drm/drm_irq.h>
+ #endif
+Index: evdi/module/evdi_painter.c
+===================================================================
+--- evdi.orig/module/evdi_painter.c
++++ evdi/module/evdi_painter.c
+@@ -885,7 +885,7 @@ evdi_painter_connect(struct evdi_device
+
+ painter_lock(painter);
+
+- evdi->pixel_area_limit = pixel_area_limit;
++ evdi->pixel_area_limit = pixel_area_limit;
+ evdi->pixel_per_second_limit = pixel_per_second_limit;
+ painter->drm_filp = file;
+ kfree(painter->edid);
diff -Nru evdi-1.9.0+dfsg/debian/patches/series
evdi-1.12.0+dfsg/debian/patches/series
--- evdi-1.9.0+dfsg/debian/patches/series 1969-12-31 19:00:00.000000000
-0500
+++ evdi-1.12.0+dfsg/debian/patches/series 2022-11-01 11:56:26.000000000
-0400
@@ -0,0 +1 @@
+0001-fix-6.0-ftbfs.patch
diff -Nru evdi-1.9.0+dfsg/library/evdi_lib.c evdi-1.12.0+dfsg/library/evdi_lib.c
--- evdi-1.9.0+dfsg/library/evdi_lib.c 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/library/evdi_lib.c 2022-07-13 09:58:06.000000000 -0400
@@ -29,7 +29,7 @@
#define EVDI_INVALID_DEVICE_INDEX -1
#define EVDI_MODULE_COMPATIBILITY_VERSION_MAJOR 1
-#define EVDI_MODULE_COMPATIBILITY_VERSION_MINOR 8
+#define EVDI_MODULE_COMPATIBILITY_VERSION_MINOR 9
#define EVDI_MODULE_COMPATIBILITY_VERSION_PATCH 0
#define evdi_log(...) do { \
@@ -468,15 +468,45 @@
return dev_index;
}
-static int find_unused_card_for(const char *sysfs_parent_device_path)
+static bool is_correct_parent_device(const char *dirname, const char
*parent_device)
{
+ char link_path[PATH_MAX];
+
+ snprintf(link_path, PATH_MAX - 7, "%s/device", dirname);
+
+ if (parent_device == NULL)
+ return access(link_path, F_OK) != 0;
+
+ char link_resolution[PATH_MAX];
+ const ssize_t link_resolution_len = readlink(link_path,
link_resolution, PATH_MAX);
+
+ if (link_resolution_len == -1 || link_resolution_len == PATH_MAX)
+ return false;
+
+ link_resolution[link_resolution_len] = '\0';
+ char *parent_device_token = strrchr(link_resolution, '/');
+
+ if (strlen(parent_device) < 2)
+ return false;
+
+ parent_device_token++;
+ size_t len = strlen(parent_device_token);
+
+ bool is_same_device = strlen(parent_device) == len &&
strncmp(parent_device_token, parent_device, len) == 0;
+
+ return is_same_device;
+}
+
+static int find_unused_card_for(const char *parent_device)
+{
+ char evdi_platform_root[] = "/sys/bus/platform/devices";
struct dirent *fd_entry;
DIR *fd_dir;
int device_index = EVDI_INVALID_DEVICE_INDEX;
- fd_dir = opendir(sysfs_parent_device_path);
+ fd_dir = opendir(evdi_platform_root);
if (fd_dir == NULL) {
- evdi_log("Failed to open dir %s", sysfs_parent_device_path);
+ evdi_log("Failed to open dir %s", evdi_platform_root);
return device_index;
}
@@ -484,9 +514,16 @@
if (strncmp(fd_entry->d_name, "evdi", 4) != 0)
continue;
+ char evdi_path[PATH_MAX];
+
+ snprintf(evdi_path, PATH_MAX, "%s/%s", evdi_platform_root,
fd_entry->d_name);
+
+ if (!is_correct_parent_device(evdi_path, parent_device))
+ continue;
+
char evdi_drm_path[PATH_MAX];
- snprintf(evdi_drm_path, PATH_MAX, "%s/%s/drm",
sysfs_parent_device_path, fd_entry->d_name);
+ snprintf(evdi_drm_path, PATH_MAX - strlen(evdi_path), "%s/drm",
evdi_path);
int dev_index = get_drm_device_index(evdi_drm_path);
assert(dev_index < EVDI_USAGE_LEN && dev_index >= 0);
@@ -503,37 +540,30 @@
static int get_generic_device(void)
{
- char evdi_platform_root[] = "/sys/devices/platform";
int device_index = EVDI_INVALID_DEVICE_INDEX;
- device_index = find_unused_card_for(evdi_platform_root);
+ device_index = find_unused_card_for(NULL);
if (device_index == EVDI_INVALID_DEVICE_INDEX) {
- evdi_log("Creating card in %s", evdi_platform_root);
+ evdi_log("Creating card in /sys/devices/platform");
write_add_device("1", 1);
- device_index = find_unused_card_for(evdi_platform_root);
+ device_index = find_unused_card_for(NULL);
}
return device_index;
}
-static int get_device_attached_to_usb(const char *bus_ident)
+static int get_device_attached_to_usb(const char *sysfs_parent_device)
{
int device_index = EVDI_INVALID_DEVICE_INDEX;
- char evdi_usb_parent_path[PATH_MAX] = "/sys/bus/usb/devices/";
-
- strncat(evdi_usb_parent_path, bus_ident, PATH_MAX -
strlen(evdi_usb_parent_path));
+ const char *parent_device = &sysfs_parent_device[4];
- device_index = find_unused_card_for(evdi_usb_parent_path);
+ device_index = find_unused_card_for(parent_device);
if (device_index == EVDI_INVALID_DEVICE_INDEX) {
- evdi_log("Creating card for %s", bus_ident);
- char usb_dev_path[PATH_MAX] = "usb:";
- const size_t current_len = strlen(usb_dev_path);
+ evdi_log("Creating card for usb device %s in
/sys/bus/platform/devices", parent_device);
+ const size_t len = strlen(sysfs_parent_device);
- strncat(usb_dev_path, bus_ident, PATH_MAX - current_len);
- const size_t len = strlen(usb_dev_path);
-
- write_add_device(usb_dev_path, len);
- device_index = find_unused_card_for(evdi_usb_parent_path);
+ write_add_device(sysfs_parent_device, len);
+ device_index = find_unused_card_for(parent_device);
}
return device_index;
@@ -616,14 +646,8 @@
if (sysfs_parent_device == NULL)
device_index = get_generic_device();
- if (sysfs_parent_device != NULL && strncmp(sysfs_parent_device, "usb:",
4) == 0 && strlen(sysfs_parent_device) > 4) {
- char bus_ident[PATH_MAX];
- const size_t len = strlen(sysfs_parent_device) - 4;
-
- strncpy(bus_ident, &sysfs_parent_device[4], len);
- bus_ident[len] = 0;
- device_index = get_device_attached_to_usb(bus_ident);
- }
+ if (sysfs_parent_device != NULL && strncmp(sysfs_parent_device, "usb:",
4) == 0 && strlen(sysfs_parent_device) > 4)
+ device_index = get_device_attached_to_usb(sysfs_parent_device);
if (device_index >= 0 && device_index < EVDI_USAGE_LEN) {
evdi_handle handle = evdi_open(device_index);
@@ -651,14 +675,16 @@
void evdi_connect(evdi_handle handle,
const unsigned char *edid,
const unsigned int edid_length,
- const uint32_t sku_area_limit)
+ const uint32_t pixel_area_limit,
+ const uint32_t pixel_per_second_limit)
{
struct drm_evdi_connect cmd = {
.connected = 1,
.dev_index = handle->device_index,
.edid = edid,
.edid_length = edid_length,
- .sku_area_limit = sku_area_limit,
+ .pixel_area_limit = pixel_area_limit,
+ .pixel_per_second_limit = pixel_per_second_limit,
};
do_ioctl(handle->fd, DRM_IOCTL_EVDI_CONNECT, &cmd, "connect");
@@ -666,44 +692,22 @@
void evdi_disconnect(evdi_handle handle)
{
- struct drm_evdi_connect cmd = { 0, 0, 0, 0, 0 };
+ struct drm_evdi_connect cmd = { 0, 0, 0, 0, 0, 0 };
do_ioctl(handle->fd, DRM_IOCTL_EVDI_CONNECT, &cmd, "disconnect");
}
-void evdi_enable_cursor_events(evdi_handle handle)
+void evdi_enable_cursor_events(evdi_handle handle, bool enable)
{
- char path[PATH_MAX] = {0};
- static const char enable[] = "Y";
- int path_len = 0;
- FILE *cursor_evs = NULL;
- size_t written = 0;
- const size_t elem_bytes = 1;
- int errcode = 0;
-
- if (evdi_device_to_platform(handle->device_index, path) !=
- AVAILABLE) {
- evdi_log("Failed to enable cursor events");
- evdi_log("Device /dev/dri/card%d, device is not available.",
- handle->device_index);
- return;
- }
+ struct drm_evdi_enable_cursor_events cmd = {
+ .enable = enable,
+ };
- path_len = strlen(path);
- snprintf(path+path_len, PATH_MAX-path_len, "/cursor_events");
- cursor_evs = fopen(path, "w");
- if (cursor_evs == NULL) {
- evdi_log("Failed to open %s, err: %s", path, strerror(errno));
- return;
- }
+ evdi_log("%s cursor events on /dev/dri/card%d",
+ (enable ? "Enabling" : "Disabling"),
+ handle->device_index);
- written = fwrite(enable, elem_bytes, sizeof(enable), cursor_evs);
- errcode = errno;
- fclose(cursor_evs);
- evdi_log("Enabling cursor events on /dev/dri/card%d %s %s",
- handle->device_index,
- written < sizeof(enable) ? "failed: " : "succeeded",
- written < sizeof(enable) ? strerror(errcode) : "");
+ do_ioctl(handle->fd, DRM_IOCTL_EVDI_ENABLE_CURSOR_EVENTS, &cmd, "enable
cursor events");
}
void evdi_grab_pixels(evdi_handle handle,
@@ -861,6 +865,8 @@
cursor_set.buffer = malloc(size);
memcpy(cursor_set.buffer, ptr, size);
munmap(ptr, size);
+ } else {
+ evdi_log("Error: mmap failed with error: %s",
strerror(errno));
}
}
@@ -936,10 +942,13 @@
if (evtctx->cursor_set_handler) {
struct drm_evdi_event_cursor_set *event =
(struct drm_evdi_event_cursor_set *) e;
+ struct evdi_cursor_set cursor_set =
to_evdi_cursor_set(handle, event);
- evtctx->cursor_set_handler(to_evdi_cursor_set(handle,
- event),
- evtctx->user_data);
+ if (cursor_set.enabled && cursor_set.buffer == NULL)
+ evdi_log("Error: Cursor buffer is null!");
+ else
+ evtctx->cursor_set_handler(cursor_set,
+ evtctx->user_data);
}
break;
diff -Nru evdi-1.9.0+dfsg/library/evdi_lib.h evdi-1.12.0+dfsg/library/evdi_lib.h
--- evdi-1.9.0+dfsg/library/evdi_lib.h 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/library/evdi_lib.h 2022-07-13 09:58:06.000000000 -0400
@@ -12,7 +12,7 @@
#endif
#define LIBEVDI_VERSION_MAJOR 1
-#define LIBEVDI_VERSION_MINOR 9
+#define LIBEVDI_VERSION_MINOR 12
#define LIBEVDI_VERSION_PATCH 0
struct evdi_lib_version {
@@ -107,9 +107,10 @@
void evdi_close(evdi_handle handle);
void evdi_connect(evdi_handle handle, const unsigned char *edid,
const unsigned int edid_length,
- const uint32_t sku_area_limit);
+ const uint32_t pixel_area_limit,
+ const uint32_t pixel_per_second_limit);
void evdi_disconnect(evdi_handle handle);
-void evdi_enable_cursor_events(evdi_handle handle);
+void evdi_enable_cursor_events(evdi_handle handle, bool enable);
void evdi_grab_pixels(evdi_handle handle,
struct evdi_rect *rects,
diff -Nru evdi-1.9.0+dfsg/library/Makefile evdi-1.12.0+dfsg/library/Makefile
--- evdi-1.9.0+dfsg/library/Makefile 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/library/Makefile 2022-07-13 09:58:06.000000000 -0400
@@ -8,9 +8,9 @@
RM ?= rm
DEPS = evdi_ioctl.h
-CFLAGS := -I../module -std=gnu99 -fPIC $(CFLAGS)
+CFLAGS := -I../module -std=gnu99 -fPIC -D_FILE_OFFSET_BITS=64 $(CFLAGS)
-LIBVER := 1.9.0
+LIBVER := 1.12.0
LIBABI := 0
PREFIX ?= /usr/local
diff -Nru evdi-1.9.0+dfsg/module/dkms.conf evdi-1.12.0+dfsg/module/dkms.conf
--- evdi-1.9.0+dfsg/module/dkms.conf 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/dkms.conf 2022-07-13 09:58:06.000000000 -0400
@@ -7,7 +7,7 @@
#
PACKAGE_NAME="evdi"
-PACKAGE_VERSION=1.9.0
+PACKAGE_VERSION=1.12.0
AUTOINSTALL=yes
MAKE[0]="make all INCLUDEDIR=/lib/modules/$kernelver/build/include
KVERSION=$kernelver DKMS_BUILD=1"
diff -Nru evdi-1.9.0+dfsg/module/evdi_connector.c
evdi-1.12.0+dfsg/module/evdi_connector.c
--- evdi-1.9.0+dfsg/module/evdi_connector.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_connector.c 2022-07-13 09:58:06.000000000
-0400
@@ -50,11 +50,14 @@
ret = drm_mode_connector_update_edid_property(connector, edid);
#endif
- if (!ret)
- ret = drm_add_edid_modes(connector, edid);
- else
- EVDI_ERROR("Failed to set edid modes! error: %d", ret);
+ if (ret) {
+ EVDI_ERROR("Failed to set edid property! error: %d", ret);
+ goto err;
+ }
+ ret = drm_add_edid_modes(connector, edid);
+ EVDI_INFO("(card%d) Edid property set", evdi->dev_index);
+err:
kfree(edid);
return ret;
}
@@ -63,13 +66,15 @@
struct drm_display_mode *mode)
{
struct evdi_device *evdi = connector->dev->dev_private;
- uint32_t mode_area = mode->hdisplay * mode->vdisplay;
+ uint32_t area_limit = mode->hdisplay * mode->vdisplay;
+ uint32_t mode_limit = area_limit * drm_mode_vrefresh(mode);
- if (evdi->sku_area_limit == 0)
+ if (evdi->pixel_per_second_limit == 0)
return MODE_OK;
- if (mode_area > evdi->sku_area_limit) {
- EVDI_WARN("(dev=%d) Mode %dx%d@%d rejected\n",
+ if (area_limit > evdi->pixel_area_limit ||
+ mode_limit > evdi->pixel_per_second_limit) {
+ EVDI_WARN("(card%d) Mode %dx%d@%d rejected\n",
evdi->dev_index,
mode->hdisplay,
mode->vdisplay,
@@ -87,11 +92,11 @@
EVDI_CHECKPT();
if (evdi_painter_is_connected(evdi->painter)) {
- EVDI_DEBUG("(dev=%d) poll connector state: connected\n",
+ EVDI_INFO("(card%d) Connector state: connected\n",
evdi->dev_index);
return connector_status_connected;
}
- EVDI_DEBUG("(dev=%d) poll connector state: disconnected\n",
+ EVDI_VERBOSE("(card%d) Connector state: disconnected\n",
evdi->dev_index);
return connector_status_disconnected;
}
diff -Nru evdi-1.9.0+dfsg/module/evdi_cursor.c
evdi-1.12.0+dfsg/module/evdi_cursor.c
--- evdi-1.9.0+dfsg/module/evdi_cursor.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_cursor.c 2022-07-13 09:58:06.000000000
-0400
@@ -55,7 +55,7 @@
if (obj)
drm_gem_object_get(&obj->base);
if (cursor->obj)
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
drm_gem_object_put(&cursor->obj->base);
#else
drm_gem_object_put_unlocked(&cursor->obj->base);
@@ -232,8 +232,8 @@
bool const is_pix_sane =
mouse_pix_x >= 0 &&
mouse_pix_y >= 0 &&
- mouse_pix_x < fb->width &&
- mouse_pix_y < fb->height;
+ mouse_pix_x < (int)fb->width &&
+ mouse_pix_y < (int)fb->height;
if (!is_pix_sane)
continue;
diff -Nru evdi-1.9.0+dfsg/module/evdi_debug.c
evdi-1.12.0+dfsg/module/evdi_debug.c
--- evdi-1.9.0+dfsg/module/evdi_debug.c 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_debug.c 2022-07-13 09:58:06.000000000
-0400
@@ -10,7 +10,7 @@
#include "evdi_debug.h"
-void evdi_log_process(void)
+void evdi_log_process(char *buf, size_t size)
{
int task_pid = (int)task_pid_nr(current);
char task_comm[TASK_COMM_LEN] = { 0 };
@@ -21,13 +21,13 @@
char process_comm[TASK_COMM_LEN] = { 0 };
get_task_comm(process_comm, current->group_leader);
- EVDI_INFO("Task %d (%s) of process %d (%s)\n",
+ snprintf(buf, size, "Task %d (%s) of process %d (%s)",
task_pid,
task_comm,
(int)task_pid_nr(current->group_leader),
process_comm);
} else {
- EVDI_INFO("Task %d (%s)\n",
+ snprintf(buf, size, "Task %d (%s)",
task_pid,
task_comm);
}
diff -Nru evdi-1.9.0+dfsg/module/evdi_debug.h
evdi-1.12.0+dfsg/module/evdi_debug.h
--- evdi-1.9.0+dfsg/module/evdi_debug.h 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_debug.h 2022-07-13 09:58:06.000000000
-0400
@@ -11,7 +11,6 @@
#include "evdi_params.h"
-#define EVDI_LOGLEVEL_ALWAYS 0
#define EVDI_LOGLEVEL_FATAL 1
#define EVDI_LOGLEVEL_ERROR 2
#define EVDI_LOGLEVEL_WARN 3
@@ -53,6 +52,6 @@
#define EVDI_ENTER() EVDI_VERBOSE("enter\n")
#define EVDI_EXIT() EVDI_VERBOSE("exit\n")
-void evdi_log_process(void);
+void evdi_log_process(char *buf, size_t size);
#endif /* EVDI_DEBUG_H */
diff -Nru evdi-1.9.0+dfsg/module/evdi_drm_drv.c
evdi-1.12.0+dfsg/module/evdi_drm_drv.c
--- evdi-1.9.0+dfsg/module/evdi_drm_drv.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_drm_drv.c 2022-07-13 09:58:06.000000000
-0400
@@ -12,14 +12,22 @@
*/
#include <linux/version.h>
-#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_ioctl.h>
+#include <drm/drm_file.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_vblank.h>
+#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
#else
#include <drm/drmP.h>
#endif
#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE || defined(EL8)
#include <drm/drm_probe_helper.h>
#endif
-
+#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_managed.h>
+#endif
+#include <drm/drm_atomic_helper.h>
#include "evdi_drm_drv.h"
#include "evdi_platform_drv.h"
#include "evdi_cursor.h"
@@ -37,13 +45,18 @@
DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(EVDI_DDCCI_RESPONSE,
evdi_painter_ddcci_response_ioctl,
DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(EVDI_ENABLE_CURSOR_EVENTS,
evdi_painter_enable_cursor_events_ioctl,
+ DRM_UNLOCKED),
};
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
static const struct vm_operations_struct evdi_gem_vm_ops = {
.fault = evdi_gem_fault,
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
};
+#endif
static const struct file_operations evdi_driver_fops = {
.owner = THIS_MODULE,
@@ -53,12 +66,16 @@
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
.release = drm_release,
+
#ifdef CONFIG_COMPAT
.compat_ioctl = evdi_compat_ioctl,
#endif
+
.llseek = noop_llseek,
};
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
static int evdi_enable_vblank(__always_unused struct drm_device *dev,
__always_unused unsigned int pipe)
{
@@ -69,30 +86,39 @@
__always_unused unsigned int pipe)
{
}
+#endif
static struct drm_driver driver = {
-#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE || defined(EL8)
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
#else
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
| DRIVER_ATOMIC,
#endif
- .unload = evdi_driver_unload,
- .preclose = evdi_driver_preclose,
+ .unload = evdi_drm_device_unload,
+ .open = evdi_driver_open,
.postclose = evdi_driver_postclose,
/* gem hooks */
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#elif KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
.gem_free_object_unlocked = evdi_gem_free_object,
#else
.gem_free_object = evdi_gem_free_object,
#endif
+
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
.gem_vm_ops = &evdi_gem_vm_ops,
+#endif
.dumb_create = evdi_dumb_create,
.dumb_map_offset = evdi_gem_mmap,
+#if KERNEL_VERSION(5, 12, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
.dumb_destroy = drm_gem_dumb_destroy,
+#endif
.ioctls = evdi_painter_ioctls,
.num_ioctls = ARRAY_SIZE(evdi_painter_ioctls),
@@ -102,12 +128,15 @@
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
+ .preclose = evdi_driver_preclose,
.gem_prime_export = drm_gem_prime_export,
.gem_prime_get_sg_table = evdi_prime_get_sg_table,
- .gem_prime_import_sg_table = evdi_prime_import_sg_table,
-
.enable_vblank = evdi_enable_vblank,
.disable_vblank = evdi_disable_vblank,
+#endif
+ .gem_prime_import_sg_table = evdi_prime_import_sg_table,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -117,7 +146,15 @@
.patchlevel = DRIVER_PATCH,
};
-static int evdi_driver_setup(struct drm_device *dev)
+#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE
+static void evdi_drm_device_release_cb(__always_unused struct drm_device *dev,
+ __always_unused void *ptr)
+{
+ EVDI_INFO("Evdi drm_device removed.\n");
+}
+#endif
+
+static int evdi_drm_device_setup(struct drm_device *dev)
{
struct evdi_device *evdi;
int ret;
@@ -129,19 +166,12 @@
evdi->ddev = dev;
dev->dev_private = evdi;
+ evdi->dev_index = dev->primary->index;
+ evdi->cursor_events_enabled = false;
ret = evdi_cursor_init(&evdi->cursor);
if (ret)
- goto err;
-
- evdi->cursor_attr = (struct dev_ext_attribute) {
- __ATTR(cursor_events, 0644, device_show_bool, device_store_bool),
- &evdi->cursor_events_enabled
- };
- ret = device_create_file(dev->dev, &evdi->cursor_attr.attr);
- if (ret)
- goto err_fb;
-
+ goto err_free;
EVDI_CHECKPT();
evdi_modeset_init(dev);
@@ -149,7 +179,7 @@
#ifdef CONFIG_FB
ret = evdi_fbdev_init(dev);
if (ret)
- goto err;
+ goto err_cursor;
#endif /* CONFIG_FB */
ret = drm_vblank_init(dev, 1);
@@ -162,21 +192,26 @@
drm_kms_helper_poll_init(dev);
+#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE
+ ret = drmm_add_action_or_reset(dev, evdi_drm_device_release_cb, NULL);
+ if (ret)
+ goto err_fb;
+#endif
return 0;
err_fb:
#ifdef CONFIG_FB
evdi_fbdev_cleanup(dev);
+err_cursor:
#endif /* CONFIG_FB */
-err:
- EVDI_ERROR("%d\n", ret);
- if (evdi->cursor)
- evdi_cursor_free(evdi->cursor);
+ evdi_cursor_free(evdi->cursor);
+err_free:
+ EVDI_ERROR("Failed to setup drm device %d\n", ret);
kfree(evdi);
return ret;
}
-void evdi_driver_unload(struct drm_device *dev)
+void evdi_drm_device_unload(struct drm_device *dev)
{
struct evdi_device *evdi = dev->dev_private;
@@ -190,7 +225,6 @@
if (evdi->cursor)
evdi_cursor_free(evdi->cursor);
- device_remove_file(dev->dev, &evdi->cursor_attr.attr);
evdi_painter_cleanup(evdi->painter);
#ifdef CONFIG_FB
evdi_fbdev_cleanup(dev);
@@ -200,6 +234,16 @@
kfree(evdi);
}
+int evdi_driver_open(struct drm_device *drm_dev, __always_unused struct
drm_file *file)
+{
+ struct evdi_device *evdi = drm_dev->dev_private;
+ char buf[100];
+
+ evdi_log_process(buf, sizeof(buf));
+ EVDI_INFO("(card%d) Opened by %s\n", evdi->dev_index, buf);
+ return 0;
+}
+
static void evdi_driver_close(struct drm_device *drm_dev, struct drm_file
*file)
{
struct evdi_device *evdi = drm_dev->dev_private;
@@ -217,10 +261,11 @@
void evdi_driver_postclose(struct drm_device *drm_dev, struct drm_file *file)
{
struct evdi_device *evdi = drm_dev->dev_private;
+ char buf[100];
- EVDI_DEBUG("(dev=%d) Process tries to close us, postclose\n",
- evdi ? evdi->dev_index : -1);
- evdi_log_process();
+ evdi_log_process(buf, sizeof(buf));
+ EVDI_INFO("(card%d) Closed by %s\n",
+ evdi->dev_index, buf);
evdi_driver_close(drm_dev, file);
}
@@ -234,7 +279,7 @@
if (IS_ERR(dev))
return dev;
- ret = evdi_driver_setup(dev);
+ ret = evdi_drm_device_setup(dev);
if (ret)
goto err_free;
@@ -252,6 +297,8 @@
int evdi_drm_device_remove(struct drm_device *dev)
{
drm_dev_unplug(dev);
+ drm_atomic_helper_shutdown(dev);
+ drm_dev_put(dev);
return 0;
}
diff -Nru evdi-1.9.0+dfsg/module/evdi_drm_drv.h
evdi-1.12.0+dfsg/module/evdi_drm_drv.h
--- evdi-1.9.0+dfsg/module/evdi_drm_drv.h 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_drm_drv.h 2022-07-13 09:58:06.000000000
-0400
@@ -15,16 +15,21 @@
#include <linux/module.h>
#include <linux/version.h>
+#include <linux/mutex.h>
#include <linux/device.h>
#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
#include <drm/drm_drv.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_ioctl.h>
-#include <drm/drm_irq.h>
#include <drm/drm_vblank.h>
#else
#include <drm/drmP.h>
#endif
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_legacy.h>
+#else
+#include <drm/drm_irq.h>
+#endif
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_rect.h>
@@ -44,10 +49,10 @@
struct drm_device *ddev;
struct drm_connector *conn;
struct evdi_cursor *cursor;
- struct dev_ext_attribute cursor_attr;
bool cursor_events_enabled;
- uint32_t sku_area_limit;
+ uint32_t pixel_area_limit;
+ uint32_t pixel_per_second_limit;
struct evdi_fbdev *fbdev;
struct evdi_painter *painter;
@@ -59,7 +64,12 @@
struct evdi_gem_object {
struct drm_gem_object base;
struct page **pages;
+ unsigned int pages_pin_count;
+ struct mutex pages_lock;
void *vmapping;
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ bool vmap_is_iomem;
+#endif
struct sg_table *sg;
#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE || defined(EL8)
struct dma_resv *resv;
@@ -68,6 +78,7 @@
struct reservation_object *resv;
struct reservation_object _resv;
#endif
+ bool allow_sw_cursor_rect_updates;
};
#define to_evdi_bo(x) container_of(x, struct evdi_gem_object, base)
@@ -87,8 +98,8 @@
struct drm_encoder *evdi_encoder_init(struct drm_device *dev);
-int evdi_driver_load(struct drm_device *dev, unsigned long flags);
-void evdi_driver_unload(struct drm_device *dev);
+void evdi_drm_device_unload(struct drm_device *dev);
+int evdi_driver_open(struct drm_device *drm_dev, struct drm_file *file);
void evdi_driver_preclose(struct drm_device *dev, struct drm_file *file_priv);
void evdi_driver_postclose(struct drm_device *dev, struct drm_file *file_priv);
@@ -96,6 +107,7 @@
long evdi_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
#endif
+
#ifdef CONFIG_FB
int evdi_fbdev_init(struct drm_device *dev);
void evdi_fbdev_cleanup(struct drm_device *dev);
@@ -146,7 +158,6 @@
void evdi_painter_dpms_notify(struct evdi_device *evdi, int mode);
void evdi_painter_mode_changed_notify(struct evdi_device *evdi,
struct drm_display_mode *mode);
-void evdi_painter_crtc_state_notify(struct evdi_device *evdi, int state);
unsigned int evdi_painter_poll(struct file *filp,
struct poll_table_struct *wait);
@@ -160,6 +171,8 @@
struct drm_file *file);
int evdi_painter_ddcci_response_ioctl(struct drm_device *drm_dev, void *data,
struct drm_file *file);
+int evdi_painter_enable_cursor_events_ioctl(struct drm_device *drm_dev, void
*data,
+ struct drm_file *file);
int evdi_painter_init(struct evdi_device *evdi);
void evdi_painter_cleanup(struct evdi_painter *painter);
diff -Nru evdi-1.9.0+dfsg/module/evdi_drm.h evdi-1.12.0+dfsg/module/evdi_drm.h
--- evdi-1.9.0+dfsg/module/evdi_drm.h 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_drm.h 2022-07-13 09:58:06.000000000 -0400
@@ -47,7 +47,8 @@
int32_t dev_index;
const unsigned char * __user edid;
uint32_t edid_length;
- uint32_t sku_area_limit;
+ uint32_t pixel_area_limit;
+ uint32_t pixel_per_second_limit;
};
struct drm_evdi_request_update {
@@ -94,6 +95,11 @@
uint8_t result;
};
+struct drm_evdi_enable_cursor_events {
+ struct drm_event base;
+ uint8_t enable;
+};
+
#define DDCCI_BUFFER_SIZE 64
struct drm_evdi_event_ddcci_data {
@@ -109,6 +115,7 @@
#define DRM_EVDI_REQUEST_UPDATE 0x01
#define DRM_EVDI_GRABPIX 0x02
#define DRM_EVDI_DDCCI_RESPONSE 0x03
+#define DRM_EVDI_ENABLE_CURSOR_EVENTS 0x04
/* LAST_IOCTL 0x5F -- 96 driver specific ioctls to use */
#define DRM_IOCTL_EVDI_CONNECT DRM_IOWR(DRM_COMMAND_BASE + \
@@ -119,5 +126,7 @@
DRM_EVDI_GRABPIX, struct drm_evdi_grabpix)
#define DRM_IOCTL_EVDI_DDCCI_RESPONSE DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EVDI_DDCCI_RESPONSE, struct drm_evdi_ddcci_response)
+#define DRM_IOCTL_EVDI_ENABLE_CURSOR_EVENTS DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_EVDI_ENABLE_CURSOR_EVENTS, struct drm_evdi_enable_cursor_events)
#endif /* __EVDI_UAPI_DRM_H__ */
diff -Nru evdi-1.9.0+dfsg/module/evdi_fb.c evdi-1.12.0+dfsg/module/evdi_fb.c
--- evdi-1.9.0+dfsg/module/evdi_fb.c 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_fb.c 2022-07-13 09:58:06.000000000 -0400
@@ -25,7 +25,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_atomic.h>
-#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
#include <drm/drm_damage_helper.h>
#endif
#include "evdi_drm_drv.h"
@@ -63,28 +63,29 @@
if (rect.x1 > fb->base.width) {
- EVDI_WARN("Wrong clip rect: x1 > fb.width\n");
+ EVDI_DEBUG("Wrong clip rect: x1 > fb.width\n");
rect.x1 = fb->base.width;
}
if (rect.y1 > fb->base.height) {
- EVDI_WARN("Wrong clip rect: y1 > fb.height\n");
+ EVDI_DEBUG("Wrong clip rect: y1 > fb.height\n");
rect.y1 = fb->base.height;
}
if (rect.x2 > fb->base.width) {
- EVDI_WARN("Wrong clip rect: x2 > fb.width\n");
+ EVDI_DEBUG("Wrong clip rect: x2 > fb.width\n");
rect.x2 = fb->base.width;
}
if (rect.y2 > fb->base.height) {
- EVDI_WARN("Wrong clip rect: y2 > fb.height\n");
+ EVDI_DEBUG("Wrong clip rect: y2 > fb.height\n");
rect.y2 = fb->base.height;
}
return rect;
}
+#ifdef CONFIG_FB
static int evdi_handle_damage(struct evdi_framebuffer *fb,
int x, int y, int width, int height)
{
@@ -104,7 +105,6 @@
return 0;
}
-#ifdef CONFIG_FB
static int evdi_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
unsigned long start = vma->vm_start;
@@ -221,7 +221,7 @@
};
#endif /* CONFIG_FB */
-#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
#else
/*
* Function taken from
@@ -243,7 +243,7 @@
struct drm_atomic_state *state;
struct drm_plane *plane;
int ret = 0;
- int i;
+ unsigned int i;
EVDI_CHECKPT();
@@ -319,7 +319,7 @@
EVDI_CHECKPT();
if (efb->obj)
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
drm_gem_object_put(&efb->obj->base);
#else
drm_gem_object_put_unlocked(&efb->obj->base);
@@ -331,7 +331,7 @@
static const struct drm_framebuffer_funcs evdifb_funcs = {
.create_handle = evdi_user_framebuffer_create_handle,
.destroy = evdi_user_framebuffer_destroy,
-#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
.dirty = drm_atomic_helper_dirtyfb,
#else
.dirty = evdi_user_framebuffer_dirty,
@@ -441,7 +441,7 @@
return ret;
out_gfree:
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
drm_gem_object_put(&efbdev->efb.obj->base);
#else
drm_gem_object_put_unlocked(&efbdev->efb.obj->base);
@@ -471,7 +471,7 @@
if (efbdev->efb.obj) {
drm_framebuffer_unregister_private(&efbdev->efb.base);
drm_framebuffer_cleanup(&efbdev->efb.base);
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
drm_gem_object_put(&efbdev->efb.obj->base);
#else
drm_gem_object_put_unlocked(&efbdev->efb.obj->base);
@@ -493,7 +493,7 @@
evdi->fbdev = efbdev;
drm_fb_helper_prepare(dev, &efbdev->helper, &evdi_fb_helper_funcs);
-#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE || defined(EL8)
ret = drm_fb_helper_init(dev, &efbdev->helper);
#else
ret = drm_fb_helper_init(dev, &efbdev->helper, 1);
@@ -503,7 +503,7 @@
return ret;
}
-#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE || defined(EL8)
#else
drm_fb_helper_single_add_all_connectors(&efbdev->helper);
#endif
@@ -541,7 +541,7 @@
struct fb_info *info;
info = efbdev->helper.fbdev;
-#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE || defined(EL8)
unregister_framebuffer(info);
#else
unlink_framebuffer(info);
diff -Nru evdi-1.9.0+dfsg/module/evdi_gem.c evdi-1.12.0+dfsg/module/evdi_gem.c
--- evdi-1.9.0+dfsg/module/evdi_gem.c 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_gem.c 2022-07-13 09:58:06.000000000 -0400
@@ -8,16 +8,66 @@
* more details.
*/
+#include <linux/sched.h>
#include <linux/version.h>
-#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#if KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE
+#elif KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE
+#include <linux/dma-buf-map.h>
+#endif
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_prime.h>
+#include <drm/drm_file.h>
+#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
#else
#include <drm/drmP.h>
#endif
#include "evdi_drm_drv.h"
+#include "evdi_params.h"
#include <linux/shmem_fs.h>
#include <linux/dma-buf.h>
#include <drm/drm_cache.h>
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+MODULE_IMPORT_NS(DMA_BUF);
+#endif
+
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+static int evdi_prime_pin(struct drm_gem_object *obj);
+static void evdi_prime_unpin(struct drm_gem_object *obj);
+
+static const struct vm_operations_struct evdi_gem_vm_ops = {
+ .fault = evdi_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+};
+
+static struct drm_gem_object_funcs gem_obj_funcs = {
+ .free = evdi_gem_free_object,
+ .pin = evdi_prime_pin,
+ .unpin = evdi_prime_unpin,
+ .vm_ops = &evdi_gem_vm_ops,
+ .export = drm_gem_prime_export,
+ .get_sg_table = evdi_prime_get_sg_table,
+};
+#endif
+
+static bool evdi_was_called_by_mutter(void)
+{
+ char task_comm[TASK_COMM_LEN] = { 0 };
+
+ get_task_comm(task_comm, current);
+
+ return strcmp(task_comm, "gnome-shell") == 0;
+}
+
+static bool evdi_drm_gem_object_use_import_attach(struct drm_gem_object *obj)
+{
+ if (!obj || !obj->import_attach)
+ return false;
+
+ return obj->import_attach &&
strcmp(obj->import_attach->dmabuf->owner->name, "amdgpu") != 0;
+}
+
uint32_t evdi_gem_object_handle_lookup(struct drm_file *filp,
struct drm_gem_object *obj)
{
@@ -58,6 +108,14 @@
#endif
obj->resv = &obj->_resv;
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ obj->base.funcs = &gem_obj_funcs;
+#endif
+
+ obj->allow_sw_cursor_rect_updates = false;
+
+ mutex_init(&obj->pages_lock);
+
return obj;
}
@@ -81,11 +139,12 @@
kfree(obj);
return ret;
}
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
drm_gem_object_put(&obj->base);
#else
drm_gem_object_put_unlocked(&obj->base);
#endif
+ obj->allow_sw_cursor_rect_updates = evdi_was_called_by_mutter();
*handle_p = handle;
return 0;
}
@@ -186,7 +245,7 @@
obj->pages = pages;
#if defined(CONFIG_X86)
- drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE);
+ drm_clflush_pages(obj->pages, DIV_ROUND_UP(obj->base.size, PAGE_SIZE));
#endif
return 0;
@@ -204,19 +263,55 @@
obj->pages = NULL;
}
+static int evdi_pin_pages(struct evdi_gem_object *obj)
+{
+ int ret = 0;
+
+ mutex_lock(&obj->pages_lock);
+ if (obj->pages_pin_count++ == 0) {
+ ret = evdi_gem_get_pages(obj, GFP_KERNEL);
+ if (ret)
+ obj->pages_pin_count--;
+ }
+ mutex_unlock(&obj->pages_lock);
+ return ret;
+}
+
+static void evdi_unpin_pages(struct evdi_gem_object *obj)
+{
+ mutex_lock(&obj->pages_lock);
+ if (--obj->pages_pin_count == 0)
+ evdi_gem_put_pages(obj);
+ mutex_unlock(&obj->pages_lock);
+}
+
int evdi_gem_vmap(struct evdi_gem_object *obj)
{
- int page_count = obj->base.size / PAGE_SIZE;
+ int page_count = DIV_ROUND_UP(obj->base.size, PAGE_SIZE);
int ret;
- if (obj->base.import_attach) {
+ if (evdi_drm_gem_object_use_import_attach(&obj->base)) {
+#if KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE
+ struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL);
+#elif KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(NULL);
+#endif
+
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ ret = dma_buf_vmap(obj->base.import_attach->dmabuf, &map);
+ if (ret)
+ return -ENOMEM;
+ obj->vmapping = map.vaddr;
+ obj->vmap_is_iomem = map.is_iomem;
+#else
obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
if (!obj->vmapping)
return -ENOMEM;
+#endif
return 0;
}
- ret = evdi_gem_get_pages(obj, GFP_KERNEL);
+ ret = evdi_pin_pages(obj);
if (ret)
return ret;
@@ -228,8 +323,29 @@
void evdi_gem_vunmap(struct evdi_gem_object *obj)
{
- if (obj->base.import_attach) {
+ if (evdi_drm_gem_object_use_import_attach(&obj->base)) {
+#if KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE
+ struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL);
+
+ if (obj->vmap_is_iomem)
+ iosys_map_set_vaddr_iomem(&map, obj->vmapping);
+ else
+ iosys_map_set_vaddr(&map, obj->vmapping);
+
+ dma_buf_vunmap(obj->base.import_attach->dmabuf, &map);
+
+#elif KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ struct dma_buf_map map;
+
+ if (obj->vmap_is_iomem)
+ dma_buf_map_set_vaddr_iomem(&map, obj->vmapping);
+ else
+ dma_buf_map_set_vaddr(&map, obj->vmapping);
+
+ dma_buf_vunmap(obj->base.import_attach->dmabuf, &map);
+#else
dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping);
+#endif
obj->vmapping = NULL;
return;
}
@@ -239,7 +355,7 @@
obj->vmapping = NULL;
}
- evdi_gem_put_pages(obj);
+ evdi_unpin_pages(obj);
}
void evdi_gem_free_object(struct drm_gem_object *gem_obj)
@@ -263,6 +379,7 @@
reservation_object_fini(&obj->_resv);
#endif
obj->resv = NULL;
+ mutex_destroy(&obj->pages_lock);
}
/*
@@ -284,7 +401,7 @@
}
gobj = to_evdi_bo(obj);
- ret = evdi_gem_get_pages(gobj, GFP_KERNEL);
+ ret = evdi_pin_pages(gobj);
if (ret)
goto out;
@@ -308,12 +425,15 @@
{
struct evdi_gem_object *obj;
int npages;
+ bool called_by_mutter;
+
+ called_by_mutter = evdi_was_called_by_mutter();
obj = evdi_gem_alloc_object(dev, attach->dmabuf->size);
if (IS_ERR(obj))
return ERR_CAST(obj);
- npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE;
+ npages = DIV_ROUND_UP(attach->dmabuf->size, PAGE_SIZE);
DRM_DEBUG_PRIME("Importing %d pages\n", npages);
obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
if (!obj->pages) {
@@ -321,15 +441,36 @@
return ERR_PTR(-ENOMEM);
}
+#if KERNEL_VERSION(5, 12, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ drm_prime_sg_to_page_array(sg, obj->pages, npages);
+#else
drm_prime_sg_to_page_addr_arrays(sg, obj->pages, NULL, npages);
+#endif
obj->sg = sg;
+ obj->allow_sw_cursor_rect_updates = called_by_mutter;
return &obj->base;
}
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8)
+static int evdi_prime_pin(struct drm_gem_object *obj)
+{
+ struct evdi_gem_object *bo = to_evdi_bo(obj);
+
+ return evdi_pin_pages(bo);
+}
+
+static void evdi_prime_unpin(struct drm_gem_object *obj)
+{
+ struct evdi_gem_object *bo = to_evdi_bo(obj);
+
+ evdi_unpin_pages(bo);
+}
+#endif
+
struct sg_table *evdi_prime_get_sg_table(struct drm_gem_object *obj)
{
struct evdi_gem_object *bo = to_evdi_bo(obj);
- #if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE
+ #if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8)
return drm_prime_pages_to_sg(obj->dev, bo->pages, bo->base.size
>> PAGE_SHIFT);
#else
return drm_prime_pages_to_sg(bo->pages, bo->base.size >>
PAGE_SHIFT);
diff -Nru evdi-1.9.0+dfsg/module/evdi_ioc32.c
evdi-1.12.0+dfsg/module/evdi_ioc32.c
--- evdi-1.9.0+dfsg/module/evdi_ioc32.c 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_ioc32.c 2022-07-13 09:58:06.000000000
-0400
@@ -22,7 +22,9 @@
#include <linux/compat.h>
#include <linux/version.h>
-#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_ioctl.h>
+#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
#else
#include <drm/drmP.h>
#endif
@@ -36,7 +38,8 @@
int32_t dev_index;
uint32_t edid_ptr32;
uint32_t edid_length;
- uint32_t sku_area_limit;
+ uint32_t pixel_area_limit;
+ uint32_t pixel_per_second_limit;
};
struct drm_evdi_grabpix32 {
@@ -59,7 +62,11 @@
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE && KERNEL_VERSION(5, 14, 0)
>= LINUX_VERSION_CODE || defined(EL8)
request = compat_alloc_user_space(sizeof(*request));
+#else
+ request = kmalloc(sizeof(*request), GFP_USER);
+#endif
#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
if (!access_ok(request, sizeof(*request))
#else
@@ -70,7 +77,8 @@
|| __put_user((void __user *)(unsigned long)req32.edid_ptr32,
&request->edid)
|| __put_user(req32.edid_length, &request->edid_length)
- || __put_user(req32.sku_area_limit, &request->sku_area_limit))
+ || __put_user(req32.pixel_area_limit,
&request->pixel_area_limit)
+ || __put_user(req32.pixel_per_second_limit,
&request->pixel_per_second_limit))
return -EFAULT;
return drm_ioctl(file, DRM_IOCTL_EVDI_CONNECT,
@@ -87,7 +95,11 @@
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
return -EFAULT;
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE && KERNEL_VERSION(5, 14, 0)
>= LINUX_VERSION_CODE || defined(EL8)
request = compat_alloc_user_space(sizeof(*request));
+#else
+ request = kmalloc(sizeof(*request), GFP_USER);
+#endif
#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
if (!access_ok(request, sizeof(*request))
#else
diff -Nru evdi-1.9.0+dfsg/module/evdi_modeset.c
evdi-1.12.0+dfsg/module/evdi_modeset.c
--- evdi-1.9.0+dfsg/module/evdi_modeset.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_modeset.c 2022-07-13 09:58:06.000000000
-0400
@@ -12,7 +12,11 @@
*/
#include <linux/version.h>
-#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_vblank.h>
+#include <drm/drm_damage_helper.h>
+#elif KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#include <drm/drm_damage_helper.h>
#else
#include <drm/drmP.h>
#endif
@@ -25,7 +29,11 @@
#include "evdi_drm_drv.h"
#include "evdi_cursor.h"
#include "evdi_params.h"
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_gem_atomic_helper.h>
+#else
#include <drm/drm_gem_framebuffer_helper.h>
+#endif
static void evdi_crtc_dpms(__always_unused struct drm_crtc *crtc,
__always_unused int mode)
@@ -36,6 +44,7 @@
static void evdi_crtc_disable(__always_unused struct drm_crtc *crtc)
{
EVDI_CHECKPT();
+ drm_crtc_vblank_off(crtc);
}
static void evdi_crtc_destroy(struct drm_crtc *crtc)
@@ -56,25 +65,37 @@
static void evdi_crtc_atomic_flush(
struct drm_crtc *crtc
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) ||
defined(EL8)
+ , struct drm_atomic_state *state
+#else
, __always_unused struct drm_crtc_state *old_state
+#endif
)
{
- struct drm_crtc_state *state = crtc->state;
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) ||
defined(EL8)
+ struct drm_crtc_state *crtc_state =
drm_atomic_get_new_crtc_state(state, crtc);
+#else
+ struct drm_crtc_state *crtc_state = crtc->state;
+#endif
struct evdi_device *evdi = crtc->dev->dev_private;
+ bool notify_mode_changed = crtc_state->active &&
+ (crtc_state->mode_changed ||
evdi_painter_needs_full_modeset(evdi->painter));
+ bool notify_dpms = crtc_state->active_changed ||
evdi_painter_needs_full_modeset(evdi->painter);
+ if (notify_mode_changed)
+ evdi_painter_mode_changed_notify(evdi,
&crtc_state->adjusted_mode);
- if (state->mode_changed && state->active)
- evdi_painter_mode_changed_notify(evdi, &state->adjusted_mode);
-
- if (state->active_changed)
+ if (notify_dpms)
evdi_painter_dpms_notify(evdi,
- state->active ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF);
+ crtc_state->active ? DRM_MODE_DPMS_ON :
DRM_MODE_DPMS_OFF);
- evdi_painter_set_vblank(evdi->painter, crtc, state->event);
+ evdi_painter_set_vblank(evdi->painter, crtc, crtc_state->event);
evdi_painter_send_update_ready_if_needed(evdi->painter);
- state->event = NULL;
+ crtc_state->event = NULL;
}
+#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
static void evdi_mark_full_screen_dirty(struct evdi_device *evdi)
{
const struct drm_clip_rect rect =
@@ -125,7 +146,7 @@
evdi_cursor_set(evdi->cursor,
eobj, width, height, hot_x, hot_y,
format, stride);
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
drm_gem_object_put(obj);
#else
drm_gem_object_put_unlocked(obj);
@@ -157,6 +178,7 @@
return 0;
}
+#endif
static struct drm_crtc_helper_funcs evdi_helper_funcs = {
.mode_set_nofb = evdi_crtc_set_nofb,
@@ -167,6 +189,17 @@
.disable = evdi_crtc_disable
};
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) ||
defined(EL8)
+static int evdi_enable_vblank(__always_unused struct drm_crtc *crtc)
+{
+ return 1;
+}
+
+static void evdi_disable_vblank(__always_unused struct drm_crtc *crtc)
+{
+}
+#endif
+
static const struct drm_crtc_funcs evdi_crtc_funcs = {
.reset = drm_atomic_helper_crtc_reset,
.destroy = evdi_crtc_destroy,
@@ -175,18 +208,40 @@
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#else
.cursor_set2 = evdi_crtc_cursor_set,
- .cursor_move = evdi_crtc_cursor_move
+ .cursor_move = evdi_crtc_cursor_move,
+#endif
+#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) ||
defined(EL8)
+ .enable_vblank = evdi_enable_vblank,
+ .disable_vblank = evdi_disable_vblank,
+#endif
};
static void evdi_plane_atomic_update(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+ struct drm_atomic_state *atom_state
+#else
+ struct drm_plane_state *old_state
+#endif
+ )
{
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+ struct drm_plane_state *old_state =
drm_atomic_get_old_plane_state(atom_state, plane);
+#else
+#endif
struct drm_plane_state *state;
struct evdi_device *evdi;
struct evdi_painter *painter;
struct drm_crtc *crtc;
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ struct drm_atomic_helper_damage_iter iter;
+ struct drm_rect rect;
+ struct drm_clip_rect clip_rect;
+#endif
+
if (!plane || !plane->state) {
EVDI_WARN("Plane state is null\n");
return;
@@ -228,10 +283,28 @@
evdi_painter_needs_full_modeset(painter)) {
evdi_painter_set_scanout_buffer(painter, efb);
+
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ state->visible = true;
+ state->src.x1 = 0;
+ state->src.y1 = 0;
+ state->src.x2 = fb->width << 16;
+ state->src.y2 = fb->height << 16;
+
+ drm_atomic_helper_damage_iter_init(&iter, old_state,
state);
+ while (drm_atomic_helper_damage_iter_next(&iter,
&rect)) {
+ clip_rect.x1 = rect.x1;
+ clip_rect.y1 = rect.y1;
+ clip_rect.x2 = rect.x2;
+ clip_rect.y2 = rect.y2;
+ evdi_painter_mark_dirty(evdi, &clip_rect);
+ }
+#endif
+
+ };
+
+ if (evdi_painter_get_num_dirts(painter) == 0)
evdi_painter_mark_dirty(evdi, &fullscreen_rect);
- } else if (evdi_painter_get_num_dirts(painter) == 0) {
- evdi_painter_mark_dirty(evdi, &fullscreen_rect);
- }
}
}
@@ -245,8 +318,17 @@
}
static void evdi_cursor_atomic_update(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+ struct drm_atomic_state *atom_state
+#else
+ struct drm_plane_state *old_state
+#endif
+ )
{
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+ struct drm_plane_state *old_state =
drm_atomic_get_old_plane_state(atom_state, plane);
+#else
+#endif
if (plane && plane->state && plane->dev && plane->dev->dev_private) {
struct drm_plane_state *state = plane->state;
struct evdi_device *evdi = plane->dev->dev_private;
@@ -288,13 +370,20 @@
mutex_unlock(&plane->dev->struct_mutex);
if (!evdi->cursor_events_enabled) {
- evdi_cursor_atomic_get_rect(&old_rect, old_state);
- evdi_cursor_atomic_get_rect(&rect, state);
-
- evdi_painter_mark_dirty(evdi, &old_rect);
- evdi_painter_mark_dirty(evdi, &rect);
+ if (fb != NULL) {
+ if (efb->obj->allow_sw_cursor_rect_updates) {
+ evdi_cursor_atomic_get_rect(&old_rect,
old_state);
+ evdi_cursor_atomic_get_rect(&rect,
state);
+
+ evdi_painter_mark_dirty(evdi,
&old_rect);
+ } else {
+ rect =
evdi_painter_framebuffer_size(evdi->painter);
+ }
+ evdi_painter_mark_dirty(evdi, &rect);
+ }
return;
}
+
if (cursor_changed)
evdi_painter_send_cursor_set(evdi->painter,
evdi->cursor);
@@ -306,12 +395,20 @@
static const struct drm_plane_helper_funcs evdi_plane_helper_funcs = {
.atomic_update = evdi_plane_atomic_update,
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+ .prepare_fb = drm_gem_plane_helper_prepare_fb
+#else
.prepare_fb = drm_gem_fb_prepare_fb
+#endif
};
static const struct drm_plane_helper_funcs evdi_cursor_helper_funcs = {
.atomic_update = evdi_cursor_atomic_update,
+#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE
+ .prepare_fb = drm_gem_plane_helper_prepare_fb
+#else
.prepare_fb = drm_gem_fb_prepare_fb
+#endif
};
static const struct drm_plane_funcs evdi_plane_funcs = {
@@ -337,10 +434,11 @@
{
struct drm_plane *plane;
int ret;
+ char *plane_type = (type == DRM_PLANE_TYPE_CURSOR) ? "cursor" :
"primary";
plane = kzalloc(sizeof(*plane), GFP_KERNEL);
if (plane == NULL) {
- EVDI_ERROR("Failed to allocate primary plane\n");
+ EVDI_ERROR("Failed to allocate %s plane\n", plane_type);
return NULL;
}
plane->format_default = true;
@@ -357,7 +455,7 @@
);
if (ret) {
- EVDI_ERROR("Failed to initialize primary plane\n");
+ EVDI_ERROR("Failed to initialize %s plane\n", plane_type);
kfree(plane);
return NULL;
}
@@ -381,6 +479,16 @@
primary_plane = evdi_create_plane(dev, DRM_PLANE_TYPE_PRIMARY,
&evdi_plane_helper_funcs);
+
+#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ cursor_plane = evdi_create_plane(dev, DRM_PLANE_TYPE_CURSOR,
+ &evdi_cursor_helper_funcs);
+#endif
+
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ drm_plane_enable_fb_damage_clips(primary_plane);
+#endif
+
status = drm_crtc_init_with_planes(dev, crtc,
primary_plane, cursor_plane,
&evdi_crtc_funcs,
@@ -393,29 +501,11 @@
return 0;
}
-static int evdi_atomic_check(struct drm_device *dev,
- struct drm_atomic_state *state)
-{
- struct drm_crtc *crtc;
- struct drm_crtc_state *crtc_state;
- int i;
- struct evdi_device *evdi = dev->dev_private;
-
- if (evdi_painter_needs_full_modeset(evdi->painter)) {
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- crtc_state->active_changed = true;
- crtc_state->mode_changed = true;
- }
- }
-
- return drm_atomic_helper_check(dev, state);
-}
-
static const struct drm_mode_config_funcs evdi_mode_funcs = {
.fb_create = evdi_fb_user_fb_create,
.output_poll_changed = NULL,
.atomic_commit = drm_atomic_helper_commit,
- .atomic_check = evdi_atomic_check
+ .atomic_check = drm_atomic_helper_check
};
void evdi_modeset_init(struct drm_device *dev)
@@ -429,8 +519,8 @@
dev->mode_config.min_width = 64;
dev->mode_config.min_height = 64;
- dev->mode_config.max_width = 3840;
- dev->mode_config.max_height = 2160;
+ dev->mode_config.max_width = 7680;
+ dev->mode_config.max_height = 4320;
dev->mode_config.prefer_shadow = 0;
dev->mode_config.preferred_depth = 24;
@@ -446,8 +536,10 @@
drm_mode_config_reset(dev);
}
-void evdi_modeset_cleanup(struct drm_device *dev)
+void evdi_modeset_cleanup(__maybe_unused struct drm_device *dev)
{
- EVDI_CHECKPT();
+#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE
+#else
drm_mode_config_cleanup(dev);
+#endif
}
diff -Nru evdi-1.9.0+dfsg/module/evdi_painter.c
evdi-1.12.0+dfsg/module/evdi_painter.c
--- evdi-1.9.0+dfsg/module/evdi_painter.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_painter.c 2022-07-13 09:58:06.000000000
-0400
@@ -10,7 +10,11 @@
#include "linux/thread_info.h"
#include "linux/mm.h"
#include <linux/version.h>
-#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+#include <drm/drm_file.h>
+#include <drm/drm_vblank.h>
+#include <drm/drm_ioctl.h>
+#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8)
#else
#include <drm/drmP.h>
#endif
@@ -27,6 +31,10 @@
#include <linux/dma-buf.h>
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+MODULE_IMPORT_NS(DMA_BUF);
+#endif
+
#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE || defined(EL8)
#include <drm/drm_probe_helper.h>
#endif
@@ -239,7 +247,6 @@
memcpy(block,
evdi->painter->edid,
evdi->painter->edid_length);
- EVDI_DEBUG("(dev=%d) EDID valid\n", evdi->dev_index);
}
}
painter_unlock(evdi->painter);
@@ -318,7 +325,7 @@
}
if (!painter->drm_filp) {
- EVDI_WARN("Painter is not connected!");
+ EVDI_VERBOSE("Painter is not connected!");
drm_event_cancel_free(painter->drm_device, event);
return;
}
@@ -496,31 +503,6 @@
evdi_painter_send_event(painter, event);
}
-static struct drm_pending_event *create_crtc_state_event(int state)
-{
- struct evdi_event_crtc_state_pending *event;
-
- event = kzalloc(sizeof(*event), GFP_KERNEL);
- if (!event) {
- EVDI_ERROR("Failed to create crtc state event");
- return NULL;
- }
-
- event->crtc_state.base.type = DRM_EVDI_EVENT_CRTC_STATE;
- event->crtc_state.base.length = sizeof(event->crtc_state);
- event->crtc_state.state = state;
- event->base.event = &event->crtc_state.base;
- return &event->base;
-}
-
-static void evdi_painter_send_crtc_state(struct evdi_painter *painter,
- int state)
-{
- struct drm_pending_event *event = create_crtc_state_event(state);
-
- evdi_painter_send_event(painter, event);
-}
-
static struct drm_pending_event *create_mode_changed_event(
struct drm_display_mode *current_mode,
int32_t bits_per_pixel,
@@ -591,7 +573,8 @@
painter_lock(painter);
efb = painter->scanout_fb;
if (!efb) {
- EVDI_DEBUG("Scanout buffer not set.");
+ if (painter->is_connected)
+ EVDI_WARN("Scanout buffer not set.");
goto unlock;
}
rect.x1 = 0;
@@ -618,14 +601,15 @@
painter_lock(painter);
efb = painter->scanout_fb;
if (!efb) {
- EVDI_DEBUG("(dev=%d) Skip clip rect. Scanout buffer not set.\n",
+ if (painter->is_connected)
+ EVDI_WARN("(card%d) Skip clip rect. Scanout buffer not
set.\n",
evdi->dev_index);
goto unlock;
}
rect = evdi_framebuffer_sanitize_rect(efb, dirty_rect);
- EVDI_VERBOSE("(dev=%d) %d,%d-%d,%d\n", evdi->dev_index, rect.x1,
+ EVDI_VERBOSE("(card%d) %d,%d-%d,%d\n", evdi->dev_index, rect.x1,
rect.y1, rect.x2, rect.y2);
if (painter->num_dirts == MAX_DIRTS)
@@ -695,8 +679,11 @@
EVDI_CHECKPT();
if (painter) {
painter_lock(painter);
-
+#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8)
+ if (painter->was_update_requested && painter->num_dirts) {
+#else
if (painter->was_update_requested) {
+#endif
evdi_painter_send_update_ready(painter);
painter->was_update_requested = false;
}
@@ -707,38 +694,47 @@
}
}
+static const char * const dpms_str[] = { "on", "standby", "suspend", "off" };
+
void evdi_painter_dpms_notify(struct evdi_device *evdi, int mode)
{
struct evdi_painter *painter = evdi->painter;
+ const char *mode_str;
- if (painter) {
- EVDI_DEBUG("(dev=%d) Notifying dpms mode: %d\n",
- evdi->dev_index, mode);
- evdi_painter_send_dpms(painter, mode);
- } else {
- EVDI_WARN("Painter does not exist!");
+ if (!painter) {
+ EVDI_WARN("(card%d) Painter does not exist!", evdi->dev_index);
+ return;
}
-}
-void evdi_painter_crtc_state_notify(struct evdi_device *evdi, int state)
-{
- struct evdi_painter *painter = evdi->painter;
+ if (!painter->is_connected)
+ return;
- if (painter) {
- EVDI_DEBUG("(dev=%d) Notifying crtc state: %d\n",
- evdi->dev_index, state);
- evdi_painter_send_crtc_state(painter, state);
- } else {
- EVDI_WARN("Painter does not exist!");
- }
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ mode_str = dpms_str[mode];
+ break;
+ default:
+ mode_str = "unknown";
+ };
+ EVDI_INFO("(card%d) Notifying display power state: %s",
+ evdi->dev_index, mode_str);
+ evdi_painter_send_dpms(painter, mode);
}
-static void evdi_log_pixel_format(uint32_t pixel_format)
+static void evdi_log_pixel_format(uint32_t pixel_format,
+ char *buf, size_t size)
{
+#if KERNEL_VERSION(5, 14, 0) <= LINUX_VERSION_CODE
+ snprintf(buf, size, "pixel format %p4cc", &pixel_format);
+#else
struct drm_format_name_buf format_name;
drm_get_format_name(pixel_format, &format_name);
- EVDI_DEBUG("pixel format %s\n", format_name.str);
+ snprintf(buf, size, "pixel format %s", format_name.str);
+#endif
}
void evdi_painter_mode_changed_notify(struct evdi_device *evdi,
@@ -748,6 +744,7 @@
struct drm_framebuffer *fb;
int bits_per_pixel;
uint32_t pixel_format;
+ char buf[100];
if (painter == NULL)
return;
@@ -759,10 +756,11 @@
bits_per_pixel = fb->format->cpp[0] * 8;
pixel_format = fb->format->format;
- EVDI_DEBUG("(dev=%d) Notifying mode changed: %dx%d@%d; bpp %d; ",
+
+ evdi_log_pixel_format(pixel_format, buf, sizeof(buf));
+ EVDI_INFO("(card%d) Notifying mode changed: %dx%d@%d; bpp %d; %s",
evdi->dev_index, new_mode->hdisplay, new_mode->vdisplay,
- drm_mode_vrefresh(new_mode), bits_per_pixel);
- evdi_log_pixel_format(pixel_format);
+ drm_mode_vrefresh(new_mode), bits_per_pixel, buf);
evdi_painter_send_mode_changed(painter,
new_mode,
@@ -795,7 +793,7 @@
evdi->i2c_adapter = kzalloc(sizeof(*evdi->i2c_adapter), GFP_KERNEL);
if (!evdi->i2c_adapter) {
- EVDI_ERROR("(dev=%d) Failed to allocate for i2c adapter",
+ EVDI_ERROR("(card%d) Failed to allocate for i2c adapter",
evdi->dev_index);
return;
}
@@ -805,19 +803,19 @@
if (result) {
kfree(evdi->i2c_adapter);
evdi->i2c_adapter = NULL;
- EVDI_ERROR("(dev=%d) Failed to add i2c adapter, error %d",
+ EVDI_ERROR("(card%d) Failed to add i2c adapter, error %d",
evdi->dev_index, result);
return;
}
- EVDI_DEBUG("(dev=%d) Added i2c adapter bus number %d",
+ EVDI_INFO("(card%d) Added i2c adapter bus number %d",
evdi->dev_index, evdi->i2c_adapter->nr);
result = sysfs_create_link(&evdi->conn->kdev->kobj,
&evdi->i2c_adapter->dev.kobj, "ddc");
if (result) {
- EVDI_ERROR("(dev=%d) Failed to create sysfs link, error %d",
+ EVDI_ERROR("(card%d) Failed to create sysfs link, error %d",
evdi->dev_index, result);
return;
}
@@ -826,7 +824,7 @@
static void evdi_remove_i2c_adapter(struct evdi_device *evdi)
{
if (evdi->i2c_adapter) {
- EVDI_DEBUG("(dev=%d) Removing i2c adapter bus number %d",
+ EVDI_INFO("(card%d) Removing i2c adapter bus number %d",
evdi->dev_index, evdi->i2c_adapter->nr);
sysfs_remove_link(&evdi->conn->kdev->kobj, "ddc");
@@ -841,16 +839,16 @@
static int
evdi_painter_connect(struct evdi_device *evdi,
void const __user *edid_data, unsigned int edid_length,
- uint32_t sku_area_limit,
- struct drm_file *file, int dev_index)
+ uint32_t pixel_area_limit,
+ uint32_t pixel_per_second_limit,
+ struct drm_file *file, __always_unused int dev_index)
{
struct evdi_painter *painter = evdi->painter;
struct edid *new_edid = NULL;
- int expected_edid_size = 0;
+ unsigned int expected_edid_size = 0;
+ char buf[100];
- EVDI_DEBUG("(dev=%d) Process is trying to connect\n",
- evdi->dev_index);
- evdi_log_process();
+ evdi_log_process(buf, sizeof(buf));
if (edid_length < sizeof(struct edid)) {
EVDI_ERROR("Edid length too small\n");
@@ -867,7 +865,7 @@
return -ENOMEM;
if (copy_from_user(new_edid, edid_data, edid_length)) {
- EVDI_ERROR("(dev=%d) Failed to read edid\n", dev_index);
+ EVDI_ERROR("(card%d) Failed to read edid\n", evdi->dev_index);
kfree(new_edid);
return -EFAULT;
}
@@ -882,13 +880,13 @@
}
if (painter->drm_filp)
- EVDI_WARN("(dev=%d) Double connect - replacing %p with %p\n",
- dev_index, painter->drm_filp, file);
+ EVDI_WARN("(card%d) Double connect - replacing %p with %p\n",
+ evdi->dev_index, painter->drm_filp, file);
painter_lock(painter);
- evdi->dev_index = dev_index;
- evdi->sku_area_limit = sku_area_limit;
+ evdi->pixel_area_limit = pixel_area_limit;
+ evdi->pixel_per_second_limit = pixel_per_second_limit;
painter->drm_filp = file;
kfree(painter->edid);
painter->edid_length = edid_length;
@@ -896,12 +894,12 @@
painter->is_connected = true;
painter->needs_full_modeset = true;
- evdi_add_i2c_adapter(evdi);
+ if (!evdi->i2c_adapter)
+ evdi_add_i2c_adapter(evdi);
painter_unlock(painter);
- EVDI_DEBUG("(dev=%d) Connected with %p\n", evdi->dev_index,
- painter->drm_filp);
+ EVDI_INFO("(card%d) Connected with %s\n", evdi->dev_index, buf);
drm_helper_hpd_irq_event(evdi->ddev);
@@ -912,6 +910,7 @@
struct drm_file *file)
{
struct evdi_painter *painter = evdi->painter;
+ char buf[100];
EVDI_CHECKPT();
@@ -929,8 +928,8 @@
painter->is_connected = false;
- EVDI_DEBUG("(dev=%d) Disconnected from %p\n", evdi->dev_index,
- painter->drm_filp);
+ evdi_log_process(buf, sizeof(buf));
+ EVDI_INFO("(card%d) Disconnected from %s\n", evdi->dev_index, buf);
evdi_painter_events_cleanup(painter);
evdi_painter_send_vblank(painter);
@@ -944,7 +943,6 @@
evdi_remove_i2c_adapter(evdi);
painter->drm_filp = NULL;
- evdi->dev_index = -1;
painter->was_update_requested = false;
evdi->cursor_events_enabled = false;
@@ -962,10 +960,8 @@
{
EVDI_CHECKPT();
- if (evdi->painter)
+ if (evdi->painter && file == evdi->painter->drm_filp)
evdi_painter_disconnect(evdi, file);
- else
- EVDI_WARN("Painter does not exist!");
}
int evdi_painter_connect_ioctl(struct drm_device *drm_dev, void *data,
@@ -982,19 +978,20 @@
ret = evdi_painter_connect(evdi,
cmd->edid,
cmd->edid_length,
- cmd->sku_area_limit,
+ cmd->pixel_area_limit,
+ cmd->pixel_per_second_limit,
file,
cmd->dev_index);
else
ret = evdi_painter_disconnect(evdi, file);
if (ret) {
- EVDI_WARN("(dev=%d)(pid=%d) disconnect failed\n",
+ EVDI_WARN("(card%d)(pid=%d) disconnect failed\n",
evdi->dev_index, (int)task_pid_nr(current));
}
return ret;
}
- EVDI_WARN("Painter does not exist!");
+ EVDI_WARN("(card%d) Painter does not exist!", evdi->dev_index);
return -ENODEV;
}
@@ -1030,7 +1027,7 @@
painter_lock(painter);
if (painter->was_update_requested) {
- EVDI_WARN("(dev=%d) Update ready not sent,",
+ EVDI_WARN("(card%d) Update ready not sent,",
evdi->dev_index);
EVDI_WARN(" but pixels are grabbed.\n");
}
@@ -1084,9 +1081,9 @@
}
}
- if (cmd->buf_width != efb->base.width ||
- cmd->buf_height != efb->base.height) {
- EVDI_ERROR("Invalid buffer dimension\n");
+ if ((unsigned int)cmd->buf_width != efb->base.width ||
+ (unsigned int)cmd->buf_height != efb->base.height) {
+ EVDI_DEBUG("Invalid buffer dimension\n");
err = -EINVAL;
goto err_fb;
}
@@ -1149,7 +1146,7 @@
if (painter->was_update_requested) {
EVDI_WARN
- ("(dev=%d) Update was already requested - ignoring\n",
+ ("(card%d) Update was already requested - ignoring\n",
evdi->dev_index);
} else {
if (painter->num_dirts > 0)
@@ -1210,6 +1207,9 @@
kfree(painter->edid);
painter->edid_length = 0;
painter->edid = NULL;
+ if (painter->scanout_fb)
+ drm_framebuffer_put(&painter->scanout_fb->base);
+ painter->scanout_fb = NULL;
evdi_painter_send_vblank(painter);
@@ -1318,7 +1318,7 @@
}
if (msg->addr != I2C_ADDRESS_DDCCI) {
- EVDI_DEBUG("Ignored ddc/ci data for address 0x%x\n", msg->addr);
+ EVDI_WARN("Ignored ddc/ci data for address 0x%x\n", msg->addr);
return false;
}
@@ -1363,3 +1363,14 @@
painter_unlock(painter);
return result;
}
+
+int evdi_painter_enable_cursor_events_ioctl(struct drm_device *drm_dev, void
*data,
+ __always_unused struct drm_file *file)
+{
+ struct evdi_device *evdi = drm_dev->dev_private;
+ struct drm_evdi_enable_cursor_events *cmd = data;
+
+ evdi->cursor_events_enabled = cmd->enable;
+
+ return 0;
+}
diff -Nru evdi-1.9.0+dfsg/module/evdi_params.c
evdi-1.12.0+dfsg/module/evdi_params.c
--- evdi-1.9.0+dfsg/module/evdi_params.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_params.c 2022-07-13 09:58:06.000000000
-0400
@@ -13,7 +13,7 @@
#include "evdi_params.h"
#include "evdi_debug.h"
-unsigned int evdi_loglevel __read_mostly = EVDI_LOGLEVEL_DEBUG;
+unsigned int evdi_loglevel __read_mostly = EVDI_LOGLEVEL_INFO;
unsigned short int evdi_initial_device_count __read_mostly;
module_param_named(initial_loglevel, evdi_loglevel, int, 0400);
@@ -22,3 +22,4 @@
module_param_named(initial_device_count,
evdi_initial_device_count, ushort, 0644);
MODULE_PARM_DESC(initial_device_count, "Initial DRM device count (default:
0)");
+
diff -Nru evdi-1.9.0+dfsg/module/evdi_platform_dev.c
evdi-1.12.0+dfsg/module/evdi_platform_dev.c
--- evdi-1.9.0+dfsg/module/evdi_platform_dev.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_platform_dev.c 2022-07-13 09:58:06.000000000
-0400
@@ -21,7 +21,7 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
#include <linux/iommu.h>
#endif
@@ -41,8 +41,8 @@
platform_dev = platform_device_register_full(info);
if (dma_set_mask(&platform_dev->dev, DMA_BIT_MASK(64))) {
- EVDI_DEBUG("Unable to change dma mask to 64 bit. ");
- EVDI_DEBUG("Sticking with 32 bit\n");
+ EVDI_WARN("Unable to change dma mask to 64 bit. ");
+ EVDI_WARN("Sticking with 32 bit\n");
}
EVDI_INFO("Evdi platform_device create\n");
@@ -58,20 +58,22 @@
int evdi_platform_device_probe(struct platform_device *pdev)
{
- struct drm_device *dev = NULL;
- struct evdi_platform_device_data *data =
- kzalloc(sizeof(struct evdi_platform_device_data), GFP_KERNEL);
+ struct drm_device *dev;
+ struct evdi_platform_device_data *data;
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
struct dev_iommu iommu;
#endif
#endif
EVDI_CHECKPT();
+ data = kzalloc(sizeof(struct evdi_platform_device_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
/* Intel-IOMMU workaround: platform-bus unsupported, force ID-mapping */
#if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU)
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
+#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8)
memset(&iommu, 0, sizeof(iommu));
iommu.priv = (void *)-1;
pdev->dev.iommu = &iommu;
@@ -83,20 +85,21 @@
dev = evdi_drm_device_create(&pdev->dev);
if (IS_ERR_OR_NULL(dev))
- kfree(data);
- else {
- data->drm_dev = dev;
- data->symlinked = false;
- platform_set_drvdata(pdev, data);
- }
+ goto err_free;
+ data->drm_dev = dev;
+ data->symlinked = false;
+ platform_set_drvdata(pdev, data);
+ return PTR_ERR_OR_ZERO(dev);
+
+err_free:
+ kfree(data);
return PTR_ERR_OR_ZERO(dev);
}
int evdi_platform_device_remove(struct platform_device *pdev)
{
- struct evdi_platform_device_data *data =
- (struct evdi_platform_device_data *)platform_get_drvdata(pdev);
+ struct evdi_platform_device_data *data = platform_get_drvdata(pdev);
EVDI_CHECKPT();
@@ -107,8 +110,7 @@
bool evdi_platform_device_is_free(struct platform_device *pdev)
{
- struct evdi_platform_device_data *data =
- (struct evdi_platform_device_data *)platform_get_drvdata(pdev);
+ struct evdi_platform_device_data *data = platform_get_drvdata(pdev);
struct evdi_device *evdi = data->drm_dev->dev_private;
if (evdi && !evdi_painter_is_connected(evdi->painter) &&
@@ -121,23 +123,21 @@
struct device *parent)
{
struct evdi_platform_device_data *data = NULL;
- char evdi_name[10] = { 0 };
int ret = 0;
if (!parent || !pdev)
return;
- data = (struct evdi_platform_device_data *)platform_get_drvdata(pdev);
+ data = platform_get_drvdata(pdev);
if (!evdi_platform_device_is_free(pdev)) {
EVDI_FATAL("Device is already attached can't symlink again\n");
return;
}
- snprintf(evdi_name, sizeof(evdi_name), "evdi.%d", pdev->id);
- ret = sysfs_create_link(&parent->kobj, &pdev->dev.kobj, evdi_name);
- if (ret)
- EVDI_FATAL("Failed to create sysfs link to parent device\n");
- else {
+ ret = sysfs_create_link(&pdev->dev.kobj, &parent->kobj, "device");
+ if (ret) {
+ EVDI_FATAL("Failed to create sysfs link from evdi to parent
device\n");
+ } else {
data->symlinked = true;
data->parent = parent;
}
@@ -146,10 +146,10 @@
void evdi_platform_device_unlink_if_linked_with(struct platform_device *pdev,
struct device *parent)
{
- struct evdi_platform_device_data *data =
- (struct evdi_platform_device_data *)platform_get_drvdata(pdev);
+ struct evdi_platform_device_data *data = platform_get_drvdata(pdev);
- if (data->parent == parent) {
+ if (parent && data->parent == parent) {
+ sysfs_remove_link(&pdev->dev.kobj, "device");
data->symlinked = false;
data->parent = NULL;
EVDI_INFO("Detached from parent device\n");
diff -Nru evdi-1.9.0+dfsg/module/evdi_platform_drv.c
evdi-1.12.0+dfsg/module/evdi_platform_drv.c
--- evdi-1.9.0+dfsg/module/evdi_platform_drv.c 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_platform_drv.c 2022-07-13 09:58:06.000000000
-0400
@@ -31,8 +31,15 @@
unsigned int dev_count;
struct platform_device *devices[EVDI_DEVICE_COUNT_MAX];
struct notifier_block usb_notifier;
+ struct mutex lock;
} g_ctx;
+#define evdi_platform_drv_context_lock(ctx) \
+ mutex_lock(&ctx->lock)
+
+#define evdi_platform_drv_context_unlock(ctx) \
+ mutex_unlock(&ctx->lock)
+
static int evdi_platform_drv_usb(__always_unused struct notifier_block *nb,
unsigned long action,
void *data)
@@ -54,8 +61,10 @@
if (pdev->dev.parent == &usb_dev->dev) {
EVDI_INFO("Parent USB removed. Removing evdi.%d\n", i);
evdi_platform_dev_destroy(pdev);
+ evdi_platform_drv_context_lock((&g_ctx));
g_ctx.dev_count--;
g_ctx.devices[i] = NULL;
+ evdi_platform_drv_context_unlock((&g_ctx));
}
}
return 0;
@@ -116,10 +125,15 @@
{
struct evdi_platform_drv_context *ctx =
(struct evdi_platform_drv_context *)dev_get_drvdata(device);
- struct platform_device *pdev = evdi_platform_drv_get_free_device(ctx);
+ struct platform_device *pdev = NULL;
+
+ evdi_platform_drv_context_lock(ctx);
+ if (parent)
+ pdev = evdi_platform_drv_get_free_device(ctx);
if (IS_ERR_OR_NULL(pdev))
pdev = evdi_platform_drv_create_new_device(ctx);
+ evdi_platform_drv_context_unlock(ctx);
if (IS_ERR_OR_NULL(pdev))
return -EINVAL;
@@ -130,19 +144,18 @@
int evdi_platform_add_devices(struct device *device, unsigned int val)
{
- struct evdi_platform_drv_context *ctx =
- (struct evdi_platform_drv_context *)dev_get_drvdata(device);
+ unsigned int dev_count = evdi_platform_device_count(device);
if (val == 0) {
EVDI_WARN("Adding 0 devices has no effect\n");
return 0;
}
- if (val > EVDI_DEVICE_COUNT_MAX - ctx->dev_count) {
+ if (val > EVDI_DEVICE_COUNT_MAX - dev_count) {
EVDI_ERROR("Evdi device add failed. Too many devices.\n");
return -EINVAL;
}
- EVDI_DEBUG("Increasing device count to %u\n", ctx->dev_count + val);
+ EVDI_INFO("Increasing device count to %u\n", dev_count + val);
while (val-- && evdi_platform_device_add(device, NULL) == 0)
;
return 0;
@@ -154,6 +167,7 @@
struct evdi_platform_drv_context *ctx =
(struct evdi_platform_drv_context *)dev_get_drvdata(device);
+ evdi_platform_drv_context_lock(ctx);
for (i = 0; i < EVDI_DEVICE_COUNT_MAX; ++i) {
if (ctx->devices[i]) {
EVDI_INFO("Removing evdi %d\n", i);
@@ -163,14 +177,21 @@
}
}
ctx->dev_count = 0;
+ evdi_platform_drv_context_unlock(ctx);
}
-int evdi_platform_device_count(struct device *device)
+unsigned int evdi_platform_device_count(struct device *device)
{
- struct evdi_platform_drv_context *ctx =
- (struct evdi_platform_drv_context *)dev_get_drvdata(device);
+ unsigned int count = 0;
+ struct evdi_platform_drv_context *ctx = NULL;
+
+ ctx = (struct evdi_platform_drv_context *)dev_get_drvdata(device);
+ evdi_platform_drv_context_lock(ctx);
+ count = ctx->dev_count;
+ evdi_platform_drv_context_unlock(ctx);
+
+ return count;
- return ctx->dev_count;
}
static struct platform_driver evdi_platform_driver = {
@@ -193,6 +214,7 @@
memset(&g_ctx, 0, sizeof(g_ctx));
g_ctx.root_dev = root_device_register(DRIVER_NAME);
g_ctx.usb_notifier.notifier_call = evdi_platform_drv_usb;
+ mutex_init(&g_ctx.lock);
dev_set_drvdata(g_ctx.root_dev, &g_ctx);
usb_register_notify(&g_ctx.usb_notifier);
diff -Nru evdi-1.9.0+dfsg/module/evdi_platform_drv.h
evdi-1.12.0+dfsg/module/evdi_platform_drv.h
--- evdi-1.9.0+dfsg/module/evdi_platform_drv.h 2021-01-26 09:31:59.000000000
-0500
+++ evdi-1.12.0+dfsg/module/evdi_platform_drv.h 2022-07-13 09:58:06.000000000
-0400
@@ -25,14 +25,14 @@
#define DRIVER_NAME "evdi"
#define DRIVER_DESC "Extensible Virtual Display Interface"
-#define DRIVER_DATE "20201210"
+#define DRIVER_DATE "20220713"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 9
+#define DRIVER_MINOR 12
#define DRIVER_PATCH 0
void evdi_platform_remove_all_devices(struct device *device);
-int evdi_platform_device_count(struct device *device);
+unsigned int evdi_platform_device_count(struct device *device);
int evdi_platform_add_devices(struct device *device, unsigned int val);
int evdi_platform_device_add(struct device *device, struct device *parent);
diff -Nru evdi-1.9.0+dfsg/module/evdi_sysfs.c
evdi-1.12.0+dfsg/module/evdi_sysfs.c
--- evdi-1.9.0+dfsg/module/evdi_sysfs.c 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/evdi_sysfs.c 2022-07-13 09:58:06.000000000
-0400
@@ -28,6 +28,8 @@
#include "evdi_debug.h"
#include "evdi_platform_drv.h"
+#define MAX_EVDI_USB_ADDR 10
+
static ssize_t version_show(__always_unused struct device *dev,
__always_unused struct device_attribute *attr,
char *buf)
@@ -44,7 +46,6 @@
}
struct evdi_usb_addr {
- #define MAX_EVDI_USB_ADDR 10
int addr[MAX_EVDI_USB_ADDR];
int len;
struct usb_device *usb;
@@ -58,15 +59,17 @@
{
char *usb_path = kstrdup(buf, GFP_KERNEL);
char *temp_path = usb_path;
- char *bus_token = NULL;
- char *usb_token = NULL;
+ char *bus_token;
+ char *usb_token;
char *usb_token_copy = NULL;
- char *itf_token = NULL;
- char *token = NULL;
- char *bus = NULL;
- char *port = NULL;
+ char *token;
+ char *bus;
+ char *port;
struct evdi_usb_addr usb_addr;
+ if (!usb_path)
+ return -ENOMEM;
+
memset(&usb_addr, 0, sizeof(usb_addr));
temp_path = strnstr(temp_path, "usb:", count);
if (!temp_path)
@@ -83,7 +86,8 @@
if (!usb_token)
goto err_parse_usb_path;
- itf_token = strsep(&temp_path, ":");
+ /* Separate trailing ':*' from usb_token */
+ strsep(&temp_path, ":");
token = usb_token_copy = kstrdup(usb_token, GFP_KERNEL);
bus = strsep(&token, "-");
@@ -231,7 +235,7 @@
void evdi_sysfs_init(struct device *root)
{
- int i;
+ unsigned int i;
if (!PTR_ERR_OR_ZERO(root))
for (i = 0; i < ARRAY_SIZE(evdi_device_attributes); i++)
@@ -240,7 +244,7 @@
void evdi_sysfs_exit(struct device *root)
{
- int i;
+ unsigned int i;
if (PTR_ERR_OR_ZERO(root)) {
EVDI_ERROR("root device is null");
diff -Nru evdi-1.9.0+dfsg/module/Kconfig evdi-1.12.0+dfsg/module/Kconfig
--- evdi-1.9.0+dfsg/module/Kconfig 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/Kconfig 2022-07-13 09:58:06.000000000 -0400
@@ -9,6 +9,9 @@
config DRM_EVDI
tristate "Extensible Virtual Display Interface"
depends on DRM
+ depends on USB_SUPPORT
+ depends on USB_ARCH_HAS_HCD
+ select USB
select DRM_KMS_HELPER
help
This is a KMS interface driver allowing user-space programs to
diff -Nru evdi-1.9.0+dfsg/module/Makefile evdi-1.12.0+dfsg/module/Makefile
--- evdi-1.9.0+dfsg/module/Makefile 2021-01-26 09:31:59.000000000 -0500
+++ evdi-1.12.0+dfsg/module/Makefile 2022-07-13 09:58:06.000000000 -0400
@@ -11,13 +11,18 @@
EL8FLAG := -DEL8
endif
+Raspbian := $(shell grep -Eic 'raspb(erry|ian)' /proc/cpuinfo /etc/os-release
2>/dev/null )
+ifeq (,$(findstring 0, $(Raspbian)))
+RPIFLAG := -DRPI
+endif
+
ifneq ($(DKMS_BUILD),)
# DKMS
KERN_DIR := /lib/modules/$(KERNELRELEASE)/build
-ccflags-y := -Iinclude/drm $(EL8FLAG)
+ccflags-y := -Iinclude/drm $(EL8FLAG) $(RPIFLAG)
evdi-y := evdi_platform_drv.o evdi_platform_dev.o evdi_sysfs.o evdi_modeset.o
evdi_connector.o evdi_encoder.o evdi_drm_drv.o evdi_fb.o evdi_gem.o
evdi_painter.o evdi_params.o evdi_cursor.o evdi_debug.o evdi_i2c.o
evdi-$(CONFIG_COMPAT) += evdi_ioc32.o
obj-m := evdi.o
@@ -40,8 +45,7 @@
# inside kbuild
# Note: this can be removed once it is in kernel tree and Kconfig is properly
used
CONFIG_DRM_EVDI := m
-LINUXINCLUDE := $(subst -I,-isystem,$(LINUXINCLUDE))
-ccflags-y := -isystem include/drm $(CFLAGS) $(EL8FLAG)
+ccflags-y := -isystem include/drm $(CFLAGS) $(EL8FLAG) $(RPIFLAG)
evdi-y := evdi_platform_drv.o evdi_platform_dev.o evdi_sysfs.o evdi_modeset.o
evdi_connector.o evdi_encoder.o evdi_drm_drv.o evdi_fb.o evdi_gem.o
evdi_painter.o evdi_params.o evdi_cursor.o evdi_debug.o evdi_i2c.o
evdi-$(CONFIG_COMPAT) += evdi_ioc32.o
obj-$(CONFIG_DRM_EVDI) := evdi.o
@@ -53,7 +57,7 @@
DKMS ?= dkms
RM ?= rm
-MODVER=1.9.0
+MODVER=1.12.0
ifeq ($(KVER),)
KVER := $(shell uname -r)
--- End Message ---