int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) { drm_agp_mem_t *entry; int retcode; int page; if (!dev->agp || !dev->agp->acquired) return EINVAL; DRM_DEBUG("agp_bind, page_size=%x\n", (int)PAGE_SIZE); entry = drm_agp_lookup_entry(dev, (void *)request->handle); if (entry == NULL || entry->bound) return EINVAL; page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; DRM_UNLOCK(dev); retcode = drm_agp_bind_memory(entry->handle, page); DRM_LOCK(dev); if (retcode == 0) entry->bound = dev->agp->base + (page << PAGE_SHIFT); return retcode; }
int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) { drm_agp_mem_t *entry; if (!dev->agp || !dev->agp->acquired) return EINVAL; entry = drm_agp_lookup_entry(dev, (void*)request->handle); if (entry == NULL) return EINVAL; if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; DRM_UNLOCK(dev); if (entry->bound) drm_agp_unbind_memory(entry->handle); drm_agp_free_memory(entry->handle); DRM_LOCK(dev); free(entry, DRM_MEM_AGPLISTS); return 0; }
/** * Free AGP memory (ioctl). * * \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 and looks up the * AGP memory entry. If the memory it's currently bound, unbind it via * unbind_agp(). Frees it via free_agp() as well as the entry itself * and unlinks from the doubly linked list it's inserted in. */ int drm_agp_free(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; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) drm_unbind_agp(entry->memory); if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; drm_free_agp(entry->memory, entry->pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; }
/** * Bind AGP memory into the GATT (ioctl) * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_agp_binding structure. * \return zero on success or a negative number on failure. * * Verifies the AGP device is present and has been acquired and that no memory * is currently bound into the GATT. Looks-up the AGP memory entry and passes * it to bind_agp() function. */ int drm_agp_bind(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_binding_t request; drm_agp_mem_t *entry; int retcode; int page; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (entry->bound) return -EINVAL; page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; if ((retcode = drm_bind_agp(entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", dev->agp->base, entry->bound); return 0; }
/** * Unbind AGP memory from the GATT (ioctl). * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_agp_binding structure. * \return zero on success or a negative number on failure. * * Verifies the AGP device is present and acquired, looks-up the AGP memory * entry and passes it to the unbind_agp() function. */ int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request) { drm_agp_mem_t *entry; int ret; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (!(entry = drm_agp_lookup_entry(dev, request->handle))) return -EINVAL; if (!entry->bound) return -EINVAL; ret = drm_unbind_agp(entry->memory); if (ret == 0) entry->bound = 0; return ret; }
int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) { drm_agp_mem_t *entry; int retcode; if (!dev->agp || !dev->agp->acquired) return EINVAL; entry = drm_agp_lookup_entry(dev, (void *)request->handle); if (entry == NULL || !entry->bound) return EINVAL; retcode = drm_agp_unbind_memory(entry->handle); if (retcode == 0) entry->bound = 0; return retcode; }
/** * Bind AGP memory into the GATT (ioctl) * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_agp_binding structure. * \return zero on success or a negative number on failure. * * Verifies the AGP device is present and has been acquired and that no memory * is currently bound into the GATT. Looks-up the AGP memory entry and passes * it to bind_agp() function. */ int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request) { drm_agp_mem_t *entry; int retcode; int page; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (!(entry = drm_agp_lookup_entry(dev, request->handle))) return -EINVAL; if (entry->bound) return -EINVAL; page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; if ((retcode = drm_bind_agp(entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", dev->agp->base, entry->bound); return 0; }
/** * Unbind AGP memory from the GATT (ioctl). * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg pointer to a drm_agp_binding structure. * \return zero on success or a negative number on failure. * * Verifies the AGP device is present and acquired, looks-up the AGP memory * entry and passes it to the unbind_agp() function. */ int drm_agp_unbind(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_binding_t request; drm_agp_mem_t *entry; int ret; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request))) return -EFAULT; if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; if (!entry->bound) return -EINVAL; ret = drm_unbind_agp(entry->memory); if (ret == 0) entry->bound = 0; return ret; }
/** * Free AGP memory (ioctl). * * \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 and looks up the * AGP memory entry. If the memory it's currently bound, unbind it via * unbind_agp(). Frees it via free_agp() as well as the entry itself * and unlinks from the doubly linked list it's inserted in. */ int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request) { drm_agp_mem_t *entry; if (!dev->agp || !dev->agp->acquired) return -EINVAL; if (!(entry = drm_agp_lookup_entry(dev, request->handle))) return -EINVAL; if (entry->bound) drm_unbind_agp(entry->memory); if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; drm_free_agp(entry->memory, entry->pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; }