From de8532dd8359dfdaba839ff61fc9e2f05eaf57d3 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sun, 30 Nov 2014 12:53:18 -0500 Subject: Fix gcc -Wextra warnings Signed-off-by: Jan Vesely Reviewed-by: Ian Romanick Reviewed-by: Emil Velikov --- xf86drmMode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 60ce3699..e3e599bd 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -854,7 +854,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx) len = read(fd, buffer, sizeof buffer); if (len == 0) return 0; - if (len < sizeof *e) + if (len < (int)sizeof *e) return -1; i = 0; -- cgit v1.2.3-54-g00ecf From 7e0460c6d4b509983307f3106ad56c6622c0c7f2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 11 Feb 2015 12:03:12 +0100 Subject: xf86drmMode: Unconditionally clear ioctl structs We really have to do this to avoid surprises when extending the ABI later on. Especially when growing the structures. Reviewed-by: Emil Velikov Reviewed-by: Rob Clark Signed-off-by: Daniel Vetter --- xf86drmMode.c | 55 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index e3e599bd..9ea8fe72 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -61,7 +61,7 @@ #define VG(x) #endif -#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) +#define memclear(s) memset(&s, 0, sizeof(s)) #define U642VOID(x) ((void *)(unsigned long)(x)) #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) @@ -164,7 +164,7 @@ drmModeResPtr drmModeGetResources(int fd) drmModeResPtr r = 0; retry: - memset(&res, 0, sizeof(struct drm_mode_card_res)); + memclear(res); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) return 0; @@ -259,7 +259,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, struct drm_mode_fb_cmd f; int ret; - VG_CLEAR(f); + memclear(f); f.width = width; f.height = height; f.pitch = pitch; @@ -282,6 +282,7 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height, struct drm_mode_fb_cmd2 f; int ret; + memclear(f); f.width = width; f.height = height; f.pixel_format = pixel_format; @@ -300,8 +301,6 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height, int drmModeRmFB(int fd, uint32_t bufferId) { return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); - - } drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) @@ -309,6 +308,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) struct drm_mode_fb_cmd info; drmModeFBPtr r; + memclear(info); info.fb_id = buf; if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info)) @@ -331,8 +331,9 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) int drmModeDirtyFB(int fd, uint32_t bufferId, drmModeClipPtr clips, uint32_t num_clips) { - struct drm_mode_fb_dirty_cmd dirty = { 0 }; + struct drm_mode_fb_dirty_cmd dirty; + memclear(dirty); dirty.fb_id = bufferId; dirty.clips_ptr = VOID2U64(clips); dirty.num_clips = num_clips; @@ -350,7 +351,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) struct drm_mode_crtc crtc; drmModeCrtcPtr r; - VG_CLEAR(crtc); + memclear(crtc); crtc.crtc_id = crtcId; if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc)) @@ -384,7 +385,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, { struct drm_mode_crtc crtc; - VG_CLEAR(crtc); + memclear(crtc); crtc.x = x; crtc.y = y; crtc.crtc_id = crtcId; @@ -394,8 +395,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, if (mode) { memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo)); crtc.mode_valid = 1; - } else - crtc.mode_valid = 0; + } return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); } @@ -408,6 +408,7 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width { struct drm_mode_cursor arg; + memclear(arg); arg.flags = DRM_MODE_CURSOR_BO; arg.crtc_id = crtcId; arg.width = width; @@ -421,6 +422,7 @@ int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t widt { struct drm_mode_cursor2 arg; + memclear(arg); arg.flags = DRM_MODE_CURSOR_BO; arg.crtc_id = crtcId; arg.width = width; @@ -436,6 +438,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y) { struct drm_mode_cursor arg; + memclear(arg); arg.flags = DRM_MODE_CURSOR_MOVE; arg.crtc_id = crtcId; arg.x = x; @@ -452,11 +455,8 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id) struct drm_mode_get_encoder enc; drmModeEncoderPtr r = NULL; + memclear(enc); enc.encoder_id = encoder_id; - enc.crtc_id = 0; - enc.encoder_type = 0; - enc.possible_crtcs = 0; - enc.possible_clones = 0; if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc)) return 0; @@ -483,7 +483,7 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) drmModeConnectorPtr r = NULL; retry: - memset(&conn, 0, sizeof(struct drm_mode_get_connector)); + memclear(conn); conn.connector_id = connector_id; if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) @@ -576,6 +576,7 @@ int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf { struct drm_mode_mode_cmd res; + memclear(res); memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); res.connector_id = connector_id; @@ -586,6 +587,7 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf { struct drm_mode_mode_cmd res; + memclear(res); memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); res.connector_id = connector_id; @@ -598,13 +600,8 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) struct drm_mode_get_property prop; drmModePropertyPtr r; - VG_CLEAR(prop); + memclear(prop); prop.prop_id = property_id; - prop.count_enum_blobs = 0; - prop.count_values = 0; - prop.flags = 0; - prop.enum_blob_ptr = 0; - prop.values_ptr = 0; if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) return 0; @@ -667,8 +664,7 @@ drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id) struct drm_mode_get_blob blob; drmModePropertyBlobPtr r; - blob.length = 0; - blob.data = 0; + memclear(blob); blob.blob_id = blob_id; if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) @@ -708,6 +704,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property { struct drm_mode_connector_set_property osp; + memclear(osp); osp.connector_id = connector_id; osp.prop_id = property_id; osp.value = value; @@ -818,6 +815,7 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, { struct drm_mode_crtc_lut l; + memclear(l); l.crtc_id = crtc_id; l.gamma_size = size; l.red = VOID2U64(red); @@ -832,6 +830,7 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, { struct drm_mode_crtc_lut l; + memclear(l); l.crtc_id = crtc_id; l.gamma_size = size; l.red = VOID2U64(red); @@ -897,11 +896,11 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, { struct drm_mode_crtc_page_flip flip; + memclear(flip); flip.fb_id = fb_id; flip.crtc_id = crtc_id; flip.user_data = VOID2U64(user_data); flip.flags = flags; - flip.reserved = 0; return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); } @@ -916,6 +915,7 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, { struct drm_mode_set_plane s; + memclear(s); s.plane_id = plane_id; s.crtc_id = crtc_id; s.fb_id = fb_id; @@ -939,7 +939,7 @@ drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) drmModePlanePtr r = 0; retry: - memset(&ovr, 0, sizeof(struct drm_mode_get_plane)); + memclear(ovr); ovr.plane_id = plane_id; if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) return 0; @@ -999,7 +999,7 @@ drmModePlaneResPtr drmModeGetPlaneResources(int fd) drmModePlaneResPtr r = 0; retry: - memset(&res, 0, sizeof(struct drm_mode_get_plane_res)); + memclear(res); if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) return 0; @@ -1056,7 +1056,7 @@ drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd, uint32_t count; retry: - memset(&properties, 0, sizeof(struct drm_mode_obj_get_properties)); + memclear(properties); properties.obj_id = object_id; properties.obj_type = object_type; @@ -1122,6 +1122,7 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, { struct drm_mode_obj_set_property prop; + memclear(prop); prop.value = value; prop.prop_id = property_id; prop.obj_id = object_id; -- cgit v1.2.3-54-g00ecf From 65041c4a19bc6d1cc86f768259b9e0888af0bd5f Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Fri, 27 Feb 2015 11:51:05 -0500 Subject: Fix type-limits, pointer-arith and sign-compare warnings Signed-off-by: Jan Vesely Reviewed-by: Emil Velikov --- tests/dristat.c | 4 ++-- tests/getstats.c | 2 -- xf86drmMode.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'xf86drmMode.c') diff --git a/tests/dristat.c b/tests/dristat.c index 449aa242..992ceb40 100644 --- a/tests/dristat.c +++ b/tests/dristat.c @@ -189,9 +189,9 @@ static void printhuman(unsigned long value, const char *name, int mult) static void getstats(int fd, int i) { drmStatsT prev, curr; - int j; + unsigned j; double rate; - + printf(" System statistics:\n"); if (drmGetStats(fd, &prev)) return; diff --git a/tests/getstats.c b/tests/getstats.c index 8d40d0b3..8a7d2999 100644 --- a/tests/getstats.c +++ b/tests/getstats.c @@ -45,8 +45,6 @@ int main(int argc, char **argv) ret = ioctl(fd, DRM_IOCTL_GET_STATS, &stats); assert(ret == 0); - assert(stats.count >= 0); - close(fd); return 0; } diff --git a/xf86drmMode.c b/xf86drmMode.c index 9ea8fe72..61d5e012 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -76,7 +76,7 @@ static inline int DRM_IOCTL(int fd, unsigned long cmd, void *arg) * Util functions */ -void* drmAllocCpy(void *array, int count, int entry_size) +static void* drmAllocCpy(char *array, int count, int entry_size) { char *r; int i; -- cgit v1.2.3-54-g00ecf From 5ed5fa10600f0140b317ec07be6f24739c11bd18 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Mar 2015 10:07:19 +0000 Subject: mode: Retrieve only the current information for a Connector Add a new API that allows the caller to skip any forced probing, which may require slow i2c to a remote display, and only report the currently active mode and encoder for a Connector. This is often the information of interest and is much, much faster than re-retrieving the link status and EDIDs, e.g. if the caller only wishes to count the number of active outputs. v2: Fix error path to avoid double free after a failed GETCONNECTOR ioctl. v3: Daniel strongly disapproved of my disjoint in behaviour between GetConnector and GetConnectorCurrent, and considering how best to make a drop in replacement for drmmode_output_init() convinced me keeping the API as consistent as possible was the right approach. v4: Avoid probing on the second calls to GETCONNECTOR for unconnected outputs. Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Damien Lespiau Cc: David Herrmann Reviewed-by: Daniel Vetter --- tests/modeprint/modeprint.c | 18 ++++++++++++++++-- xf86drmMode.c | 23 ++++++++++++++++++++--- xf86drmMode.h | 17 +++++++++++++++-- 3 files changed, 51 insertions(+), 7 deletions(-) (limited to 'xf86drmMode.c') diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c index de59cbd1..e6c6553b 100644 --- a/tests/modeprint/modeprint.c +++ b/tests/modeprint/modeprint.c @@ -43,6 +43,7 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +int current; int connectors; int full_props; int edid; @@ -272,7 +273,7 @@ static int printRes(int fd, drmModeResPtr res) if (connectors) { for (i = 0; i < res->count_connectors; i++) { - connector = drmModeGetConnector(fd, res->connectors[i]); + connector = (current ? drmModeGetConnectorCurrent : drmModeGetConnector) (fd, res->connectors[i]); if (!connector) printf("Could not get connector %i\n", res->connectors[i]); @@ -331,6 +332,7 @@ static int printRes(int fd, drmModeResPtr res) static void args(int argc, char **argv) { + int defaults = 1; int i; fbs = 0; @@ -341,32 +343,41 @@ static void args(int argc, char **argv) full_modes = 0; full_props = 0; connectors = 0; + current = 0; module_name = argv[1]; for (i = 2; i < argc; i++) { if (strcmp(argv[i], "-fb") == 0) { fbs = 1; + defaults = 0; } else if (strcmp(argv[i], "-crtcs") == 0) { crtcs = 1; + defaults = 0; } else if (strcmp(argv[i], "-cons") == 0) { connectors = 1; modes = 1; + defaults = 0; } else if (strcmp(argv[i], "-modes") == 0) { connectors = 1; modes = 1; + defaults = 0; } else if (strcmp(argv[i], "-full") == 0) { connectors = 1; modes = 1; full_modes = 1; + defaults = 0; } else if (strcmp(argv[i], "-props") == 0) { connectors = 1; full_props = 1; + defaults = 0; } else if (strcmp(argv[i], "-edids") == 0) { connectors = 1; edid = 1; + defaults = 0; } else if (strcmp(argv[i], "-encoders") == 0) { encoders = 1; + defaults = 0; } else if (strcmp(argv[i], "-v") == 0) { fbs = 1; edid = 1; @@ -376,10 +387,13 @@ static void args(int argc, char **argv) full_modes = 1; full_props = 1; connectors = 1; + defaults = 0; + } else if (strcmp(argv[i], "-current") == 0) { + current = 1; } } - if (argc == 2) { + if (defaults) { fbs = 1; edid = 1; crtcs = 1; diff --git a/xf86drmMode.c b/xf86drmMode.c index 61d5e012..1333da48 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -476,19 +476,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id) /* * Connector manipulation */ - -drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) +static drmModeConnectorPtr +_drmModeGetConnector(int fd, uint32_t connector_id, int probe) { struct drm_mode_get_connector conn, counts; drmModeConnectorPtr r = NULL; -retry: memclear(conn); conn.connector_id = connector_id; + if (!probe) { + conn.count_modes = 1; + conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo))); + } if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) return 0; +retry: counts = conn; if (conn.count_props) { @@ -504,6 +508,9 @@ retry: conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); if (!conn.modes_ptr) goto err_allocs; + } else { + conn.count_modes = 1; + conn.modes_ptr = VOID2U64(drmMalloc(sizeof(struct drm_mode_modeinfo))); } if (conn.count_encoders) { @@ -572,6 +579,16 @@ err_allocs: return r; } +drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) +{ + return _drmModeGetConnector(fd, connector_id, 1); +} + +drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id) +{ + return _drmModeGetConnector(fd, connector_id, 0); +} + int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) { struct drm_mode_mode_cmd res; diff --git a/xf86drmMode.h b/xf86drmMode.h index 2d30184e..20c3f153 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h @@ -422,10 +422,23 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id); */ /** - * Retrive information about the connector connectorId. + * Retrieve all information about the connector connectorId. This will do a + * forced probe on the connector to retrieve remote information such as EDIDs + * from the display device. */ extern drmModeConnectorPtr drmModeGetConnector(int fd, - uint32_t connectorId); + uint32_t connectorId); + +/** + * Retrieve current information, i.e the currently active mode and encoder, + * about the connector connectorId. This will not do any probing on the + * connector or remote device, and only reports what is currently known. + * For the complete set of modes and encoders associated with the connector + * use drmModeGetConnector() which will do a probe to determine any display + * link changes first. + */ +extern drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, + uint32_t connector_id); /** * Attaches the given mode to an connector. -- cgit v1.2.3-54-g00ecf From ed44e0b9585c563905447eceed12af9c1c7ca8d4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 22 Jun 2015 17:26:02 +0100 Subject: Support atomic modesetting ioctl Add support for the atomic modesetting ioctl through a property-set API. v1: Squashed intermediate patches from Ville, Rob and myself. Updated for current kernel interface (no blobs). v2: Rewrite user-facing API to provide transactional/cursor interface. Use memclear to zero out ioctl. Signed-off-by: Ville Syrjälä Signed-off-by: Rob Clark Signed-off-by: Daniel Stone v3 [Emil Velikov]: Remove DRM_CAP_ATOMIC - superseded by DRM_CLIENT_CAP_ATOMIC. Signed-off-by: Emil Velikov --- include/drm/drm.h | 8 ++ include/drm/drm_mode.h | 16 ++++ xf86drmMode.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++ xf86drmMode.h | 19 ++++ 4 files changed, 283 insertions(+) (limited to 'xf86drmMode.c') diff --git a/include/drm/drm.h b/include/drm/drm.h index 229a29f9..d1dc3e38 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -635,6 +635,13 @@ struct drm_get_cap { */ #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 +/** + * DRM_CLIENT_CAP_ATOMIC + * + * If set to 1, the DRM core will allow atomic modesetting requests. + */ +#define DRM_CLIENT_CAP_ATOMIC 3 + /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; @@ -758,6 +765,7 @@ struct drm_prime_handle { #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) +#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index a2ab88a5..66f856fc 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -507,4 +507,20 @@ struct drm_mode_destroy_dumb { __u32 handle; }; +/* page-flip flags are valid, plus: */ +#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 +#define DRM_MODE_ATOMIC_NONBLOCK 0x0200 +#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400 + +struct drm_mode_atomic { + __u32 flags; + __u32 count_objs; + __u64 objs_ptr; + __u64 count_props_ptr; + __u64 props_ptr; + __u64 prop_values_ptr; + __u64 reserved; + __u64 user_data; +}; + #endif diff --git a/xf86drmMode.c b/xf86drmMode.c index 1333da48..a75eca33 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -37,9 +37,12 @@ * TODO the types we are after are defined in diffrent headers on diffrent * platforms find which headers to include to get uint32_t */ +#include #include +#include #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -1147,3 +1150,240 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop); } + +typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr; + +struct _drmModeAtomicReqItem { + uint32_t object_id; + uint32_t property_id; + uint64_t value; +}; + +struct _drmModeAtomicReq { + uint32_t cursor; + uint32_t size_items; + drmModeAtomicReqItemPtr items; +}; + +drmModeAtomicReqPtr drmModeAtomicAlloc(void) +{ + drmModeAtomicReqPtr req; + + req = drmMalloc(sizeof *req); + if (!req) + return NULL; + + req->items = NULL; + req->cursor = 0; + req->size_items = 0; + + return req; +} + +drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old) +{ + drmModeAtomicReqPtr new; + + new = drmMalloc(sizeof *new); + if (!new) + return NULL; + + new->cursor = old->cursor; + new->size_items = old->size_items; + + if (old->size_items) { + new->items = drmMalloc(old->size_items * sizeof(*new->items)); + if (!new->items) { + free(new); + return NULL; + } + memcpy(new->items, old->items, + old->size_items * sizeof(*new->items)); + } else { + new->items = NULL; + } + + return new; +} + +int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment) +{ + if (!augment || augment->cursor == 0) + return 0; + + if (base->cursor + augment->cursor >= base->size_items) { + drmModeAtomicReqItemPtr new; + int saved_size = base->size_items; + + base->size_items = base->cursor + augment->cursor; + new = realloc(base->items, + base->size_items * sizeof(*base->items)); + if (!new) { + base->size_items = saved_size; + return -ENOMEM; + } + base->items = new; + } + + memcpy(&base->items[base->cursor], augment->items, + augment->cursor * sizeof(*augment->items)); + base->cursor += augment->cursor; + + return 0; +} + +int drmModeAtomicGetCursor(drmModeAtomicReqPtr req) +{ + return req->cursor; +} + +void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor) +{ + req->cursor = cursor; +} + +int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, + uint32_t object_id, + uint32_t property_id, + uint64_t value) +{ + if (req->cursor >= req->size_items) { + drmModeAtomicReqItemPtr new; + + req->size_items += 16; + new = realloc(req->items, req->size_items * sizeof(*req->items)); + if (!new) { + req->size_items -= 16; + return -ENOMEM; + } + req->items = new; + } + + req->items[req->cursor].object_id = object_id; + req->items[req->cursor].property_id = property_id; + req->items[req->cursor].value = value; + req->cursor++; + + return req->cursor; +} + +void drmModeAtomicFree(drmModeAtomicReqPtr req) +{ + if (!req) + return; + + if (req->items) + drmFree(req->items); + drmFree(req); +} + +static int sort_req_list(const void *misc, const void *other) +{ + const drmModeAtomicReqItem *first = misc; + const drmModeAtomicReqItem *second = other; + + if (first->object_id < second->object_id) + return -1; + else if (first->object_id > second->object_id) + return 1; + else + return second->property_id - first->property_id; +} + +int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags, + void *user_data) +{ + drmModeAtomicReqPtr sorted = drmModeAtomicDuplicate(req); + struct drm_mode_atomic atomic; + uint32_t *objs_ptr = NULL; + uint32_t *count_props_ptr = NULL; + uint32_t *props_ptr = NULL; + uint64_t *prop_values_ptr = NULL; + uint32_t last_obj_id = 0; + uint32_t i; + int obj_idx = -1; + int ret = -1; + + if (!sorted) + return -ENOMEM; + + memclear(atomic); + + /* Sort the list by object ID, then by property ID. */ + qsort(sorted->items, sorted->cursor, sizeof(*sorted->items), + sort_req_list); + + /* Now the list is sorted, eliminate duplicate property sets. */ + for (i = 0; i < sorted->cursor; i++) { + if (sorted->items[i].object_id != last_obj_id) { + atomic.count_objs++; + last_obj_id = sorted->items[i].object_id; + } + + if (i == sorted->cursor - 1) + continue; + + if (sorted->items[i].object_id != sorted->items[i + 1].object_id || + sorted->items[i].property_id != sorted->items[i + 1].property_id) + continue; + + memmove(&sorted->items[i], &sorted->items[i + 1], + (sorted->cursor - i - 1) * sizeof(*sorted->items)); + sorted->cursor--; + } + + objs_ptr = drmMalloc(atomic.count_objs * sizeof objs_ptr[0]); + if (!objs_ptr) { + errno = ENOMEM; + goto out; + } + + count_props_ptr = drmMalloc(atomic.count_objs * sizeof count_props_ptr[0]); + if (!count_props_ptr) { + errno = ENOMEM; + goto out; + } + + props_ptr = drmMalloc(sorted->cursor * sizeof props_ptr[0]); + if (!props_ptr) { + errno = ENOMEM; + goto out; + } + + prop_values_ptr = drmMalloc(sorted->cursor * sizeof prop_values_ptr[0]); + if (!prop_values_ptr) { + errno = ENOMEM; + goto out; + } + + for (i = 0, last_obj_id = 0; i < sorted->cursor; i++) { + if (sorted->items[i].object_id != last_obj_id) { + obj_idx++; + objs_ptr[obj_idx] = sorted->items[i].object_id; + last_obj_id = objs_ptr[obj_idx]; + } + + count_props_ptr[obj_idx]++; + props_ptr[i] = sorted->items[i].property_id; + prop_values_ptr[i] = sorted->items[i].value; + + } + + atomic.flags = flags; + atomic.objs_ptr = VOID2U64(objs_ptr); + atomic.count_props_ptr = VOID2U64(count_props_ptr); + atomic.props_ptr = VOID2U64(props_ptr); + atomic.prop_values_ptr = VOID2U64(prop_values_ptr); + atomic.user_data = VOID2U64(user_data); + + ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic); + +out: + drmFree(objs_ptr); + drmFree(count_props_ptr); + drmFree(props_ptr); + drmFree(prop_values_ptr); + drmModeAtomicFree(sorted); + + return ret; +} diff --git a/xf86drmMode.h b/xf86drmMode.h index 20c3f153..317ea234 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h @@ -484,6 +484,25 @@ extern int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, uint32_t property_id, uint64_t value); + +typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr; + +extern drmModeAtomicReqPtr drmModeAtomicAlloc(void); +extern drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr req); +extern int drmModeAtomicMerge(drmModeAtomicReqPtr base, + drmModeAtomicReqPtr augment); +extern void drmModeAtomicFree(drmModeAtomicReqPtr req); +extern int drmModeAtomicGetCursor(drmModeAtomicReqPtr req); +extern void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor); +extern int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, + uint32_t object_id, + uint32_t property_id, + uint64_t value); +extern int drmModeAtomicCommit(int fd, + drmModeAtomicReqPtr req, + uint32_t flags, + void *user_data); + #if defined(__cplusplus) || defined(c_plusplus) } #endif -- cgit v1.2.3-54-g00ecf From 32471b265c6fbce6d519f0420a0ffeb608296502 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 22 Jun 2015 17:26:03 +0100 Subject: Add blob property create/destroy ioctl wrappers v2: Use memclear to zero out structure. Signed-off-by: Daniel Stone Reviewed-by: Rob Clark --- include/drm/drm.h | 2 ++ include/drm/drm_mode.h | 21 +++++++++++++++++++++ xf86drmMode.c | 34 ++++++++++++++++++++++++++++++++++ xf86drmMode.h | 5 +++++ 4 files changed, 62 insertions(+) (limited to 'xf86drmMode.c') diff --git a/include/drm/drm.h b/include/drm/drm.h index d1dc3e38..167b7b81 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -766,6 +766,8 @@ struct drm_prime_handle { #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) #define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) +#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob) +#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob) /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 66f856fc..69c1ac3c 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -523,4 +523,25 @@ struct drm_mode_atomic { __u64 user_data; }; +/** + * Create a new 'blob' data property, copying length bytes from data pointer, + * and returning new blob ID. + */ +struct drm_mode_create_blob { + /** Pointer to data to copy. */ + __u64 data; + /** Length of data to copy. */ + __u32 length; + /** Return: new property ID. */ + __u32 blob_id; +}; + +/** + * Destroy a user-created blob property. + */ +struct drm_mode_destroy_blob { + __u32 blob_id; +}; + + #endif diff --git a/xf86drmMode.c b/xf86drmMode.c index a75eca33..73c86958 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -1387,3 +1387,37 @@ out: return ret; } + +int +drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id) +{ + struct drm_mode_create_blob create; + int ret; + + if (length >= 0xffffffff) + return -ERANGE; + + memclear(create); + + create.length = length; + create.data = (uintptr_t) data; + create.blob_id = 0; + *id = 0; + + ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create); + if (ret != 0) + return ret; + + *id = create.blob_id; + return 0; +} + +int +drmModeDestroyPropertyBlob(int fd, uint32_t id) +{ + struct drm_mode_destroy_blob destroy; + + memclear(destroy); + destroy.blob_id = id; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy); +} diff --git a/xf86drmMode.h b/xf86drmMode.h index 317ea234..1c10023c 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h @@ -503,6 +503,11 @@ extern int drmModeAtomicCommit(int fd, uint32_t flags, void *user_data); +extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size, + uint32_t *id); +extern int drmModeDestroyPropertyBlob(int fd, uint32_t id); + + #if defined(__cplusplus) || defined(c_plusplus) } #endif -- cgit v1.2.3-54-g00ecf From 8426967d4e34ef5924a30166662c60d1003072bd Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 22 Jun 2015 17:58:05 +0000 Subject: xf86drmMode: remove unused valgrind(VG) macros Signed-off-by: Emil Velikov --- xf86drmMode.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 73c86958..206d1c25 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -56,14 +56,6 @@ #include #include -#ifdef HAVE_VALGRIND -#include -#include -#define VG(x) x -#else -#define VG(x) -#endif - #define memclear(s) memset(&s, 0, sizeof(s)) #define U642VOID(x) ((void *)(unsigned long)(x)) -- cgit v1.2.3-54-g00ecf From 5f76273d51fee5c176302ae5f57673461b80333b Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Mon, 29 Jun 2015 17:32:21 +0100 Subject: xf86drmMode: include config.h before anything else Signed-off-by: Emil Velikov --- xf86drmMode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 206d1c25..f4b8d146 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -37,6 +37,11 @@ * TODO the types we are after are defined in diffrent headers on diffrent * platforms find which headers to include to get uint32_t */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -44,10 +49,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "xf86drmMode.h" #include "xf86drm.h" #include -- cgit v1.2.3-54-g00ecf From fc8c3e23fb990efd620ef9d9bf3b91686aecc934 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Mon, 6 Jul 2015 12:45:31 +0100 Subject: Fix headers inclusion in xf86drmMode.c Add sys/sysctl.h to get sysctlbyname declaration on kFreeBSD Updated by Thorsten “mirabilos” Glaser to add autoconf check and only include if it is detected by configure as it’s unusable on Linux/x32 (and others, e.g. other new architectures). Reviewed-by: Emil Velikov --- configure.ac | 2 +- xf86drmMode.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'xf86drmMode.c') diff --git a/configure.ac b/configure.ac index 001fd3da..2cf9a190 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,7 @@ AC_USE_SYSTEM_EXTENSIONS AC_SYS_LARGEFILE AC_FUNC_ALLOCA -AC_CHECK_HEADERS([sys/mkdev.h]) +AC_CHECK_HEADERS([sys/mkdev.h sys/sysctl.h]) # Initialize libtool LT_PREREQ([2.2]) diff --git a/xf86drmMode.c b/xf86drmMode.c index f4b8d146..529429e8 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -46,6 +46,9 @@ #include #include #include +#ifdef HAVE_SYS_SYSCTL_H +#include +#endif #include #include -- cgit v1.2.3-54-g00ecf From 1a6efaf68e207302cd9423051b8091fa663bbabe Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Jul 2015 13:46:45 +0100 Subject: drm: Detect no-op drmModeAtomicRequest and return early If the number of items to process in the request is zero, we can forgo duplicating, sorting the request and feeding it into the kernel and instead report success immediately. This prevents a NULL dereference of the sorted->items for the no-op request. Fixes: ed44e0b9585c563905447eceed12af9c1c7ca8d4 Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Rob Clark Cc: Daniel Stone Cc: Emil Velikov Reviewed-by: Emil Velikov --- xf86drmMode.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 529429e8..fa219861 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -1289,7 +1289,7 @@ static int sort_req_list(const void *misc, const void *other) int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags, void *user_data) { - drmModeAtomicReqPtr sorted = drmModeAtomicDuplicate(req); + drmModeAtomicReqPtr sorted; struct drm_mode_atomic atomic; uint32_t *objs_ptr = NULL; uint32_t *count_props_ptr = NULL; @@ -1300,7 +1300,11 @@ int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags, int obj_idx = -1; int ret = -1; - if (!sorted) + if (req->cursor == 0) + return 0; + + sorted = drmModeAtomicDuplicate(req); + if (sorted == NULL) return -ENOMEM; memclear(atomic); -- cgit v1.2.3-54-g00ecf From 1d3b823650bf980a48df00b748fef7cfc7c19b14 Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Sun, 19 Jul 2015 07:20:37 +1000 Subject: xf86drmMode: Implement drmCheckModesettingSupported() for OpenBSD This is implemented with kms ioctls so it could also be used as a generic fallback. Signed-off-by: Jonathan Gray Reviewed-by: Emil Velikov --- xf86drmMode.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index fa219861..fc19504d 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -822,8 +822,25 @@ int drmCheckModesettingSupported(const char *busid) #elif defined(__DragonFly__) return 0; #endif - return -ENOSYS; +#ifdef __OpenBSD__ + int fd; + struct drm_mode_card_res res; + drmModeResPtr r = 0; + + if ((fd = drmOpen(NULL, busid)) < 0) + return -EINVAL; + + memset(&res, 0, sizeof(struct drm_mode_card_res)); + if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) { + drmClose(fd); + return -errno; + } + + drmClose(fd); + return 0; +#endif + return -ENOSYS; } int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, -- cgit v1.2.3-54-g00ecf From d2d361cddd2bdf8f1bf627b9ebe8ca802156f8af Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 9 Apr 2014 08:59:04 +0200 Subject: libdrm: Remove gratuitous blank lines Usage of blank lines can be a matter of taste, of course, but for these we can surely all agree that they're not needed and inconsistent. Acked-by: Laurent Pinchart Signed-off-by: Thierry Reding --- xf86drmMode.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index fc19504d..23348d76 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -114,7 +114,6 @@ void drmModeFreeResources(drmModeResPtr ptr) drmFree(ptr->connectors); drmFree(ptr->encoders); drmFree(ptr); - } void drmModeFreeFB(drmModeFBPtr ptr) @@ -132,7 +131,6 @@ void drmModeFreeCrtc(drmModeCrtcPtr ptr) return; drmFree(ptr); - } void drmModeFreeConnector(drmModeConnectorPtr ptr) @@ -145,7 +143,6 @@ void drmModeFreeConnector(drmModeConnectorPtr ptr) drmFree(ptr->props); drmFree(ptr->modes); drmFree(ptr); - } void drmModeFreeEncoder(drmModeEncoderPtr ptr) @@ -340,7 +337,6 @@ int drmModeDirtyFB(int fd, uint32_t bufferId, return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); } - /* * Crtc functions */ @@ -377,7 +373,6 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) return r; } - int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, uint32_t x, uint32_t y, uint32_t *connectors, int count, drmModeModeInfoPtr mode) @@ -610,7 +605,6 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res); } - drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) { struct drm_mode_get_property prop; @@ -944,7 +938,6 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, uint32_t crtc_w, uint32_t crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) - { struct drm_mode_set_plane s; @@ -965,7 +958,6 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); } - drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) { struct drm_mode_get_plane ovr, counts; -- cgit v1.2.3-54-g00ecf From 5e5a3c48b83fb3929e57cb4e7261624a327137f3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 9 Apr 2014 09:00:49 +0200 Subject: libdrm: Make indentation consistent Use tabs and spaces consistently to align function arguments on subsequent lines with those of the first line. Acked-by: Laurent Pinchart Signed-off-by: Thierry Reding --- xf86drmMode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 23348d76..9b70ce83 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -249,7 +249,7 @@ err_allocs: } int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, - uint8_t bpp, uint32_t pitch, uint32_t bo_handle, + uint8_t bpp, uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id) { struct drm_mode_fb_cmd f; @@ -374,7 +374,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) } int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, - uint32_t x, uint32_t y, uint32_t *connectors, int count, + uint32_t x, uint32_t y, uint32_t *connectors, int count, drmModeModeInfoPtr mode) { struct drm_mode_crtc crtc; -- cgit v1.2.3-54-g00ecf From 4bac035c34b8dfd02e8046150fd19843058618b8 Mon Sep 17 00:00:00 2001 From: Hyungwon Hwang Date: Wed, 19 Aug 2015 09:58:39 +0900 Subject: xf86drmMode: remove the trailing white spaces This patch removes the trailing white spaces. Signed-off-by: Hyungwon Hwang --- xf86drmMode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 9b70ce83..23800dd1 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -873,7 +873,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx) int len, i; struct drm_event *e; struct drm_event_vblank *vblank; - + /* The DRM read semantics guarantees that we always get only * complete events. */ @@ -893,7 +893,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx) break; vblank = (struct drm_event_vblank *) e; evctx->vblank_handler(fd, - vblank->sequence, + vblank->sequence, vblank->tv_sec, vblank->tv_usec, U642VOID (vblank->user_data)); -- cgit v1.2.3-54-g00ecf From ed3c665548c2c0400a7e9e91cb9324c9e1f29375 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Sat, 5 Sep 2015 17:20:53 +0100 Subject: xf86drmMode: smoke-test the atomic API As going through the modetest patches for atomic support I've noticed that if we pass NULL for the drmModeAtomicReqPtr argument we'll crash. So let's handle things appropriately if the user forgot to check the return value of drmModeAtomicAlloc and drmModeAtomicDuplicate or made a typo somewhere along the way. Cc: Ville Syrjälä Cc: Rob Clark Cc: Daniel Stone Signed-off-by: Emil Velikov --- xf86drmMode.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'xf86drmMode.c') diff --git a/xf86drmMode.c b/xf86drmMode.c index 23800dd1..ab6b5195 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -1189,6 +1189,9 @@ drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old) { drmModeAtomicReqPtr new; + if (!old) + return NULL; + new = drmMalloc(sizeof *new); if (!new) return NULL; @@ -1213,6 +1216,9 @@ drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old) int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment) { + if (!base) + return -EINVAL; + if (!augment || augment->cursor == 0) return 0; @@ -1239,12 +1245,15 @@ int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment) int drmModeAtomicGetCursor(drmModeAtomicReqPtr req) { + if (!req) + return -EINVAL; return req->cursor; } void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor) { - req->cursor = cursor; + if (req) + req->cursor = cursor; } int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, @@ -1252,6 +1261,9 @@ int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, uint32_t property_id, uint64_t value) { + if (!req) + return -EINVAL; + if (req->cursor >= req->size_items) { drmModeAtomicReqItemPtr new; @@ -1309,6 +1321,9 @@ int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags, int obj_idx = -1; int ret = -1; + if (!req) + return -EINVAL; + if (req->cursor == 0) return 0; -- cgit v1.2.3-54-g00ecf