int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { drm_version_t version; int len; if (copy_from_user(&version, (drm_version_t *)arg, sizeof(version))) return -EFAULT; #define DRM_COPY(name,value) \ len = strlen(value); \ if (len > name##_len) len = name##_len; \ name##_len = strlen(value); \ if (len && name) { \ if (copy_to_user(name, value, len)) \ return -EFAULT; \ } version.version_major = TDFX_MAJOR; version.version_minor = TDFX_MINOR; version.version_patchlevel = TDFX_PATCHLEVEL; DRM_COPY(version.name, TDFX_NAME); DRM_COPY(version.date, TDFX_DATE); DRM_COPY(version.desc, TDFX_DESC); if (copy_to_user((drm_version_t *)arg, &version, sizeof(version))) return -EFAULT; return 0; }
static int version( drm_version_t *version ) { int len; version->version_major = DRIVER_MAJOR; version->version_minor = DRIVER_MINOR; version->version_patchlevel = DRIVER_PATCHLEVEL; DRM_COPY( version->name, DRIVER_NAME ); DRM_COPY( version->date, DRIVER_DATE ); DRM_COPY( version->desc, DRIVER_DESC ); return 0; }
/** * Get version information * * \param inode device inode. * \param filp file pointer. * \param cmd command. * \param arg user argument, pointing to a drm_version structure. * \return zero on success or negative number on failure. * * Fills in the version information in \p arg. */ static int drm_version(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_version_t __user *argp = (void __user *)arg; drm_version_t version; int len; if (copy_from_user(&version, argp, sizeof(version))) return -EFAULT; version.version_major = dev->driver->major; version.version_minor = dev->driver->minor; version.version_patchlevel = dev->driver->patchlevel; DRM_COPY(version.name, dev->driver->name); DRM_COPY(version.date, dev->driver->date); DRM_COPY(version.desc, dev->driver->desc); if (copy_to_user(argp, &version, sizeof(version))) return -EFAULT; return 0; }