/**
 * Called whenever a 32-bit process running under a 64-bit kernel
 * performs an ioctl on /dev/dri/card<n>.
 *
 * \param filp file pointer.
 * \param cmd command.
 * \param arg user argument.
 * \return zero on success or negative number on failure.
 */
long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	unsigned int nr = DRM_IOCTL_NR(cmd);
	drm_ioctl_compat_t *fn = NULL;
	struct drm_file *file_priv = filp->private_data;
	struct drm_device *dev = file_priv->minor->dev;
	int ret;

	i915_rpm_get_ioctl(dev);
	if (nr < DRM_COMMAND_BASE) {
		ret = drm_compat_ioctl(filp, cmd, arg);
		goto out;
	}

	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];


	if (fn != NULL)
		ret = (*fn) (filp, cmd, arg);
	else
		ret = drm_ioctl(filp, cmd, arg);

out:
	i915_rpm_put_ioctl(dev);

	return ret;
}
/**
 * Called whenever a 32-bit process running under a 64-bit kernel
 * performs an ioctl on /dev/dri/card<n>.
 *
 * \param filp file pointer.
 * \param cmd command.
 * \param arg user argument.
 * \return zero on success or negative number on failure.
 */
long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    unsigned int nr = DRM_IOCTL_NR(cmd);
    drm_ioctl_compat_t *fn = NULL;
    struct drm_file *file_priv = filp->private_data;
    struct drm_device *dev = file_priv->minor->dev;
    int ret;

    i915_rpm_get_ioctl(dev);
    if (nr < DRM_COMMAND_BASE) {
        ret = drm_compat_ioctl(filp, cmd, arg);
        goto out;
    }

    if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
        fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];

    if (fn != NULL) {
        ret = (*fn) (filp, cmd, arg);
    } else {
#ifdef CONFIG_DRM_VXD_BYT
        unsigned int nr = DRM_IOCTL_NR(cmd);
        struct drm_i915_private *dev_priv = dev->dev_private;

        if ((nr >= DRM_COMMAND_VXD_BASE) &&
                (nr < DRM_COMMAND_VXD_BASE + 0x10)) {
            BUG_ON(!dev_priv->vxd_ioctl);
            ret = dev_priv->vxd_ioctl(filp, cmd, arg);
        } else
#endif
        {
            ret = drm_ioctl(filp, cmd, arg);
        }
    }

out:
    i915_rpm_put_ioctl(dev);

    return ret;
}