X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=xf86drmMode.c;h=c94e40cee68b55457bc1eb4eb84680786c5fbf8f;hb=refs%2Fheads%2Ffroyo-x86;hp=44ef05bcbb85e77bc60d78c15e9f5e387e594019;hpb=85fb3e55fdb7af9b5f59c1ec0f15d1950e601b05;p=android-x86%2Fexternal-libdrm.git diff --git a/xf86drmMode.c b/xf86drmMode.c index 44ef05bc..c94e40ce 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -52,6 +52,12 @@ #define U642VOID(x) ((void *)(unsigned long)(x)) #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) +static inline int DRM_IOCTL(int fd, int cmd, void *arg) +{ + int ret = drmIoctl(fd, cmd, arg); + return ret < 0 ? -errno : ret; +} + /* * Util functions */ @@ -206,7 +212,11 @@ retry: r->crtcs = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t)); r->connectors = drmAllocCpy(U642VOID(res.connector_id_ptr), res.count_connectors, sizeof(uint32_t)); r->encoders = drmAllocCpy(U642VOID(res.encoder_id_ptr), res.count_encoders, sizeof(uint32_t)); - if (!r->fbs || !r->crtcs || !r->connectors || !r->encoders) { + if ((res.count_fbs && !r->fbs) || + (res.count_crtcs && !r->crtcs) || + (res.count_connectors && !r->connectors) || + (res.count_encoders && !r->encoders)) + { drmFree(r->fbs); drmFree(r->crtcs); drmFree(r->connectors); @@ -238,7 +248,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, f.depth = depth; f.handle = bo_handle; - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f))) + if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f))) return ret; *buf_id = f.fb_id; @@ -247,7 +257,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, int drmModeRmFB(int fd, uint32_t bufferId) { - return drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); } @@ -285,7 +295,7 @@ int drmModeDirtyFB(int fd, uint32_t bufferId, dirty.clips_ptr = VOID2U64(clips); dirty.num_clips = num_clips; - return drmIoctl(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); } @@ -340,7 +350,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, } else crtc.mode_valid = 0; - return drmIoctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); } /* @@ -357,7 +367,7 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width arg.height = height; arg.handle = bo_handle; - return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg); } int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y) @@ -369,7 +379,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y) arg.x = x; arg.y = y; - return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg); } /* @@ -406,37 +416,57 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id) drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) { - struct drm_mode_get_connector conn; + struct drm_mode_get_connector conn, counts; drmModeConnectorPtr r = NULL; +retry: + memset(&conn, 0, sizeof(struct drm_mode_get_connector)); conn.connector_id = connector_id; - conn.connector_type_id = 0; - conn.connector_type = 0; - conn.count_modes = 0; - conn.modes_ptr = 0; - conn.count_props = 0; - conn.props_ptr = 0; - conn.prop_values_ptr = 0; - conn.count_encoders = 0; - conn.encoders_ptr = 0; if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) return 0; + counts = conn; + if (conn.count_props) { conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t))); + if (!conn.props_ptr) + goto err_allocs; conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t))); + if (!conn.prop_values_ptr) + goto err_allocs; } - if (conn.count_modes) + if (conn.count_modes) { conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); + if (!conn.modes_ptr) + goto err_allocs; + } - if (conn.count_encoders) + if (conn.count_encoders) { conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t))); + if (!conn.encoders_ptr) + goto err_allocs; + } if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) goto err_allocs; + /* The number of available connectors and etc may have changed with a + * hotplug event in between the ioctls, in which case the field is + * silently ignored by the kernel. + */ + if (counts.count_props < conn.count_props || + counts.count_modes < conn.count_modes || + counts.count_encoders < conn.count_encoders) { + drmFree(U642VOID(conn.props_ptr)); + drmFree(U642VOID(conn.prop_values_ptr)); + drmFree(U642VOID(conn.modes_ptr)); + drmFree(U642VOID(conn.encoders_ptr)); + + goto retry; + } + if(!(r = drmMalloc(sizeof(*r)))) { goto err_allocs; } @@ -449,7 +479,6 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) /* convert subpixel from kernel to userspace */ r->subpixel = conn.subpixel + 1; r->count_modes = conn.count_modes; - /* TODO we should test if these alloc & cpy fails. */ r->count_props = conn.count_props; r->props = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t)); r->prop_values = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t)); @@ -459,8 +488,17 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) r->connector_type = conn.connector_type; r->connector_type_id = conn.connector_type_id; - if (!r->props || !r->prop_values || !r->modes || !r->encoders) - goto err_allocs; + if ((r->count_props && !r->props) || + (r->count_props && !r->prop_values) || + (r->count_modes && !r->modes) || + (r->count_encoders && !r->encoders)) { + drmFree(r->props); + drmFree(r->prop_values); + drmFree(r->modes); + drmFree(r->encoders); + drmFree(r); + r = 0; + } err_allocs: drmFree(U642VOID(conn.prop_values_ptr)); @@ -478,7 +516,7 @@ int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); res.connector_id = connector_id; - return drmIoctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_ATTACHMODE, &res); } int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) @@ -488,7 +526,7 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); res.connector_id = connector_id; - return drmIoctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res); } @@ -581,7 +619,7 @@ drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id) } if (!(r = drmMalloc(sizeof(*r)))) - return NULL; + goto err_allocs; r->id = blob.blob_id; r->length = blob.length; @@ -605,16 +643,12 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property uint64_t value) { struct drm_mode_connector_set_property osp; - int ret; osp.connector_id = connector_id; osp.prop_id = property_id; osp.value = value; - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp))) - return ret; - - return 0; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp); } /* @@ -683,7 +717,6 @@ int drmCheckModesettingSupported(const char *busid) int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue) { - int ret; struct drm_mode_crtc_lut l; l.crtc_id = crtc_id; @@ -692,16 +725,12 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, l.green = VOID2U64(green); l.blue = VOID2U64(blue); - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l))) - return ret; - - return 0; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_GETGAMMA, &l); } int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue) { - int ret; struct drm_mode_crtc_lut l; l.crtc_id = crtc_id; @@ -710,10 +739,7 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, l.green = VOID2U64(green); l.blue = VOID2U64(blue); - if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l))) - return ret; - - return 0; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l); } int drmHandleEvent(int fd, drmEventContextPtr evctx) @@ -778,5 +804,5 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, flip.flags = flags; flip.reserved = 0; - return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); + return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); }