Exemplo n.º 1
0
static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev,
						int size, u32 *handle)
{
	struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1);
	if (gtt == NULL)
		return -ENOMEM;
	if (drm_gem_private_object_init(dev, &gtt->gem, size) != 0)
		goto free_gtt;
	if (drm_gem_handle_create(file, &gtt->gem, handle) == 0)
		return 0;
free_gtt:
	psb_gtt_free_range(dev, gtt);
	return -ENOMEM;
}
Exemplo n.º 2
0
/**
 *	psb_gem_create		-	create a mappable object
 *	@file: the DRM file of the client
 *	@dev: our device
 *	@size: the size requested
 *	@handlep: returned handle (opaque number)
 *
 *	Create a GEM object, fill in the boilerplate and attach a handle to
 *	it so that userspace can speak about it. This does the core work
 *	for the various methods that do/will create GEM objects for things
 */
static int psb_gem_create(struct drm_file *file,
                          struct drm_device *dev, uint64_t size, uint32_t *handlep)
{
    struct gtt_range *r;
    int ret;
    u32 handle;

    size = roundup(size, PAGE_SIZE);

    /* Allocate our object - for now a direct gtt range which is not
       stolen memory backed */
    r = psb_gtt_alloc_range(dev, size, "gem", 0);
    if (r == NULL) {
        dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
        return -ENOSPC;
    }
    /* Initialize the extra goodies GEM needs to do all the hard work */
    if (drm_gem_object_init(dev, &r->gem, size) != 0) {
        psb_gtt_free_range(dev, r);
        /* GEM doesn't give an error code so use -ENOMEM */
        dev_err(dev->dev, "GEM init failed for %lld\n", size);
        return -ENOMEM;
    }
    /* Limit the object to 32bit mappings */
    mapping_set_gfp_mask(r->gem.filp->f_mapping, GFP_KERNEL | __GFP_DMA32);
    /* Give the object a handle so we can carry it more easily */
    ret = drm_gem_handle_create(file, &r->gem, &handle);
    if (ret) {
        dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
                &r->gem, size);
        drm_gem_object_release(&r->gem);
        psb_gtt_free_range(dev, r);
        return ret;
    }
    /* We have the initial and handle reference but need only one now */
    drm_gem_object_unreference(&r->gem);
    *handlep = handle;
    return 0;
}