/** * Allocate AGP memory. * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_agp_buffer structure. * \return zero on success or a negative number on failure. * * Verifies the AGP device is present and has been acquired, allocates the * memory via alloc_agp() and creates a drm_agp_mem entry for it. */ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_agp_buffer_t request; drm_agp_mem_t *entry; DRM_AGP_MEM *memory; unsigned long pages; u32 type; drm_agp_buffer_t __user *argp = (void __user *)arg; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; memset(entry, 0, sizeof(*entry)); pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u32) request.type; if (!(memory = drm_alloc_agp(dev, pages, type))) { drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -ENOMEM; } entry->handle = (unsigned long)memory->key + 1; entry->memory = memory; entry->bound = 0; entry->pages = pages; entry->prev = NULL; entry->next = dev->agp->memory; if (dev->agp->memory) dev->agp->memory->prev = entry; dev->agp->memory = entry; request.handle = entry->handle; request.physical = memory->physical; if (copy_to_user(argp, &request, sizeof(request))) { dev->agp->memory = entry->next; dev->agp->memory->prev = NULL; drm_free_agp(memory, pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -EFAULT; } return 0; }
/** * Allocate AGP memory. * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_agp_buffer structure. * \return zero on success or a negative number on failure. * * Verifies the AGP device is present and has been acquired, allocates the * memory via alloc_agp() and creates a drm_agp_mem entry for it. */ int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request) { drm_agp_mem_t *entry; DRM_AGP_MEM *memory; unsigned long pages; u32 type; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) return -ENOMEM; memset(entry, 0, sizeof(*entry)); pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; type = (u32) request->type; if (!(memory = drm_alloc_agp(dev, pages, type))) { drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return -ENOMEM; } entry->handle = (unsigned long)memory->key + 1; entry->memory = memory; entry->bound = 0; entry->pages = pages; entry->prev = NULL; entry->next = dev->agp->memory; if (dev->agp->memory) dev->agp->memory->prev = entry; dev->agp->memory = entry; request->handle = entry->handle; request->physical = memory->physical; return 0; }