[58129] | 1 | /* $Id: vbox_drv.c 102874 2024-01-15 12:08:04Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
[48115] | 3 | * VirtualBox Additions Linux kernel video driver
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2013-2023 Oracle and/or its affiliates.
|
---|
[66544] | 8 | * This file is based on ast_drv.c
|
---|
[48115] | 9 | * Copyright 2012 Red Hat Inc.
|
---|
| 10 | *
|
---|
| 11 | * Permission is hereby granted, free of charge, to any person obtaining a
|
---|
| 12 | * copy of this software and associated documentation files (the
|
---|
| 13 | * "Software"), to deal in the Software without restriction, including
|
---|
| 14 | * without limitation the rights to use, copy, modify, merge, publish,
|
---|
| 15 | * distribute, sub license, and/or sell copies of the Software, and to
|
---|
| 16 | * permit persons to whom the Software is furnished to do so, subject to
|
---|
| 17 | * the following conditions:
|
---|
| 18 | *
|
---|
| 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
| 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
| 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
---|
| 22 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
---|
| 23 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
---|
| 24 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
---|
| 25 | * USE OR OTHER DEALINGS IN THE SOFTWARE.
|
---|
| 26 | *
|
---|
| 27 | * The above copyright notice and this permission notice (including the
|
---|
| 28 | * next paragraph) shall be included in all copies or substantial portions
|
---|
| 29 | * of the Software.
|
---|
| 30 | *
|
---|
| 31 | * Authors: Dave Airlie <airlied@redhat.com>
|
---|
[66544] | 32 | * Michael Thayer <michael.thayer@oracle.com,
|
---|
| 33 | * Hans de Goede <hdegoede@redhat.com>
|
---|
[48115] | 34 | */
|
---|
| 35 | #include <linux/module.h>
|
---|
| 36 | #include <linux/console.h>
|
---|
[60104] | 37 | #include <linux/vt_kern.h>
|
---|
[48115] | 38 |
|
---|
[83109] | 39 | #include "vbox_drv.h"
|
---|
| 40 |
|
---|
[48115] | 41 | #include <drm/drm_crtc_helper.h>
|
---|
[85705] | 42 | #if RTLNX_VER_MIN(5,1,0) || RTLNX_RHEL_MAJ_PREREQ(8,1)
|
---|
[85707] | 43 | # include <drm/drm_probe_helper.h>
|
---|
[77850] | 44 | #endif
|
---|
| 45 |
|
---|
[94330] | 46 | #if RTLNX_VER_MIN(5,14,0) || RTLNX_RHEL_RANGE(8,6, 8,99)
|
---|
[90498] | 47 | # include <drm/drm_aperture.h>
|
---|
| 48 | #endif
|
---|
| 49 |
|
---|
[74773] | 50 | #include "version-generated.h"
|
---|
| 51 | #include "revision-generated.h"
|
---|
| 52 |
|
---|
[93416] | 53 | /** Detect whether kernel mode setting is OFF. */
|
---|
| 54 | #if defined(CONFIG_VGA_CONSOLE)
|
---|
[100677] | 55 | # if RTLNX_VER_MIN(5,17,0) || RTLNX_RHEL_RANGE(8,7, 8,99) || RTLNX_RHEL_MIN(9,1) || RTLNX_SUSE_MAJ_PREREQ(15,5)
|
---|
[93416] | 56 | # define VBOX_VIDEO_NOMODESET() drm_firmware_drivers_only() && vbox_modeset == -1
|
---|
| 57 | # elif RTLNX_VER_MIN(4,7,0)
|
---|
| 58 | # define VBOX_VIDEO_NOMODESET() vgacon_text_force() && vbox_modeset == -1
|
---|
| 59 | # else /* < 4.7.0 */
|
---|
| 60 | # define VBOX_VIDEO_NOMODESET() 0
|
---|
| 61 | # endif /* < 4.7.0 */
|
---|
| 62 | #else /* !CONFIG_VGA_CONSOLE */
|
---|
| 63 | # define VBOX_VIDEO_NOMODESET() 0
|
---|
| 64 | #endif /* !CONFIG_VGA_CONSOLE */
|
---|
| 65 |
|
---|
[74810] | 66 | static int vbox_modeset = -1;
|
---|
[48115] | 67 |
|
---|
| 68 | MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
|
---|
| 69 | module_param_named(modeset, vbox_modeset, int, 0400);
|
---|
| 70 |
|
---|
| 71 | static struct drm_driver driver;
|
---|
| 72 |
|
---|
[67395] | 73 | static const struct pci_device_id pciidlist[] = {
|
---|
| 74 | { 0x80ee, 0xbeef, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
---|
| 75 | { 0, 0, 0},
|
---|
[48115] | 76 | };
|
---|
| 77 | MODULE_DEVICE_TABLE(pci, pciidlist);
|
---|
| 78 |
|
---|
| 79 | static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
---|
| 80 | {
|
---|
[86196] | 81 | #if RTLNX_VER_MIN(4,19,0) || RTLNX_RHEL_MIN(8,3)
|
---|
[76976] | 82 | struct drm_device *dev = NULL;
|
---|
| 83 | int ret = 0;
|
---|
| 84 |
|
---|
[94330] | 85 | # if RTLNX_VER_MIN(5,14,0) || RTLNX_RHEL_RANGE(8,6, 8,99)
|
---|
[97566] | 86 | # if RTLNX_VER_MIN(5,15,0) || RTLNX_RHEL_RANGE(8,7, 8,99) || RTLNX_RHEL_MIN(9,1) || RTLNX_SUSE_MAJ_PREREQ(15,4)
|
---|
[91233] | 87 | ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
|
---|
| 88 | # else
|
---|
[90498] | 89 | ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "vboxvideofb");
|
---|
[91233] | 90 | # endif
|
---|
[90498] | 91 | if (ret)
|
---|
| 92 | {
|
---|
| 93 | printk("unable to remove conflicting framebuffer devices\n");
|
---|
| 94 | return ret;
|
---|
| 95 | }
|
---|
[91233] | 96 | # endif /* >= 5.14. */
|
---|
[90498] | 97 |
|
---|
[76976] | 98 | dev = drm_dev_alloc(&driver, &pdev->dev);
|
---|
| 99 | if (IS_ERR(dev)) {
|
---|
| 100 | ret = PTR_ERR(dev);
|
---|
| 101 | goto err_drv_alloc;
|
---|
| 102 | }
|
---|
[94330] | 103 | # if RTLNX_VER_MAX(5,14,0) && !RTLNX_RHEL_RANGE(8,6, 8,99)
|
---|
[76976] | 104 | dev->pdev = pdev;
|
---|
[90583] | 105 | # endif
|
---|
[76976] | 106 | pci_set_drvdata(pdev, dev);
|
---|
| 107 |
|
---|
| 108 | ret = vbox_driver_load(dev);
|
---|
| 109 | if (ret)
|
---|
| 110 | goto err_vbox_driver_load;
|
---|
| 111 |
|
---|
| 112 | ret = drm_dev_register(dev, 0);
|
---|
| 113 | if (ret)
|
---|
| 114 | goto err_drv_dev_register;
|
---|
| 115 | return ret;
|
---|
| 116 |
|
---|
| 117 | err_drv_dev_register:
|
---|
| 118 | vbox_driver_unload(dev);
|
---|
| 119 | err_vbox_driver_load:
|
---|
| 120 | drm_dev_put(dev);
|
---|
| 121 | err_drv_alloc:
|
---|
| 122 | return ret;
|
---|
[86196] | 123 | #else /* < 4.19.0 || RHEL < 8.3 */
|
---|
| 124 | return drm_get_pci_dev(pdev, ent, &driver);
|
---|
[76976] | 125 | #endif
|
---|
[48115] | 126 | }
|
---|
| 127 |
|
---|
[49518] | 128 | static void vbox_pci_remove(struct pci_dev *pdev)
|
---|
[48115] | 129 | {
|
---|
[67395] | 130 | struct drm_device *dev = pci_get_drvdata(pdev);
|
---|
[48115] | 131 |
|
---|
[85704] | 132 | #if RTLNX_VER_MAX(4,19,0)
|
---|
[67395] | 133 | drm_put_dev(dev);
|
---|
[76976] | 134 | #else
|
---|
| 135 | drm_dev_unregister(dev);
|
---|
| 136 | vbox_driver_unload(dev);
|
---|
| 137 | drm_dev_put(dev);
|
---|
| 138 | #endif
|
---|
[48115] | 139 | }
|
---|
| 140 |
|
---|
[85705] | 141 | #if RTLNX_VER_MAX(4,9,0) && !RTLNX_RHEL_MAJ_PREREQ(7,4)
|
---|
[74773] | 142 | static void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
|
---|
| 143 | bool suspend)
|
---|
| 144 | {
|
---|
| 145 | if (!fb_helper || !fb_helper->fbdev)
|
---|
| 146 | return;
|
---|
| 147 |
|
---|
| 148 | console_lock();
|
---|
| 149 | fb_set_suspend(fb_helper->fbdev, suspend);
|
---|
| 150 | console_unlock();
|
---|
| 151 | }
|
---|
| 152 | #endif
|
---|
| 153 |
|
---|
[59526] | 154 | static int vbox_drm_freeze(struct drm_device *dev)
|
---|
| 155 | {
|
---|
[74773] | 156 | struct vbox_private *vbox = dev->dev_private;
|
---|
| 157 |
|
---|
[67395] | 158 | drm_kms_helper_poll_disable(dev);
|
---|
[59526] | 159 |
|
---|
[90498] | 160 | pci_save_state(VBOX_DRM_TO_PCI_DEV(dev));
|
---|
[59526] | 161 |
|
---|
[74773] | 162 | drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true);
|
---|
[67395] | 163 |
|
---|
| 164 | return 0;
|
---|
[59526] | 165 | }
|
---|
| 166 |
|
---|
| 167 | static int vbox_drm_thaw(struct drm_device *dev)
|
---|
| 168 | {
|
---|
[74773] | 169 | struct vbox_private *vbox = dev->dev_private;
|
---|
| 170 |
|
---|
[67395] | 171 | drm_mode_config_reset(dev);
|
---|
| 172 | drm_helper_resume_force_mode(dev);
|
---|
[74773] | 173 | drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false);
|
---|
[59526] | 174 |
|
---|
[67395] | 175 | return 0;
|
---|
[59526] | 176 | }
|
---|
| 177 |
|
---|
| 178 | static int vbox_drm_resume(struct drm_device *dev)
|
---|
| 179 | {
|
---|
[67395] | 180 | int ret;
|
---|
[59526] | 181 |
|
---|
[90498] | 182 | if (pci_enable_device(VBOX_DRM_TO_PCI_DEV(dev)))
|
---|
[67395] | 183 | return -EIO;
|
---|
[59526] | 184 |
|
---|
[67395] | 185 | ret = vbox_drm_thaw(dev);
|
---|
| 186 | if (ret)
|
---|
| 187 | return ret;
|
---|
[59526] | 188 |
|
---|
[67395] | 189 | drm_kms_helper_poll_enable(dev);
|
---|
| 190 |
|
---|
| 191 | return 0;
|
---|
[59526] | 192 | }
|
---|
| 193 |
|
---|
| 194 | static int vbox_pm_suspend(struct device *dev)
|
---|
| 195 | {
|
---|
[67395] | 196 | struct pci_dev *pdev = to_pci_dev(dev);
|
---|
| 197 | struct drm_device *ddev = pci_get_drvdata(pdev);
|
---|
| 198 | int error;
|
---|
[59526] | 199 |
|
---|
[67395] | 200 | error = vbox_drm_freeze(ddev);
|
---|
| 201 | if (error)
|
---|
| 202 | return error;
|
---|
[59526] | 203 |
|
---|
[67395] | 204 | pci_disable_device(pdev);
|
---|
| 205 | pci_set_power_state(pdev, PCI_D3hot);
|
---|
| 206 |
|
---|
| 207 | return 0;
|
---|
[59526] | 208 | }
|
---|
| 209 |
|
---|
| 210 | static int vbox_pm_resume(struct device *dev)
|
---|
| 211 | {
|
---|
[67395] | 212 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
|
---|
| 213 |
|
---|
| 214 | return vbox_drm_resume(ddev);
|
---|
[59526] | 215 | }
|
---|
| 216 |
|
---|
| 217 | static int vbox_pm_freeze(struct device *dev)
|
---|
| 218 | {
|
---|
[67395] | 219 | struct pci_dev *pdev = to_pci_dev(dev);
|
---|
| 220 | struct drm_device *ddev = pci_get_drvdata(pdev);
|
---|
[59526] | 221 |
|
---|
[67395] | 222 | if (!ddev || !ddev->dev_private)
|
---|
| 223 | return -ENODEV;
|
---|
[59526] | 224 |
|
---|
[67395] | 225 | return vbox_drm_freeze(ddev);
|
---|
[59526] | 226 | }
|
---|
| 227 |
|
---|
| 228 | static int vbox_pm_thaw(struct device *dev)
|
---|
| 229 | {
|
---|
[67395] | 230 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
|
---|
| 231 |
|
---|
| 232 | return vbox_drm_thaw(ddev);
|
---|
[59526] | 233 | }
|
---|
| 234 |
|
---|
| 235 | static int vbox_pm_poweroff(struct device *dev)
|
---|
| 236 | {
|
---|
[67395] | 237 | struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
|
---|
[59526] | 238 |
|
---|
[67395] | 239 | return vbox_drm_freeze(ddev);
|
---|
[59526] | 240 | }
|
---|
| 241 |
|
---|
| 242 | static const struct dev_pm_ops vbox_pm_ops = {
|
---|
[67395] | 243 | .suspend = vbox_pm_suspend,
|
---|
| 244 | .resume = vbox_pm_resume,
|
---|
| 245 | .freeze = vbox_pm_freeze,
|
---|
| 246 | .thaw = vbox_pm_thaw,
|
---|
| 247 | .poweroff = vbox_pm_poweroff,
|
---|
| 248 | .restore = vbox_pm_resume,
|
---|
[59526] | 249 | };
|
---|
| 250 |
|
---|
[67395] | 251 | static struct pci_driver vbox_pci_driver = {
|
---|
| 252 | .name = DRIVER_NAME,
|
---|
| 253 | .id_table = pciidlist,
|
---|
| 254 | .probe = vbox_pci_probe,
|
---|
| 255 | .remove = vbox_pci_remove,
|
---|
| 256 | .driver.pm = &vbox_pm_ops,
|
---|
[48115] | 257 | };
|
---|
| 258 |
|
---|
[85705] | 259 | #if RTLNX_VER_MAX(4,7,0) && !RTLNX_RHEL_MAJ_PREREQ(7,4)
|
---|
[63551] | 260 | /* This works around a bug in X servers prior to 1.18.4, which sometimes
|
---|
| 261 | * submit more dirty rectangles than the kernel is willing to handle and
|
---|
| 262 | * then disable dirty rectangle handling altogether when they see the
|
---|
| 263 | * EINVAL error. I do not want the code to hang around forever, which is
|
---|
| 264 | * why I am limiting it to certain kernel versions. We can increase the
|
---|
| 265 | * limit if some distributions uses old X servers with new kernels. */
|
---|
[67395] | 266 | long vbox_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
---|
[63551] | 267 | {
|
---|
[67395] | 268 | long rc = drm_ioctl(filp, cmd, arg);
|
---|
| 269 |
|
---|
| 270 | if (cmd == DRM_IOCTL_MODE_DIRTYFB && rc == -EINVAL)
|
---|
| 271 | return -EOVERFLOW;
|
---|
| 272 |
|
---|
| 273 | return rc;
|
---|
[63551] | 274 | }
|
---|
[85705] | 275 | #endif /* RTLNX_VER_MAX(4,7,0) && !RTLNX_RHEL_MAJ_PREREQ(7,4) */
|
---|
[63551] | 276 |
|
---|
[67395] | 277 | static const struct file_operations vbox_fops = {
|
---|
| 278 | .owner = THIS_MODULE,
|
---|
| 279 | .open = drm_open,
|
---|
| 280 | .release = drm_release,
|
---|
[85705] | 281 | #if RTLNX_VER_MAX(4,7,0) && !RTLNX_RHEL_MAJ_PREREQ(7,4)
|
---|
[67395] | 282 | .unlocked_ioctl = vbox_ioctl,
|
---|
[63551] | 283 | #else
|
---|
[67395] | 284 | .unlocked_ioctl = drm_ioctl,
|
---|
[63551] | 285 | #endif
|
---|
[67395] | 286 | .mmap = vbox_mmap,
|
---|
| 287 | .poll = drm_poll,
|
---|
[85705] | 288 | #if RTLNX_VER_MAX(3,12,0) && !RTLNX_RHEL_MAJ_PREREQ(7,0)
|
---|
[67395] | 289 | .fasync = drm_fasync,
|
---|
[52599] | 290 | #endif
|
---|
[48115] | 291 | #ifdef CONFIG_COMPAT
|
---|
[67395] | 292 | .compat_ioctl = drm_compat_ioctl,
|
---|
[48115] | 293 | #endif
|
---|
[67395] | 294 | .read = drm_read,
|
---|
[48115] | 295 | };
|
---|
| 296 |
|
---|
[89690] | 297 | #if RTLNX_VER_MIN(5,9,0) || RTLNX_RHEL_MIN(8,4) || RTLNX_SUSE_MAJ_PREREQ(15,3)
|
---|
[86542] | 298 | static void
|
---|
| 299 | #else
|
---|
| 300 | static int
|
---|
| 301 | #endif
|
---|
[86547] | 302 | vbox_master_set(struct drm_device *dev,
|
---|
| 303 | struct drm_file *file_priv, bool from_open)
|
---|
[60352] | 304 | {
|
---|
[67395] | 305 | struct vbox_private *vbox = dev->dev_private;
|
---|
| 306 |
|
---|
| 307 | /*
|
---|
| 308 | * We do not yet know whether the new owner can handle hotplug, so we
|
---|
| 309 | * do not advertise dynamic modes on the first query and send a
|
---|
| 310 | * tentative hotplug notification after that to see if they query again.
|
---|
| 311 | */
|
---|
| 312 | vbox->initial_mode_queried = false;
|
---|
| 313 |
|
---|
| 314 | mutex_lock(&vbox->hw_mutex);
|
---|
[74581] | 315 | /* Start the refresh timer in case the user does not provide dirty
|
---|
| 316 | * rectangles. */
|
---|
| 317 | vbox->need_refresh_timer = true;
|
---|
| 318 | schedule_delayed_work(&vbox->refresh_work, VBOX_REFRESH_PERIOD);
|
---|
[67395] | 319 | mutex_unlock(&vbox->hw_mutex);
|
---|
| 320 |
|
---|
[89690] | 321 | #if RTLNX_VER_MAX(5,9,0) && !RTLNX_RHEL_MAJ_PREREQ(8,4) && !RTLNX_SUSE_MAJ_PREREQ(15,3)
|
---|
[67395] | 322 | return 0;
|
---|
[86542] | 323 | #endif
|
---|
[60352] | 324 | }
|
---|
| 325 |
|
---|
[85705] | 326 | #if RTLNX_VER_MAX(4,8,0) && !RTLNX_RHEL_MAJ_PREREQ(7,4)
|
---|
[60352] | 327 | static void vbox_master_drop(struct drm_device *dev,
|
---|
[67395] | 328 | struct drm_file *file_priv, bool from_release)
|
---|
[63755] | 329 | #else
|
---|
[67395] | 330 | static void vbox_master_drop(struct drm_device *dev, struct drm_file *file_priv)
|
---|
[63755] | 331 | #endif
|
---|
[60352] | 332 | {
|
---|
[67395] | 333 | struct vbox_private *vbox = dev->dev_private;
|
---|
| 334 |
|
---|
| 335 | /* See vbox_master_set() */
|
---|
| 336 | vbox->initial_mode_queried = false;
|
---|
[74963] | 337 | vbox_report_caps(vbox);
|
---|
[67395] | 338 |
|
---|
| 339 | mutex_lock(&vbox->hw_mutex);
|
---|
[74581] | 340 | vbox->need_refresh_timer = false;
|
---|
[67395] | 341 | mutex_unlock(&vbox->hw_mutex);
|
---|
[60352] | 342 | }
|
---|
| 343 |
|
---|
[67395] | 344 | static struct drm_driver driver = {
|
---|
[89690] | 345 | #if RTLNX_VER_MAX(5,4,0) && !RTLNX_RHEL_MAJ_PREREQ(8,3) && !RTLNX_SUSE_MAJ_PREREQ(15,3)
|
---|
[86196] | 346 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ |
|
---|
[85705] | 347 | # if RTLNX_VER_MAX(5,1,0) && !RTLNX_RHEL_MAJ_PREREQ(8,1)
|
---|
[77850] | 348 | DRIVER_IRQ_SHARED |
|
---|
[85705] | 349 | # endif
|
---|
[67395] | 350 | DRIVER_PRIME,
|
---|
[89690] | 351 | #else /* >= 5.4.0 && RHEL >= 8.3 && SLES >= 15-SP3 */
|
---|
[88274] | 352 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ,
|
---|
[86174] | 353 | #endif /* < 5.4.0 */
|
---|
[48115] | 354 |
|
---|
[86196] | 355 | #if RTLNX_VER_MAX(4,19,0) && !RTLNX_RHEL_MAJ_PREREQ(8,3)
|
---|
[88274] | 356 | /* Legacy hooks, but still supported. */
|
---|
[67395] | 357 | .load = vbox_driver_load,
|
---|
| 358 | .unload = vbox_driver_unload,
|
---|
[76976] | 359 | #endif
|
---|
[67395] | 360 | .lastclose = vbox_driver_lastclose,
|
---|
| 361 | .master_set = vbox_master_set,
|
---|
| 362 | .master_drop = vbox_master_drop,
|
---|
[85705] | 363 | #if RTLNX_VER_MIN(3,18,0) || RTLNX_RHEL_MAJ_PREREQ(7,2)
|
---|
[85707] | 364 | # if RTLNX_VER_MAX(4,14,0) && !RTLNX_RHEL_MAJ_PREREQ(7,5) && !RTLNX_SUSE_MAJ_PREREQ(15,1) && !RTLNX_SUSE_MAJ_PREREQ(12,5)
|
---|
[67395] | 365 | .set_busid = drm_pci_set_busid,
|
---|
[69143] | 366 | # endif
|
---|
[59526] | 367 | #endif
|
---|
[48115] | 368 |
|
---|
[67395] | 369 | .fops = &vbox_fops,
|
---|
[100677] | 370 | #if RTLNX_VER_MAX(5,15,0) && !RTLNX_RHEL_RANGE(8,7, 8,99) && !RTLNX_RHEL_MAJ_PREREQ(9,1) && !RTLNX_SUSE_MAJ_PREREQ(15,5)
|
---|
[67395] | 371 | .irq_handler = vbox_irq_handler,
|
---|
[91233] | 372 | #endif
|
---|
[67395] | 373 | .name = DRIVER_NAME,
|
---|
| 374 | .desc = DRIVER_DESC,
|
---|
| 375 | .date = DRIVER_DATE,
|
---|
| 376 | .major = DRIVER_MAJOR,
|
---|
| 377 | .minor = DRIVER_MINOR,
|
---|
| 378 | .patchlevel = DRIVER_PATCHLEVEL,
|
---|
[48115] | 379 |
|
---|
[85704] | 380 | #if RTLNX_VER_MAX(4,7,0)
|
---|
[67395] | 381 | .gem_free_object = vbox_gem_free_object,
|
---|
[76943] | 382 | #endif
|
---|
[67395] | 383 | .dumb_create = vbox_dumb_create,
|
---|
| 384 | .dumb_map_offset = vbox_dumb_mmap_offset,
|
---|
[85705] | 385 | #if RTLNX_VER_MAX(3,12,0) && !RTLNX_RHEL_MAJ_PREREQ(7,3)
|
---|
[67395] | 386 | .dumb_destroy = vbox_dumb_destroy,
|
---|
[90577] | 387 | #elif RTLNX_VER_MAX(5,12,0) && !RTLNX_RHEL_MAJ_PREREQ(8,5)
|
---|
[67395] | 388 | .dumb_destroy = drm_gem_dumb_destroy,
|
---|
[59568] | 389 | #endif
|
---|
[102874] | 390 | #if RTLNX_VER_MAX(6,6,0) && !RTLNX_RHEL_RANGE(9,4, 9,99)
|
---|
[67395] | 391 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
---|
| 392 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
---|
[101079] | 393 | #endif
|
---|
[88207] | 394 | .gem_prime_import = drm_gem_prime_import,
|
---|
| 395 | .gem_prime_import_sg_table = vbox_gem_prime_import_sg_table,
|
---|
[102874] | 396 | #if RTLNX_VER_MAX(6,6,0) && !RTLNX_RHEL_RANGE(9,4, 9,99)
|
---|
[88207] | 397 | .gem_prime_mmap = vbox_gem_prime_mmap,
|
---|
[101079] | 398 | #endif
|
---|
[88207] | 399 |
|
---|
[90577] | 400 | #if RTLNX_VER_MAX(5,11,0) && !RTLNX_RHEL_MAJ_PREREQ(8,5)
|
---|
[88207] | 401 | .dev_priv_size = 0,
|
---|
[88212] | 402 | # if RTLNX_VER_MIN(4,7,0)
|
---|
[88207] | 403 | .gem_free_object_unlocked = vbox_gem_free_object,
|
---|
[88212] | 404 | # endif
|
---|
[67395] | 405 | .gem_prime_export = drm_gem_prime_export,
|
---|
| 406 | .gem_prime_pin = vbox_gem_prime_pin,
|
---|
| 407 | .gem_prime_unpin = vbox_gem_prime_unpin,
|
---|
| 408 | .gem_prime_get_sg_table = vbox_gem_prime_get_sg_table,
|
---|
| 409 | .gem_prime_vmap = vbox_gem_prime_vmap,
|
---|
| 410 | .gem_prime_vunmap = vbox_gem_prime_vunmap,
|
---|
[88207] | 411 | #endif
|
---|
[48115] | 412 | };
|
---|
| 413 |
|
---|
| 414 | static int __init vbox_init(void)
|
---|
| 415 | {
|
---|
[88510] | 416 | printk("vboxvideo: loading version " VBOX_VERSION_STRING " r" __stringify(VBOX_SVN_REV) "\n");
|
---|
[93416] | 417 | if (VBOX_VIDEO_NOMODESET())
|
---|
[89689] | 418 | {
|
---|
| 419 | printk("vboxvideo: kernel is running with *nomodeset* parameter,\n");
|
---|
| 420 | printk("vboxvideo: please consider either to remove it or load driver\n");
|
---|
| 421 | printk("vboxvideo: with parameter modeset=1, unloading\n");
|
---|
[67395] | 422 | return -EINVAL;
|
---|
[89689] | 423 | }
|
---|
[48115] | 424 |
|
---|
[67395] | 425 | if (vbox_modeset == 0)
|
---|
[89689] | 426 | {
|
---|
| 427 | printk("vboxvideo: driver loaded with modeset=0 parameter, unloading\n");
|
---|
[67395] | 428 | return -EINVAL;
|
---|
[89689] | 429 | }
|
---|
[60104] | 430 |
|
---|
[85705] | 431 | #if RTLNX_VER_MIN(3,18,0) || RTLNX_RHEL_MAJ_PREREQ(7,3)
|
---|
[69143] | 432 | return pci_register_driver(&vbox_pci_driver);
|
---|
[79690] | 433 | #else
|
---|
| 434 | return drm_pci_init(&driver, &vbox_pci_driver);
|
---|
| 435 | #endif
|
---|
[48115] | 436 | }
|
---|
[67395] | 437 |
|
---|
[48115] | 438 | static void __exit vbox_exit(void)
|
---|
| 439 | {
|
---|
[85705] | 440 | #if RTLNX_VER_MIN(3,18,0) || RTLNX_RHEL_MAJ_PREREQ(7,3)
|
---|
[69143] | 441 | pci_unregister_driver(&vbox_pci_driver);
|
---|
[79690] | 442 | #else
|
---|
| 443 | drm_pci_exit(&driver, &vbox_pci_driver);
|
---|
| 444 | #endif
|
---|
[48115] | 445 | }
|
---|
| 446 |
|
---|
| 447 | module_init(vbox_init);
|
---|
| 448 | module_exit(vbox_exit);
|
---|
| 449 |
|
---|
| 450 | MODULE_AUTHOR(DRIVER_AUTHOR);
|
---|
| 451 | MODULE_DESCRIPTION(DRIVER_DESC);
|
---|
| 452 | MODULE_LICENSE("GPL and additional rights");
|
---|
[60584] | 453 | #ifdef MODULE_VERSION
|
---|
[67177] | 454 | MODULE_VERSION(VBOX_VERSION_STRING " r" __stringify(VBOX_SVN_REV));
|
---|
[60584] | 455 | #endif
|
---|