/* Try to find sdvo panel data */
static void
parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
		      struct bdb_header *bdb)
{
	struct bdb_sdvo_lvds_options *sdvo_lvds_options;
	struct lvds_dvo_timing *dvo_timing;
	struct drm_display_mode *panel_fixed_mode;

	dev_priv->sdvo_lvds_vbt_mode = NULL;

	sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
	if (!sdvo_lvds_options)
		return;

	dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
	if (!dvo_timing)
		return;

	panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
				      DRM_MEM_DRIVER);

	if (!panel_fixed_mode)
		return;

	fill_detail_timing_data(panel_fixed_mode,
			dvo_timing + sdvo_lvds_options->panel_type);

	dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;

	return;
}
示例#2
0
/* Called by the X Server to initialize the FB heap.  Allocations will fail
 * unless this is called.  Offset is the beginning of the heap from the
 * framebuffer offset (MaxXFBMem in XFree86).
 *
 * Memory layout according to Thomas Winischofer:
 * |------------------|DDDDDDDDDDDDDDDDDDDDDDDDDDDDD|HHHH|CCCCCCCCCCC|
 *
 *    X driver/sisfb                                  HW-   Command-
 *  framebuffer memory           DRI heap           Cursor   queue
 */
static int sis_fb_init(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_sis_private_t *dev_priv = dev->dev_private;
	drm_sis_fb_t fb;

	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb));

	if (dev_priv == NULL) {
		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
					      DRM_MEM_DRIVER);
		dev_priv = dev->dev_private;
		if (dev_priv == NULL)
			return ENOMEM;
	}

	if (dev_priv->FBHeap != NULL)
		return DRM_ERR(EINVAL);

	dev_priv->FBHeap = mmInit(fb.offset, fb.size);

	DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);

	return 0;
}
示例#3
0
static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_sis_private_t *dev_priv = dev->dev_private;
	drm_sis_agp_t agp;

	if (dev_priv == NULL) {
		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
					      DRM_MEM_DRIVER);
		dev_priv = dev->dev_private;
		if (dev_priv == NULL)
			return ENOMEM;
	}

	if (dev_priv->AGPHeap != NULL)
		return DRM_ERR(EINVAL);

	DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data,
				 sizeof(agp));

	dev_priv->AGPHeap = mmInit(agp.offset, agp.size);

	DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);

	return 0;
}
示例#4
0
/**
 * Register.
 *
 * \param pdev - PCI device structure
 * \param ent entry from the PCI ID table with device type flags
 * \return zero on success or a negative number on failure.
 *
 * Attempt to gets inter module "drm" information. If we are first
 * then register the character device and inter module information.
 * Try and register, if we fail to register, backout previous work.
 */
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
		struct drm_driver *driver)
{
	drm_device_t *dev;
	int ret;

	DRM_DEBUG("\n");

	dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
	if (!dev)
		return -ENOMEM;

	pci_enable_device(pdev);

	if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
		printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
		goto err_g1;
	}
	if ((ret = drm_get_head(dev, &dev->primary)))
		goto err_g1;
	
	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
		 driver->name, driver->major, driver->minor, driver->patchlevel,
		 driver->date, dev->primary.minor);

	return 0;

      err_g1:
	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
	return ret;
}
示例#5
0
int drm_platform_init(struct drm_driver *driver)
{
	struct drm_device *dev;
	int ret;

	DRM_DEBUG("\n");

	dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
	if (!dev)
		return -ENOMEM;

	ret = drm_fill_in_platform_dev(dev, driver->platform_device,
					driver);
	if (ret) {
		printk(KERN_ERR "DRM: Fill_in_platform_dev failed.\n");
		goto err_g1;
	}

	ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);

	if (ret)
		goto err_g1;

	list_add_tail(&dev->driver_item, &driver->device_list);

	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
		 driver->name, driver->major, driver->minor, driver->patchlevel,
		 driver->date, dev->primary->index);

	return 0;

err_g1:
	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
	return ret;
}
示例#6
0
int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	drm_draw_t *draw = data;
	struct bsd_drm_drawable_info *info;

	info = drm_calloc(1, sizeof(struct bsd_drm_drawable_info),
	    DRM_MEM_DRAWABLE);
	if (info == NULL)
		return ENOMEM;

#ifdef __FreeBSD__
	info->handle = alloc_unr(dev->drw_unrhdr);
#else
	/* XXXJDM */
	info->handle = ++dev->drw_no;
#endif
	DRM_SPINLOCK(&dev->drw_lock);
	RB_INSERT(drawable_tree, &dev->drw_head, info);
	draw->handle = info->handle;
	DRM_SPINUNLOCK(&dev->drw_lock);

	DRM_DEBUG("%d\n", draw->handle);

	return 0;
}
示例#7
0
int
drm_sman_init(struct drm_sman * sman, unsigned int num_managers,
	      unsigned int user_order, unsigned int owner_order)
{
	int ret = 0;

	sman->mm = (struct drm_sman_mm *) drm_calloc(num_managers,
	    sizeof(*sman->mm), DRM_MEM_MM);
	if (!sman->mm) {
		ret = -ENOMEM;
		goto out;
	}
	sman->num_managers = num_managers;
	INIT_LIST_HEAD(&sman->owner_items);
	ret = drm_ht_create(&sman->owner_hash_tab, owner_order);
	if (ret)
		goto out1;
	ret = drm_ht_create(&sman->user_hash_tab, user_order);
	if (!ret)
		goto out;

	drm_ht_remove(&sman->owner_hash_tab);
out1:
	drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM);
out:
	return ret;
}
static int mali_driver_load(struct drm_device *dev, unsigned long chipset)
{
	int ret;
	unsigned long base, size;
	drm_mali_private_t *dev_priv;
	printk(KERN_ERR "DRM: mali_driver_load start\n");

	dev_priv = drm_calloc(1, sizeof(drm_mali_private_t), DRM_MEM_DRIVER);
	if ( dev_priv == NULL ) return -ENOMEM;

	dev->dev_private = (void *)dev_priv;

	if ( NULL == dev->platformdev )
	{
		dev->platformdev = platform_device_register_simple(mali_drm_device_name, 0, NULL, 0);
		pdev = dev->platformdev;
	}

	#if 0
	base = drm_get_resource_start(dev, 1 );
	size = drm_get_resource_len(dev, 1 );
	#endif
	ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
	if ( ret ) drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER);
	//if ( ret ) kfree( dev_priv );

	printk(KERN_ERR "DRM: mali_driver_load done\n");

	return ret;
}
示例#9
0
int
drm_queue_vblank_event(struct drm_device *dev, int crtc,
    union drm_wait_vblank *vblwait, struct drm_file *file_priv)
{
	struct drm_pending_vblank_event	*vev;
	struct timeval			 now;
	u_int				 seq;


	vev = drm_calloc(1, sizeof(*vev));
	if (vev == NULL)
		return (ENOMEM);

	vev->event.base.type = DRM_EVENT_VBLANK;
	vev->event.base.length = sizeof(vev->event);
	vev->event.user_data = vblwait->request.signal;
	vev->base.event = &vev->event.base;
	vev->base.file_priv = file_priv;
	vev->base.destroy = (void (*) (struct drm_pending_event *))drm_free;

	microtime(&now);

	mtx_enter(&dev->event_lock);
	if (file_priv->event_space < sizeof(vev->event)) {
		mtx_leave(&dev->event_lock);
		drm_free(vev);
		return (ENOMEM);
	}


	seq = drm_vblank_count(dev, crtc);
	file_priv->event_space -= sizeof(vev->event);

	DPRINTF("%s: queueing event %d on crtc %d\n", __func__, seq, crtc);

	if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
	    (seq - vblwait->request.sequence) <= (1 << 23)) {
		vblwait->request.sequence = seq + 1;
		vblwait->reply.sequence = vblwait->request.sequence;
	}

	vev->event.sequence = vblwait->request.sequence;
	if ((seq - vblwait->request.sequence) <= (1 << 23)) {
		vev->event.tv_sec = now.tv_sec;
		vev->event.tv_usec = now.tv_usec;
		DPRINTF("%s: already passed, dequeuing: crtc %d, value %d\n",
		    __func__, crtc, seq);
		drm_vblank_put(dev, crtc);
		TAILQ_INSERT_TAIL(&file_priv->evlist, &vev->base, link);
		wakeup(&file_priv->evlist);
		selwakeup(&file_priv->rsel);
	} else {
		TAILQ_INSERT_TAIL(&dev->vblank->vb_crtcs[crtc].vbl_events,
		    &vev->base, link);
	}
	mtx_leave(&dev->event_lock);

	return (0);
}
示例#10
0
static TMemBlock *SliceBlock(TMemBlock * p,
			     int startofs, int size,
			     int reserved, int alignment)
{
	TMemBlock *newblock;

	/* break left */
	if (startofs > p->ofs) {
		newblock =
		    (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
					     DRM_MEM_DRIVER);
		newblock->ofs = startofs;
		newblock->size = p->size - (startofs - p->ofs);
		newblock->free = 1;
		newblock->next = p->next;
		p->size -= newblock->size;
		p->next = newblock;
		p = newblock;
	}

	/* break right */
	if (size < p->size) {
		newblock =
		    (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
					     DRM_MEM_DRIVER);
		newblock->ofs = startofs + size;
		newblock->size = p->size - size;
		newblock->free = 1;
		newblock->next = p->next;
		p->size = size;
		p->next = newblock;
	}

	/* p = middle block */
	p->align = alignment;
	p->free = 0;
	p->reserved = reserved;
	return p;
}
示例#11
0
文件: drm_ttm.c 项目: jobi/drm-psb
static void ttm_alloc_pages(struct drm_ttm *ttm)
{
	unsigned long size = ttm->num_pages * sizeof(*ttm->pages);
	ttm->pages = NULL;

	if (size <= PAGE_SIZE)
		ttm->pages = drm_calloc(1, size, DRM_MEM_TTM);

	if (!ttm->pages) {
		ttm->pages = vmalloc_user(size);
		if (ttm->pages)
			ttm->page_flags |= DRM_TTM_PAGE_VMALLOC;
	}
}
示例#12
0
文件: via_map.c 项目: Ionic/nx-libs
int via_driver_load(drm_device_t *dev, unsigned long chipset)
{
	drm_via_private_t *dev_priv;

	dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
	if (dev_priv == NULL)
		return DRM_ERR(ENOMEM);

	dev->dev_private = (void *)dev_priv;

	if (chipset == VIA_PRO_GROUP_A)
		dev_priv->pro_group_a = 1;

	return 0;
}
示例#13
0
memHeap_t *mmInit(int ofs, int size)
{
	PMemBlock blocks;

	if (size <= 0)
		return NULL;

	blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
	if (blocks != NULL) {
		blocks->ofs = ofs;
		blocks->size = size;
		blocks->free = 1;
		return (memHeap_t *) blocks;
	} else
		return NULL;
}
示例#14
0
int
drm_dma_setup(drm_device_t *dev)
{
	int i;
	drm_buf_entry_t *pbuf;

	dev->dma = drm_calloc(1, sizeof (*dev->dma), DRM_MEM_DMA);
	if (dev->dma == NULL)
		return (ENOMEM);

	mutex_init(&dev->dma_lock, NULL, MUTEX_DRIVER, NULL);
	pbuf = &(dev->dma->bufs[0]);
	for (i = 0; i <= DRM_MAX_ORDER; i++, pbuf++)
		bzero(pbuf, sizeof (drm_buf_entry_t));

	return (0);
}
示例#15
0
static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
{
    drm_sis_private_t *dev_priv;
    int ret;

    dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER);
    if (dev_priv == NULL)
        return DRM_ERR(ENOMEM);

    dev->dev_private = (void *)dev_priv;
    dev_priv->chipset = chipset;
    ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
    if (ret) {
        drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER);
    }

    return ret;
}
示例#16
0
/* Try to find integrated panel data */
static void
parse_lfp_panel_data(struct drm_i915_private *dev_priv,
			    struct bdb_header *bdb)
{
	struct bdb_lvds_options *lvds_options;
	struct bdb_lvds_lfp_data *lvds_lfp_data;
	struct bdb_lvds_lfp_data_entry *entry;
	struct lvds_dvo_timing *dvo_timing;
	struct drm_display_mode *panel_fixed_mode;

	/* Defaults if we can't find VBT info */
	dev_priv->lvds_dither = 0;
	dev_priv->lvds_vbt = 0;

	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
	if (!lvds_options)
		return;

	dev_priv->lvds_dither = lvds_options->pixel_dither;
	if (lvds_options->panel_type == 0xff)
		return;

	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
	if (!lvds_lfp_data)
		return;

	dev_priv->lvds_vbt = 1;

	entry = &lvds_lfp_data->data[lvds_options->panel_type];
	dvo_timing = &entry->dvo_timing;

	panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
				      DRM_MEM_DRIVER);

	fill_detail_timing_data(panel_fixed_mode, dvo_timing);

	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;

	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
	drm_mode_debug_printmodeline(panel_fixed_mode);

	return;
}
示例#17
0
int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
		struct drm_driver *driver)
{
	struct drm_device *dev;
	int ret;

	DRM_DEBUG("\n");

	dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
	if (!dev)
		return -ENOMEM;

	ret = pci_enable_device(pdev);
	if (ret)
		goto err_g1;

	pci_set_master(pdev);

	ret = drm_fill_in_pci_dev(dev, pdev, ent, driver);
	if (ret) {
		printk(KERN_ERR "DRM: Fill_in_pci_dev failed.\n");
		goto err_g2;
	}

	ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
	if (ret)
		goto err_g2;

	list_add_tail(&dev->driver_item, &driver->device_list);

	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
		 driver->name, driver->major, driver->minor, driver->patchlevel,
		 driver->date, dev->primary->index);

	return 0;

err_g2:
	pci_disable_device(pdev);
err_g1:
	kfree(dev);
	return ret;
}
示例#18
0
文件: drm_drv.c 项目: Ionic/nx-libs
static int __init drm_core_init(void)
{
	int ret = -ENOMEM;

	cards_limit =
	    (cards_limit < DRM_MAX_MINOR + 1 ? cards_limit : DRM_MAX_MINOR + 1);
	drm_heads = drm_calloc(cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
	if (!drm_heads)
		goto err_p1;

	if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
		goto err_p1;

	drm_class = drm_sysfs_create(THIS_MODULE, "drm");
	if (IS_ERR(drm_class)) {
		printk(KERN_ERR "DRM: Error creating drm class.\n");
		ret = PTR_ERR(drm_class);
		goto err_p2;
	}

	drm_proc_root = create_proc_entry("dri", S_IFDIR, NULL);
	if (!drm_proc_root) {
		DRM_ERROR("Cannot create /proc/dri\n");
		ret = -1;
		goto err_p3;
	}

	drm_mem_init();

	DRM_INFO("Initialized %s %d.%d.%d %s\n",
		 CORE_NAME,
		 CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
	return 0;
err_p3:
	drm_sysfs_destroy(drm_class);
err_p2:
	unregister_chrdev(DRM_MAJOR, "drm");
	drm_free(drm_heads, sizeof(*drm_heads) * cards_limit, DRM_MEM_STUB);
err_p1:
	return ret;
}
示例#19
0
static int sis_ioctl_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	drm_sis_private_t *dev_priv = dev->dev_private;
	drm_sis_agp_t *agp = data;

	if (dev_priv == NULL) {
		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
					      DRM_MEM_DRIVER);
		dev_priv = dev->dev_private;
		if (dev_priv == NULL)
			return ENOMEM;
	}

	if (dev_priv->AGPHeap != NULL)
		return -EINVAL;

	dev_priv->AGPHeap = mmInit(agp->offset, agp->size);

	DRM_DEBUG("offset = %u, size = %u", agp->offset, agp->size);

	return 0;
}
示例#20
0
memHeap_t *via_mmAddRange(memHeap_t * heap, int ofs, int size)
{
	PMemBlock blocks;
	blocks = (TMemBlock *) drm_calloc(2, sizeof(TMemBlock), DRM_MEM_DRIVER);

	if (blocks) {
		blocks[0].size = size;
		blocks[0].free = 1;
		blocks[0].ofs = ofs;
		blocks[0].next = &blocks[1];

		/* Discontinuity - stops JoinBlock from trying to join non-adjacent
		 * ranges.
		 */
		blocks[1].size = 0;
		blocks[1].free = 0;
		blocks[1].ofs = ofs + size;
		blocks[1].next = (PMemBlock) heap;
		return (memHeap_t *) blocks;
	} else
		return heap;
}
示例#21
0
/**
 * Register.
 *
 * \param pdev - PCI device structure
 * \param ent entry from the PCI ID table with device type flags
 * \return zero on success or a negative number on failure.
 *
 * Attempt to gets inter module "drm" information. If we are first
 * then register the character device and inter module information.
 * Try and register, if we fail to register, backout previous work.
 */
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                struct drm_driver *driver)
{
    drm_device_t *dev;
    int ret;

    DRM_DEBUG("\n");

    dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
    if (!dev)
        return -ENOMEM;

    if (!drm_fb_loaded) {
        pci_set_drvdata(pdev, dev);
        pci_request_regions(pdev, driver->pci_driver.name);
        pci_enable_device(pdev);
    }
    if ((ret = fill_in_dev(dev, pdev, ent, driver))) {
        goto err_g1;
    }
    if ((ret = drm_get_head(dev, &dev->primary)))
        goto err_g1;

    DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
             driver->name, driver->major, driver->minor, driver->patchlevel,
             driver->date, dev->primary.minor, pci_pretty_name(dev->pdev));

    return 0;

err_g1:
    if (!drm_fb_loaded) {
        pci_set_drvdata(pdev, NULL);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
    }
    drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
    printk(KERN_ERR "DRM: drm_get_dev failed.\n");
    return ret;
}
示例#22
0
文件: drm_ttm.c 项目: jobi/drm-psb
struct drm_ttm *drm_ttm_init(struct drm_device *dev, unsigned long size)
{
	struct drm_bo_driver *bo_driver = dev->driver->bo_driver;
	struct drm_ttm *ttm;

	if (!bo_driver)
		return NULL;

	ttm = drm_calloc(1, sizeof(*ttm), DRM_MEM_TTM);
	if (!ttm)
		return NULL;

	ttm->dev = dev;
	atomic_set(&ttm->vma_count, 0);

	ttm->destroy = 0;
	ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;

	ttm->page_flags = 0;

	/*
	 * Account also for AGP module memory usage.
	 */

	ttm_alloc_pages(ttm);
	if (!ttm->pages) {
		drm_destroy_ttm(ttm);
		DRM_ERROR("Failed allocating page table\n");
		return NULL;
	}
	ttm->be = bo_driver->create_ttm_backend_entry(dev);
	if (!ttm->be) {
		drm_destroy_ttm(ttm);
		DRM_ERROR("Failed creating ttm backend entry\n");
		return NULL;
	}
	ttm->state = ttm_unpopulated;
	return ttm;
}
int nouveau_load(struct drm_device *dev, unsigned long flags)
{
	struct drm_nouveau_private *dev_priv;
	void __iomem *regs;
	uint32_t reg0,reg1;
	uint8_t architecture = 0;

	dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
	if (!dev_priv)
		return -ENOMEM;

	dev_priv->flags = flags & NOUVEAU_FLAGS;
	dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;

	DRM_DEBUG("vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class);

	/* Time to determine the card architecture */
	regs = ioremap_nocache(pci_resource_start(dev->pdev, 0), 0x8);
	if (!regs) {
		DRM_ERROR("Could not ioremap to determine register\n");
		return -ENOMEM;
	}

	reg0 = readl(regs+NV03_PMC_BOOT_0);
	reg1 = readl(regs+NV03_PMC_BOOT_1);
#if defined(__powerpc__)
	if (reg1)
		reg0=__swab32(reg0);
#endif

	/* We're dealing with >=NV10 */
	if ((reg0 & 0x0f000000) > 0 ) {
		/* Bit 27-20 contain the architecture in hex */
		architecture = (reg0 & 0xff00000) >> 20;
	/* NV04 or NV05 */
	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
示例#24
0
int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
    struct drm_update_draw *update = data;
    unsigned long irqflags;
    struct drm_clip_rect *rects;
    struct drm_drawable_info *info;
    int err;

    info = idr_find(&dev->drw_idr, update->handle);
    if (!info) {
        info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS);
        if (!info)
            return -ENOMEM;
        if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) {
            DRM_ERROR("No such drawable %d\n", update->handle);
            drm_free(info, sizeof(*info), DRM_MEM_BUFS);
            return -EINVAL;
        }
    }

    switch (update->type) {
    case DRM_DRAWABLE_CLIPRECTS:
        if (update->num != info->num_rects) {
            rects = drm_alloc(update->num * sizeof(struct drm_clip_rect),
                     DRM_MEM_BUFS);
        } else
            rects = info->rects;

        if (update->num && !rects) {
            DRM_ERROR("Failed to allocate cliprect memory\n");
            err = -ENOMEM;
            goto error;
        }

        if (update->num && DRM_COPY_FROM_USER(rects,
                             (struct drm_clip_rect __user *)
                             (unsigned long)update->data,
                             update->num *
                             sizeof(*rects))) {
            DRM_ERROR("Failed to copy cliprects from userspace\n");
            err = -EFAULT;
            goto error;
        }

        spin_lock_irqsave(&dev->drw_lock, irqflags);

        if (rects != info->rects) {
            drm_free(info->rects, info->num_rects *
                 sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
        }

        info->rects = rects;
        info->num_rects = update->num;

        spin_unlock_irqrestore(&dev->drw_lock, irqflags);

        DRM_DEBUG("Updated %d cliprects for drawable %d\n",
              info->num_rects, update->handle);
        break;
    default:
        DRM_ERROR("Invalid update type %d\n", update->type);
        return -EINVAL;
    }

    return 0;

error:
    if (rects != info->rects)
        drm_free(rects, update->num * sizeof(struct drm_clip_rect),
             DRM_MEM_BUFS);

    return err;
}
示例#25
0
static int fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
                       const struct pci_device_id *ent,
                       struct drm_driver *driver)
{
    int retcode;

    spin_lock_init(&dev->count_lock);
    init_timer(&dev->timer);
    sema_init(&dev->struct_sem, 1);
    sema_init(&dev->ctxlist_sem, 1);

    dev->pdev = pdev;

#ifdef __alpha__
    dev->hose = pdev->sysdata;
    dev->pci_domain = dev->hose->bus->number;
#else
    dev->pci_domain = 0;
#endif
    dev->pci_bus = pdev->bus->number;
    dev->pci_slot = PCI_SLOT(pdev->devfn);
    dev->pci_func = PCI_FUNC(pdev->devfn);
    dev->irq = pdev->irq;

    dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
    if (dev->maplist == NULL)
        return -ENOMEM;
    INIT_LIST_HEAD(&dev->maplist->head);

    /* the DRM has 6 counters */
    dev->counters = 6;
    dev->types[0] = _DRM_STAT_LOCK;
    dev->types[1] = _DRM_STAT_OPENS;
    dev->types[2] = _DRM_STAT_CLOSES;
    dev->types[3] = _DRM_STAT_IOCTLS;
    dev->types[4] = _DRM_STAT_LOCKS;
    dev->types[5] = _DRM_STAT_UNLOCKS;

    dev->driver = driver;

    if (dev->driver->load)
        if ((retcode = dev->driver->load(dev, ent->driver_data)))
            goto error_out_unreg;

    if (drm_core_has_AGP(dev)) {
        if (drm_device_is_agp(dev))
            dev->agp = drm_agp_init(dev);
        if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
                && (dev->agp == NULL)) {
            DRM_ERROR("Cannot initialize the agpgart module.\n");
            retcode = -EINVAL;
            goto error_out_unreg;
        }

        if (drm_core_has_MTRR(dev)) {
            if (dev->agp)
                dev->agp->agp_mtrr =
                    mtrr_add(dev->agp->agp_info.aper_base,
                             dev->agp->agp_info.aper_size *
                             1024 * 1024, MTRR_TYPE_WRCOMB, 1);
        }
    }

    retcode = drm_ctxbitmap_init(dev);
    if (retcode) {
        DRM_ERROR("Cannot allocate memory for context bitmap.\n");
        goto error_out_unreg;
    }

    return 0;

error_out_unreg:
    drm_lastclose(dev);
    return retcode;
}