more WIP on blobs..
authorDave Airlie <airlied@redhat.com>
Wed, 5 Dec 2007 06:31:35 +0000 (16:31 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 5 Dec 2007 06:31:35 +0000 (16:31 +1000)
I'm going to pass back a list of blob ids and lengths in the getproperty.
will need another ioctl to return the blob data as it is variable length.

libdrm/xf86drmMode.c
libdrm/xf86drmMode.h
linux-core/drm_crtc.c
shared-core/drm.h

index e5191d8..f4ec004 100644 (file)
@@ -406,7 +406,8 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
 {
        struct drm_mode_get_property prop;
        drmModePropertyPtr r;
-
+       struct drm_mode_property_blob *blob_tmp;
+       int i;
        prop.prop_id = property_id;
        prop.count_enum_blobs = 0;
        prop.count_values = 0;
@@ -420,9 +421,14 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
        if (prop.count_values)
                prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t)));
 
-       if (prop.count_enum_blobs)
+       if (prop.count_enum_blobs & (prop.flags & DRM_MODE_PROP_ENUM))
                prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)));
 
+       if (prop.count_enum_blobs & (prop.flags & DRM_MODE_PROP_BLOB)) {
+               prop.values_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
+               prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
+       }
+
        if (ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
                r = NULL;
                goto err_allocs;
@@ -433,10 +439,18 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
        
        r->prop_id = prop.prop_id;
        r->count_values = prop.count_values;
-       r->count_enums = prop.count_enum_blobs;
+       
        r->flags = prop.flags;
-       r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t));
-       r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum));
+       if (prop.count_values)
+               r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t));
+       if (prop.flags & DRM_MODE_PROP_ENUM) {
+               r->count_enums = prop.count_enum_blobs;
+               r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum));
+       } else  if (prop.flags & DRM_MODE_PROP_ENUM) {
+               r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_enum_blobs, sizeof(uint32_t));
+               r->blob_ids = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(uint32_t));
+               r->count_blobs = prop.count_enum_blobs;
+       }
        strncpy(r->name, prop.name, DRM_PROP_NAME_LEN);
        r->name[DRM_PROP_NAME_LEN-1] = 0;
 
index ec77174..e936044 100644 (file)
@@ -69,15 +69,22 @@ typedef struct _drmModeRes {
 
 typedef struct drm_mode_fb_cmd drmModeFB, *drmModeFBPtr;
 
+typedef struct _drmModePropertyBlob {
+       uint32_t id;
+       uint32_t length;
+       void *data;
+} drmModePropertyBlobRes, *drmModePropertyBlobPtr;
+
 typedef struct _drmModeProperty {
        unsigned int prop_id;
        unsigned int flags;
        unsigned char name[DRM_PROP_NAME_LEN];
        int count_values;
-       uint64_t *values;
+       uint64_t *values; // store the blob lengths
        int count_enums;
        struct drm_mode_property_enum *enums;
-
+       int count_blobs;
+       uint32_t *blob_ids; // store the blob IDs
 } drmModePropertyRes, *drmModePropertyPtr;
 
 typedef struct _drmModeCrtc {
index c268031..a3aa783 100644 (file)
@@ -1968,7 +1968,9 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
        struct drm_property_enum *prop_enum;
        struct drm_property_enum __user *enum_ptr;
        struct drm_property_blob *prop_blob;
+       uint32_t *blob_id_ptr;
        uint64_t __user *values_ptr;
+       uint32_t __user *blob_length_ptr;
 
        mutex_lock(&dev->mode_config.mutex);
        property = idr_find(&dev->mode_config.crtc_idr, out_resp->prop_id);
@@ -1980,7 +1982,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
        if (property->flags & DRM_MODE_PROP_ENUM) {
                list_for_each_entry(prop_enum, &property->enum_blob_list, head)
                        enum_count++;
-       } else  if (property->flags & DRM_MODE_PROP_BLOB) {
+       } else if (property->flags & DRM_MODE_PROP_BLOB) {
                list_for_each_entry(prop_blob, &property->enum_blob_list, head)
                        blob_count++;
        }
@@ -2002,44 +2004,49 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
        }
        out_resp->count_values = value_count;
 
-       if ((out_resp->count_enum_blobs >= enum_count) && enum_count && (property->flags & DRM_MODE_PROP_ENUM)) {
-               copied = 0;
-               enum_ptr = (struct drm_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
-               list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
-                       if (put_user(prop_enum->value, &enum_ptr[copied].value)) {
-                               ret = -EFAULT;
-                               goto done;
-                       }
-
-                       if (copy_to_user(&enum_ptr[copied].name,
-                                        prop_enum->name, DRM_PROP_NAME_LEN)) {
+       if (property->flags & DRM_MODE_PROP_ENUM) {
+               if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
+                       copied = 0;
+                       enum_ptr = (struct drm_property_enum *)(unsigned long)out_resp->enum_blob_ptr;
+                       list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
+                               if (put_user(prop_enum->value, &enum_ptr[copied].value)) {
+                                       ret = -EFAULT;
+                                       goto done;
+                               }
+                               
+                               if (copy_to_user(&enum_ptr[copied].name,
+                                                prop_enum->name, DRM_PROP_NAME_LEN)) {
                                ret = -EFAULT;
                                goto done;
+                               }
+                               copied++;
                        }
-                       copied++;
                }
+               out_resp->count_enum_blobs = enum_count;
        }
-       out_resp->count_enum_blobs = enum_count;
 
-#if 0
-       if ((out_resp->count_blobs >= enum_count) && blob_count && (property->flags & DRM_MODE_PROP_BLOB)) {
-               copied = 0;
-               list_for_each_entry(prop_blob, &property->enum_list, head) {
-                       if (put_user(prop_enum->value, &out_resp->blobs[copied].value)) {
-                               ret = -EFAULT;
-                               goto done;
-                       }
-
-                       if (copy_to_user(&out_resp->enums[copied].name,
-                                        prop_enum->name, DRM_PROP_NAME_LEN)) {
-                               ret = -EFAULT;
-                               goto done;
+       if (property->flags & DRM_MODE_PROP_BLOB) {
+               if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
+                       copied = 0;
+                       blob_id_ptr = (uint32_t *)(unsigned long)out_resp->enum_blob_ptr;
+                       blob_length_ptr = (uint32_t *)(unsigned long)out_resp->values_ptr;
+                       
+                       list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
+                               if (put_user(prop_blob->id, blob_id_ptr + copied)) {
+                                       ret = -EFAULT;
+                                       goto done;
+                               }
+                               
+                               if (put_user(prop_blob->length, blob_length_ptr + copied)) {
+                                       ret = -EFAULT;
+                                       goto done;
+                               }
+                               
+                               copied++;
                        }
-                       copied++;
                }
+               out_resp->count_enum_blobs = enum_count;
        }
-       out_resp->count_enums = enum_count;
-#endif
 done:
        mutex_unlock(&dev->mode_config.mutex);
        return ret;
index 6317f14..7649abd 100644 (file)
@@ -981,12 +981,13 @@ struct drm_mode_property_enum {
 };
 
 struct drm_mode_property_blob {
+       uint64_t data_ptr;
        uint32_t length;
 };
                
 struct drm_mode_get_property {
-       uint64_t values_ptr;
-       uint64_t enum_blob_ptr;
+       uint64_t values_ptr; /* values and blob lengths */
+       uint64_t enum_blob_ptr; /* enum and blob id ptrs */
 
        unsigned int prop_id;
        unsigned int flags;