VirtualBox

Changeset 74773 in vbox for trunk


Ignore:
Timestamp:
Oct 11, 2018 3:19:06 PM (6 years ago)
Author:
vboxsync
Message:

Additions/linux/drm: add clean-ups made when adding driver to Linux staging.
bugref:4567: Linux kernel driver maintenance
Based on work done by Hans de Goede. Main changes:

  • Lots of cosmetic and white space changes to reduce unnecessary differences. Replaced some if (RT_FAILURE(ret)) checks by if (ret).
  • Use additional helpers instead of hard-coding.
  • Use devm_* managed allocation functions in a number of places.
  • Linux-style resource clean-up in a number of functions (goto clean-ups, collapsing nested if-else with breaks and returns, etc).
  • Fixed fbdev fix base setting.
  • Added vbox_check_supported() to vbox_main.c and use instead of VBoxHGSMIIsSupported().
  • Added vbox_bo_move().
Location:
trunk/src/VBox/Additions/linux/drm
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/drm/vbox_drv.c

    r74615 r74773  
    3333 *          Hans de Goede <[email protected]>
    3434 */
    35 #include "vbox_drv.h"
    36 
    37 #include "version-generated.h"
    38 #include "revision-generated.h"
    39 
    4035#include <linux/module.h>
    4136#include <linux/console.h>
     
    4540#include <drm/drm_crtc_helper.h>
    4641
     42#include "vbox_drv.h"
     43
     44#include "version-generated.h"
     45#include "revision-generated.h"
     46
    4747int vbox_modeset = -1;
    4848
     
    7070}
    7171
     72#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) && !defined(RHEL_74)
     73static void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
     74                                        bool suspend)
     75{
     76        if (!fb_helper || !fb_helper->fbdev)
     77                return;
     78
     79        console_lock();
     80        fb_set_suspend(fb_helper->fbdev, suspend);
     81        console_unlock();
     82}
     83#endif
     84
    7285static int vbox_drm_freeze(struct drm_device *dev)
    7386{
     87        struct vbox_private *vbox = dev->dev_private;
     88
    7489        drm_kms_helper_poll_disable(dev);
    7590
    7691        pci_save_state(dev->pdev);
    7792
    78         console_lock();
    79         vbox_fbdev_set_suspend(dev, 1);
    80         console_unlock();
     93        drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true);
    8194
    8295        return 0;
     
    8598static int vbox_drm_thaw(struct drm_device *dev)
    8699{
     100        struct vbox_private *vbox = dev->dev_private;
     101
    87102        drm_mode_config_reset(dev);
    88103        drm_helper_resume_force_mode(dev);
    89 
    90         console_lock();
    91         vbox_fbdev_set_suspend(dev, 0);
    92         console_unlock();
     104        drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false);
    93105
    94106        return 0;
  • trunk/src/VBox/Additions/linux/drm/vbox_drv.h

    r74615 r74773  
    3636#define __VBOX_DRV_H__
    3737
    38 #define LOG_GROUP LOG_GROUP_DEV_VGA
    39 
    4038#include <linux/version.h>
    41 
    4239#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
    4340# include <linux/types.h>
     
    8683
    8784#include <drm/drmP.h>
     85#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || defined(RHEL_75)
     86#include <drm/drm_encoder.h>
     87#endif
     88#include <drm/drm_fb_helper.h>
    8889#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) || defined(RHEL_72)
    8990#include <drm/drm_gem.h>
    90 #endif
    91 #include <drm/drm_fb_helper.h>
    92 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || defined(RHEL_75)
    93 #include <drm/drm_encoder.h>
    9491#endif
    9592
     
    133130#define VBOX_REFRESH_PERIOD (HZ / 2)
    134131
     132#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) && !defined(RHEL_72)
     133static inline void *devm_kcalloc(struct device *dev, size_t n, size_t size,
     134                                 gfp_t flags)
     135{
     136    return devm_kzalloc(dev, n * size, flags);
     137}
     138#endif
     139
    135140struct vbox_fbdev;
    136141
     
    143148        struct VBVABUFFERCONTEXT *vbva_info;
    144149        bool any_pitch;
    145         unsigned int num_crtcs;
     150        u32 num_crtcs;
    146151        /** Amount of available VRAM, including space used for buffers. */
    147152        u32 full_vram_size;
     
    163168
    164169        struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */
    165         bool isr_installed;
    166170        /**
    167171         * We decide whether or not user-space supports display hot-plug
     
    219223        struct vbox_crtc *vbox_crtc;
    220224        struct {
    221                 u32 width;
    222                 u32 height;
     225                u16 width;
     226                u16 height;
    223227                bool disconnected;
    224228        } mode_hint;
     
    285289                          struct vbox_framebuffer *vbox_fb,
    286290#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) || defined(RHEL_73)
    287                           const
    288 #endif
     291                          const struct DRM_MODE_FB_CMD *mode_cmd,
     292#else
    289293                          struct DRM_MODE_FB_CMD *mode_cmd,
     294#endif
    290295                          struct drm_gem_object *obj);
    291296
    292297int vbox_fbdev_init(struct drm_device *dev);
    293298void vbox_fbdev_fini(struct drm_device *dev);
    294 void vbox_fbdev_set_suspend(struct drm_device *dev, int state);
     299void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr);
    295300
    296301struct vbox_bo {
     
    373378void vbox_gem_prime_unpin(struct drm_gem_object *obj);
    374379struct sg_table *vbox_gem_prime_get_sg_table(struct drm_gem_object *obj);
    375 struct drm_gem_object *vbox_gem_prime_import_sg_table(struct drm_device *dev,
    376380#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) && !defined(RHEL_72)
    377                                                       size_t size,
    378 #else
    379                                                       struct dma_buf_attachment
    380                                                       *attach,
    381 #endif
    382                                                       struct sg_table *table);
     381struct drm_gem_object *vbox_gem_prime_import_sg_table(
     382        struct drm_device *dev, size_t size, struct sg_table *table);
     383#else
     384struct drm_gem_object *vbox_gem_prime_import_sg_table(
     385        struct drm_device *dev, struct dma_buf_attachment *attach,
     386        struct sg_table *table);
     387#endif
    383388void *vbox_gem_prime_vmap(struct drm_gem_object *obj);
    384389void vbox_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
     
    394399/* vbox_hgsmi.c */
    395400void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size,
    396                         u8 channel, u16 channel_info);
     401                        u8 channel, u16 channel_info);
    397402void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf);
    398403int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf);
     
    400405static inline void vbox_write_ioport(u16 index, u16 data)
    401406{
    402         outw(index, VBE_DISPI_IOPORT_INDEX);
    403         outw(data, VBE_DISPI_IOPORT_DATA);
     407        outw(index, VBE_DISPI_IOPORT_INDEX);
     408        outw(data, VBE_DISPI_IOPORT_DATA);
    404409}
    405410
  • trunk/src/VBox/Additions/linux/drm/vbox_fb.c

    r71947 r74773  
    3232 *          Michael Thayer <[email protected],
    3333 */
    34 /* Include from most specific to most general to be able to override things. */
    35 #include "vbox_drv.h"
    36 #include <VBoxVideo.h>
    37 
    3834#include <linux/module.h>
    3935#include <linux/kernel.h>
     
    5147#include <drm/drm_fb_helper.h>
    5248#include <drm/drm_crtc_helper.h>
     49
    5350#include "vbox_drv.h"
     51#include <VBoxVideo.h>
    5452
    5553#define VBOX_DIRTY_DELAY (HZ / 30)
     
    211209#endif
    212210
    213         int ret = 0;
     211        int ret;
    214212
    215213        size = pitch * mode_cmd->height;
     
    219217
    220218        *gobj_p = gobj;
    221         return ret;
     219
     220        return 0;
    222221}
    223222
     
    232231        struct fb_info *info;
    233232        struct device *device = &dev->pdev->dev;
    234         struct drm_gem_object *gobj = NULL;
    235         struct vbox_bo *bo = NULL;
     233        struct drm_gem_object *gobj;
     234        struct vbox_bo *bo;
    236235        int size, ret;
    237236        u32 pitch;
     
    315314        info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
    316315        info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
    317         info->fix.smem_start = 0;
    318         info->fix.smem_len = size;
    319316
    320317#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || defined(RHEL_75)
     
    345342};
    346343
    347 static void vbox_fbdev_destroy(struct drm_device *dev, struct vbox_fbdev *fbdev)
    348 {
    349         struct fb_info *info;
     344#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) && !defined(RHEL_73)
     345static void drm_fb_helper_unregister_fbi(struct drm_fb_helper *fb_helper)
     346{
     347        if (fb_helper && fb_helper->fbdev)
     348                unregister_framebuffer(fb_helper->fbdev);
     349}
     350#endif
     351
     352void vbox_fbdev_fini(struct drm_device *dev)
     353{
     354        struct vbox_private *vbox = dev->dev_private;
     355        struct vbox_fbdev *fbdev = vbox->fbdev;
    350356        struct vbox_framebuffer *afb = &fbdev->afb;
    351357
    352         if (fbdev->helper.fbdev) {
    353                 info = fbdev->helper.fbdev;
    354                 unregister_framebuffer(info);
    355                 if (info->cmap.len)
    356                         fb_dealloc_cmap(&info->cmap);
    357                 framebuffer_release(info);
    358         }
     358        drm_fb_helper_unregister_fbi(&fbdev->helper);
    359359
    360360        if (afb->obj) {
     
    389389        int ret;
    390390
    391         fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
     391        fbdev = devm_kzalloc(dev->dev, sizeof(*fbdev), GFP_KERNEL);
    392392        if (!fbdev)
    393393                return -ENOMEM;
     
    409409#endif
    410410        if (ret)
    411                 goto free;
     411                return ret;
    412412
    413413        ret = drm_fb_helper_single_add_all_connectors(&fbdev->helper);
    414414        if (ret)
    415                 goto fini;
     415                goto err_fini;
    416416
    417417        /* disable all the possible outputs/crtcs before entering KMS mode */
     
    420420        ret = drm_fb_helper_initial_config(&fbdev->helper, 32);
    421421        if (ret)
    422                 goto fini;
     422                goto err_fini;
    423423
    424424        return 0;
    425425
    426 fini:
     426err_fini:
    427427        drm_fb_helper_fini(&fbdev->helper);
    428 free:
    429         kfree(fbdev);
    430         vbox->fbdev = NULL;
    431 
    432428        return ret;
    433429}
    434430
    435 void vbox_fbdev_fini(struct drm_device *dev)
    436 {
    437         struct vbox_private *vbox = dev->dev_private;
    438 
    439         if (!vbox->fbdev)
    440                 return;
    441 
    442         vbox_fbdev_destroy(dev, vbox->fbdev);
    443         kfree(vbox->fbdev);
    444         vbox->fbdev = NULL;
    445 }
    446 
    447 void vbox_fbdev_set_suspend(struct drm_device *dev, int state)
    448 {
    449         struct vbox_private *vbox = dev->dev_private;
    450 
    451         if (!vbox->fbdev)
    452                 return;
    453 
    454         fb_set_suspend(vbox->fbdev->helper.fbdev, state);
    455 }
     431void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr)
     432{
     433        struct fb_info *fbdev = vbox->fbdev->helper.fbdev;
     434
     435        fbdev->fix.smem_start = fbdev->apertures->ranges[0].base + gpu_addr;
     436        fbdev->fix.smem_len = vbox->available_vram_size - gpu_addr;
     437}
  • trunk/src/VBox/Additions/linux/drm/vbox_hgsmi.c

    r69325 r74773  
    8888        dma_addr_t offset;
    8989
    90         total_size = size + sizeof(HGSMIBUFFERHEADER) + sizeof(HGSMIBUFFERTAIL);
     90        total_size = size + sizeof(*h) + sizeof(*t);
    9191        h = gen_pool_dma_alloc(guest_pool, total_size, &offset);
    9292        if (!h)
    9393                return NULL;
    9494
    95         t = (HGSMIBUFFERTAIL *)((u8 *)h + sizeof(HGSMIBUFFERHEADER) + size);
     95        t = (HGSMIBUFFERTAIL *)((u8 *)h + sizeof(*h) + size);
    9696
    9797        h->u8Flags = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE;
     
    104104        t->u32Checksum = hgsmi_checksum(offset, h, t);
    105105
    106         return (u8 *)h + sizeof(HGSMIBUFFERHEADER);
     106        return (u8 *)h + sizeof(*h);
    107107}
    108108
     
    110110{
    111111        HGSMIBUFFERHEADER *h =
    112                 (HGSMIBUFFERHEADER *)((u8 *)buf - sizeof(HGSMIBUFFERHEADER));
    113         size_t total_size = h->u32DataSize + sizeof(HGSMIBUFFERHEADER) +
     112                (HGSMIBUFFERHEADER *)((u8 *)buf - sizeof(*h));
     113        size_t total_size = h->u32DataSize + sizeof(*h) +
    114114                                             sizeof(HGSMIBUFFERTAIL);
    115115
     
    127127        mb();
    128128
    129         return VINF_SUCCESS;
     129        return 0;
    130130}
  • trunk/src/VBox/Additions/linux/drm/vbox_irq.c

    r74615 r74773  
    3232 *          Hans de Goede <[email protected]>
    3333 */
    34 
    3534#include "vbox_drv.h"
    3635
     36#include <drm/drm_crtc_helper.h>
    3737#include <VBoxVideo.h>
    38 
    39 #include <drm/drm_crtc_helper.h>
    4038
    4139static void vbox_clear_irq(void)
     
    8785static void validate_or_set_position_hints(struct vbox_private *vbox)
    8886{
     87        struct VBVAMODEHINT *hintsi, *hintsj;
     88        bool valid = true;
     89        u16 currentx = 0;
    8990        int i, j;
    90         u16 currentx = 0;
    91         bool valid = true;
    9291
    9392        for (i = 0; i < vbox->num_crtcs; ++i) {
    9493                for (j = 0; j < i; ++j) {
    95                         struct VBVAMODEHINT *hintsi = &vbox->last_mode_hints[i];
    96                         struct VBVAMODEHINT *hintsj = &vbox->last_mode_hints[j];
     94                        hintsi = &vbox->last_mode_hints[i];
     95                        hintsj = &vbox->last_mode_hints[j];
    9796
    9897                        if (hintsi->fEnabled && hintsj->fEnabled) {
     
    131130        struct drm_device *dev = vbox->dev;
    132131        struct drm_connector *connector;
    133         struct vbox_connector *vbox_connector;
     132        struct vbox_connector *vbox_conn;
    134133        struct VBVAMODEHINT *hints;
    135134        u16 flags;
    136135        bool disconnected;
    137136        unsigned int crtc_id;
    138         int rc;
    139 
    140         rc = VBoxHGSMIGetModeHints(vbox->guest_pool, vbox->num_crtcs,
     137        int ret;
     138
     139        ret = VBoxHGSMIGetModeHints(vbox->guest_pool, vbox->num_crtcs,
    141140                                   vbox->last_mode_hints);
    142         if (RT_FAILURE(rc)) {
    143                 DRM_ERROR("vboxvideo: VBoxHGSMIGetModeHints failed, rc=%i.\n",
    144                           rc);
     141        if (ret) {
     142                DRM_ERROR("vboxvideo: hgsmi_get_mode_hints failed: %d\n", ret);
    145143                return;
    146144        }
     145
    147146        validate_or_set_position_hints(vbox);
    148147#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
     
    152151#endif
    153152        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
    154                 vbox_connector = to_vbox_connector(connector);
    155                 hints =
    156                     &vbox->last_mode_hints[vbox_connector->vbox_crtc->crtc_id];
    157                 if (hints->magic == VBVAMODEHINT_MAGIC) {
    158                         disconnected = !(hints->fEnabled);
    159                         crtc_id = vbox_connector->vbox_crtc->crtc_id;
    160                         flags = VBVA_SCREEN_F_ACTIVE
    161                             | (disconnected ? VBVA_SCREEN_F_DISABLED :
    162                                VBVA_SCREEN_F_BLANK);
    163                         vbox_connector->mode_hint.width = hints->cx;
    164                         vbox_connector->mode_hint.height = hints->cy;
    165                         vbox_connector->vbox_crtc->x_hint = hints->dx;
    166                         vbox_connector->vbox_crtc->y_hint = hints->dy;
    167                         vbox_connector->mode_hint.disconnected = disconnected;
    168                         if (vbox_connector->vbox_crtc->disconnected !=
    169                             disconnected) {
    170                                 VBoxHGSMIProcessDisplayInfo(vbox->guest_pool,
    171                                                             crtc_id, 0, 0, 0,
    172                                                             hints->cx * 4,
    173                                                             hints->cx,
    174                                                             hints->cy, 0,
    175                                                             flags);
    176                                 vbox_connector->vbox_crtc->disconnected =
    177                                     disconnected;
    178                         }
    179                 }
     153                vbox_conn = to_vbox_connector(connector);
     154
     155                hints = &vbox->last_mode_hints[vbox_conn->vbox_crtc->crtc_id];
     156                if (hints->magic != VBVAMODEHINT_MAGIC)
     157                        continue;
     158
     159                disconnected = !(hints->fEnabled);
     160                crtc_id = vbox_conn->vbox_crtc->crtc_id;
     161                vbox_conn->mode_hint.width = hints->cx & 0x8fff;
     162                vbox_conn->mode_hint.height = hints->cy & 0x8fff;
     163                vbox_conn->vbox_crtc->x_hint = hints->dx;
     164                vbox_conn->vbox_crtc->y_hint = hints->dy;
     165                vbox_conn->mode_hint.disconnected = disconnected;
     166
     167                if (vbox_conn->vbox_crtc->disconnected == disconnected)
     168                        continue;
     169
     170                if (disconnected)
     171                        flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED;
     172                else
     173                        flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_BLANK;
     174
     175                VBoxHGSMIProcessDisplayInfo(vbox->guest_pool, crtc_id, 0, 0, 0,
     176                                           hints->cx * 4, hints->cx,
     177                                           hints->cy, 0, flags);
     178
     179                vbox_conn->vbox_crtc->disconnected = disconnected;
    180180        }
    181181#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
     
    197197int vbox_irq_init(struct vbox_private *vbox)
    198198{
    199         int ret;
    200 
     199        INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker);
    201200        vbox_update_mode_hints(vbox);
    202201#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) || defined(RHEL_71)
    203         ret = drm_irq_install(vbox->dev, vbox->dev->pdev->irq);
     202        return drm_irq_install(vbox->dev, vbox->dev->pdev->irq);
    204203#else
    205         ret = drm_irq_install(vbox->dev);
     204        return drm_irq_install(vbox->dev);
    206205#endif
    207         if (unlikely(ret != 0)) {
    208                 vbox_irq_fini(vbox);
    209                 DRM_ERROR("Failed installing irq: %d\n", ret);
    210                 return 1;
    211         }
    212         INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker);
    213         vbox->isr_installed = true;
    214         return 0;
    215206}
    216207
    217208void vbox_irq_fini(struct vbox_private *vbox)
    218209{
    219         if (vbox->isr_installed) {
    220                 drm_irq_uninstall(vbox->dev);
    221                 flush_work(&vbox->hotplug_work);
    222                 vbox->isr_installed = false;
    223         }
    224 }
     210        drm_irq_uninstall(vbox->dev);
     211        flush_work(&vbox->hotplug_work);
     212}
  • trunk/src/VBox/Additions/linux/drm/vbox_main.c

    r74738 r74773  
    3434 */
    3535#include "vbox_drv.h"
     36#include <drm/drm_fb_helper.h>
     37#include <drm/drm_crtc_helper.h>
    3638
    3739#include <VBoxVideoGuest.h>
    3840#include <VBoxVideoVBE.h>
    39 
    40 #include <drm/drm_fb_helper.h>
    41 #include <drm/drm_crtc_helper.h>
    4241
    4342static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb)
     
    6463
    6564        for (i = 0; i < vbox->num_crtcs; ++i) {
    66                 if (!vbox->vbva_info[i].pVBVA) {
    67                         vbva = (struct VBVABUFFER *)
    68                                 ((u8 *)vbox->vbva_buffers +
    69                                                      i * VBVA_MIN_BUFFER_SIZE);
    70                         if (!VBoxVBVAEnable(&vbox->vbva_info[i],
    71                                             vbox->guest_pool, vbva, i)) {
    72                                 /* very old host or driver error. */
    73                                 DRM_ERROR("vboxvideo: VBoxVBVAEnable failed - heap allocation error.\n");
    74                                 return;
    75                         }
     65                if (vbox->vbva_info[i].pVBVA)
     66                        continue;
     67
     68                vbva = (void *)vbox->vbva_buffers + i * VBVA_MIN_BUFFER_SIZE;
     69                if (!VBoxVBVAEnable(&vbox->vbva_info[i],
     70                                 vbox->guest_pool, vbva, i)) {
     71                        /* very old host or driver error. */
     72                        DRM_ERROR("vboxvideo: vbva_enable failed\n");
     73                        return;
    7674                }
    7775        }
     
    8886void vbox_report_caps(struct vbox_private *vbox)
    8987{
    90         u32 caps = VBVACAPS_DISABLE_CURSOR_INTEGRATION
    91             | VBVACAPS_IRQ | VBVACAPS_USE_VBVA_ONLY;
     88        u32 caps = VBVACAPS_DISABLE_CURSOR_INTEGRATION |
     89                   VBVACAPS_IRQ | VBVACAPS_USE_VBVA_ONLY;
     90
    9291        if (vbox->initial_mode_queried)
    9392                caps |= VBVACAPS_VIDEO_MODE_HINTS;
     93
    9494        VBoxHGSMISendCapsInfo(vbox->guest_pool, caps);
    9595}
     
    113113        mutex_lock(&vbox->hw_mutex);
    114114        list_for_each_entry(crtc, &fb->dev->mode_config.crtc_list, head) {
    115                 if (CRTC_FB(crtc) == fb) {
    116                         for (i = 0; i < num_rects; ++i) {
    117                                 VBVACMDHDR cmd_hdr;
    118                                 unsigned int crtc_id =
    119                                     to_vbox_crtc(crtc)->crtc_id;
    120 
    121                                 if ((rects[i].x1 >
    122                                          crtc->x + crtc->hwmode.hdisplay) ||
    123                                     (rects[i].y1 >
    124                                          crtc->y + crtc->hwmode.vdisplay) ||
    125                                     (rects[i].x2 < crtc->x) ||
    126                                     (rects[i].y2 < crtc->y))
    127                                         continue;
    128 
    129                                 cmd_hdr.x = (s16)rects[i].x1;
    130                                 cmd_hdr.y = (s16)rects[i].y1;
    131                                 cmd_hdr.w = (u16)rects[i].x2 - rects[i].x1;
    132                                 cmd_hdr.h = (u16)rects[i].y2 - rects[i].y1;
    133 
    134                                 if (VBoxVBVABufferBeginUpdate(
    135                                                 &vbox->vbva_info[crtc_id],
    136                                                 vbox->guest_pool)) {
    137                                         VBoxVBVAWrite(&vbox->vbva_info[crtc_id],
    138                                                       vbox->guest_pool,
    139                                                       &cmd_hdr,
    140                                                       sizeof(cmd_hdr));
    141                                         VBoxVBVABufferEndUpdate(
    142                                                 &vbox->vbva_info[crtc_id]);
    143                                 }
    144                         }
     115                if (CRTC_FB(crtc) != fb)
     116                        continue;
     117
     118                for (i = 0; i < num_rects; ++i) {
     119                        VBVACMDHDR cmd_hdr;
     120                        unsigned int crtc_id = to_vbox_crtc(crtc)->crtc_id;
     121
     122                        if ((rects[i].x1 > crtc->x + crtc->hwmode.hdisplay) ||
     123                            (rects[i].y1 > crtc->y + crtc->hwmode.vdisplay) ||
     124                            (rects[i].x2 < crtc->x) ||
     125                            (rects[i].y2 < crtc->y))
     126                                continue;
     127
     128                        cmd_hdr.x = (s16)rects[i].x1;
     129                        cmd_hdr.y = (s16)rects[i].y1;
     130                        cmd_hdr.w = (u16)rects[i].x2 - rects[i].x1;
     131                        cmd_hdr.h = (u16)rects[i].y2 - rects[i].y1;
     132
     133                        if (!VBoxVBVABufferBeginUpdate(&vbox->vbva_info[crtc_id],
     134                                                      vbox->guest_pool))
     135                                continue;
     136
     137                        VBoxVBVAWrite(&vbox->vbva_info[crtc_id], vbox->guest_pool,
     138                                   &cmd_hdr, sizeof(cmd_hdr));
     139                        VBoxVBVABufferEndUpdate(&vbox->vbva_info[crtc_id]);
    145140                }
    146141        }
     
    167162                          struct vbox_framebuffer *vbox_fb,
    168163#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) || defined(RHEL_73)
    169                           const
    170 #endif
     164                          const struct DRM_MODE_FB_CMD *mode_cmd,
     165#else
    171166                          struct DRM_MODE_FB_CMD *mode_cmd,
     167#endif
    172168                          struct drm_gem_object *obj)
    173169{
     
    200196        struct drm_gem_object *obj;
    201197        struct vbox_framebuffer *vbox_fb;
    202         int ret;
     198        int ret = -ENOMEM;
    203199
    204200#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) || defined(RHEL_74)
     
    211207
    212208        vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL);
    213         if (!vbox_fb) {
    214                 drm_gem_object_unreference_unlocked(obj);
    215                 return ERR_PTR(-ENOMEM);
    216         }
     209        if (!vbox_fb)
     210                goto err_unref_obj;
    217211
    218212        ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj);
    219         if (ret) {
    220                 drm_gem_object_unreference_unlocked(obj);
    221                 kfree(vbox_fb);
    222                 return ERR_PTR(ret);
    223         }
     213        if (ret)
     214                goto err_free_vbox_fb;
    224215
    225216        return &vbox_fb->base;
     217
     218err_free_vbox_fb:
     219        kfree(vbox_fb);
     220err_unref_obj:
     221        drm_gem_object_unreference_unlocked(obj);
     222        return ERR_PTR(ret);
    226223}
    227224
     
    230227};
    231228
    232 static void vbox_accel_fini(struct vbox_private *vbox)
    233 {
    234         if (vbox->vbva_info) {
    235                 vbox_disable_accel(vbox);
    236                 kfree(vbox->vbva_info);
    237                 vbox->vbva_info = NULL;
    238         }
    239         if (vbox->vbva_buffers) {
    240                 pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers);
    241                 vbox->vbva_buffers = NULL;
    242         }
    243 }
    244 
    245229#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) && !defined(RHEL_73)
    246230#define pci_iomap_range(dev, bar, offset, maxlen) \
     
    252236        unsigned int i;
    253237
    254         vbox->vbva_info = kcalloc(vbox->num_crtcs, sizeof(*vbox->vbva_info),
    255                                   GFP_KERNEL);
     238        vbox->vbva_info = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
     239                                       sizeof(*vbox->vbva_info), GFP_KERNEL);
    256240        if (!vbox->vbva_info)
    257241                return -ENOMEM;
     
    269253        for (i = 0; i < vbox->num_crtcs; ++i)
    270254                VBoxVBVASetupBufferContext(&vbox->vbva_info[i],
    271                                            vbox->available_vram_size +
    272                                            i * VBVA_MIN_BUFFER_SIZE,
    273                                            VBVA_MIN_BUFFER_SIZE);
     255                                          vbox->available_vram_size +
     256                                          i * VBVA_MIN_BUFFER_SIZE,
     257                                          VBVA_MIN_BUFFER_SIZE);
    274258
    275259        vbox_enable_accel(vbox);
    276260
    277261        return 0;
     262}
     263
     264static void vbox_accel_fini(struct vbox_private *vbox)
     265{
     266        vbox_disable_accel(vbox);
     267        pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers);
    278268}
    279269
     
    285275
    286276        ret = VBoxQueryConfHGSMI(vbox->guest_pool,
    287                                 VBOX_VBVA_CONF32_MODE_HINT_REPORTING,
    288                                 &have_hints);
    289         if (RT_FAILURE(ret))
     277                              VBOX_VBVA_CONF32_MODE_HINT_REPORTING,
     278                              &have_hints);
     279        if (ret)
    290280                return false;
    291281
    292282        ret = VBoxQueryConfHGSMI(vbox->guest_pool,
    293                                 VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING,
    294                                 &have_cursor);
    295         if (RT_FAILURE(ret))
     283                              VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING,
     284                              &have_cursor);
     285        if (ret)
    296286                return false;
    297287
     
    325315}
    326316
     317static bool vbox_check_supported(u16 id)
     318{
     319        u16 dispi_id;
     320
     321        vbox_write_ioport(VBE_DISPI_INDEX_ID, id);
     322        dispi_id = inw(VBE_DISPI_IOPORT_DATA);
     323
     324        return dispi_id == id;
     325}
     326
    327327/**
    328328 * Set up our heaps and data exchange buffers in VRAM before handing the rest
     
    331331static int vbox_hw_init(struct vbox_private *vbox)
    332332{
    333         int ret;
    334 
    335         vbox->full_vram_size = VBoxVideoGetVRAMSize();
    336         vbox->any_pitch = VBoxVideoAnyWidthAllowed();
     333        int ret = -ENOMEM;
     334
     335        vbox->full_vram_size = inl(VBE_DISPI_IOPORT_DATA);
     336        vbox->any_pitch = vbox_check_supported(VBE_DISPI_ID_ANYX);
    337337
    338338        DRM_INFO("VRAM %08x\n", vbox->full_vram_size);
     
    348348        vbox->guest_pool = gen_pool_create(4, -1);
    349349        if (!vbox->guest_pool)
    350                 return -ENOMEM;
     350                goto err_unmap_guest_heap;
    351351
    352352        ret = gen_pool_add_virt(vbox->guest_pool,
     
    355355                                GUEST_HEAP_USABLE_SIZE, -1);
    356356        if (ret)
    357                 return ret;
     357                goto err_destroy_guest_pool;
    358358
    359359        /* Reduce available VRAM size to reflect the guest heap. */
    360360        vbox->available_vram_size = GUEST_HEAP_OFFSET(vbox);
    361361        /* Linux drm represents monitors as a 32-bit array. */
    362         vbox->num_crtcs = min_t(u32, VBoxHGSMIGetMonitorCount(vbox->guest_pool),
    363                                 VBOX_MAX_SCREENS);
    364 
    365         if (!have_hgsmi_mode_hints(vbox))
    366                 return -ENOTSUPP;
    367 
    368         vbox->last_mode_hints =
    369             kcalloc(vbox->num_crtcs, sizeof(VBVAMODEHINT), GFP_KERNEL);
    370         if (!vbox->last_mode_hints)
    371                 return -ENOMEM;
     362        VBoxQueryConfHGSMI(vbox->guest_pool, VBOX_VBVA_CONF32_MONITOR_COUNT,
     363                         &vbox->num_crtcs);
     364        vbox->num_crtcs = clamp_t(u32, vbox->num_crtcs, 1, VBOX_MAX_SCREENS);
     365
     366        if (!have_hgsmi_mode_hints(vbox)) {
     367                ret = -ENOTSUPP;
     368                goto err_destroy_guest_pool;
     369        }
     370
     371        vbox->last_mode_hints = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
     372                                             sizeof(VBVAMODEHINT),
     373                                             GFP_KERNEL);
     374        if (!vbox->last_mode_hints) {
     375                ret = -ENOMEM;
     376                goto err_destroy_guest_pool;
     377        }
    372378
    373379        ret = vbox_accel_init(vbox);
    374380        if (ret)
    375                 return ret;
     381                goto err_destroy_guest_pool;
     382
    376383        /* Set up the refresh timer for users which do not send dirty rectangles. */
    377384        INIT_DELAYED_WORK(&vbox->refresh_work, vbox_refresh_timer);
    378         return 0;
     385
     386        return 0;
     387
     388err_destroy_guest_pool:
     389        gen_pool_destroy(vbox->guest_pool);
     390err_unmap_guest_heap:
     391        pci_iounmap(vbox->dev->pdev, vbox->guest_heap);
     392        return ret;
    379393}
    380394
     
    384398        cancel_delayed_work(&vbox->refresh_work);
    385399        vbox_accel_fini(vbox);
    386         kfree(vbox->last_mode_hints);
    387         vbox->last_mode_hints = NULL;
     400        gen_pool_destroy(vbox->guest_pool);
     401        pci_iounmap(vbox->dev->pdev, vbox->guest_heap);
    388402}
    389403
     
    393407        int ret = 0;
    394408
    395         if (!VBoxHGSMIIsSupported())
     409        if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
    396410                return -ENODEV;
    397411
    398         vbox = kzalloc(sizeof(*vbox), GFP_KERNEL);
     412        vbox = devm_kzalloc(dev->dev, sizeof(*vbox), GFP_KERNEL);
    399413        if (!vbox)
    400414                return -ENOMEM;
     
    407421        ret = vbox_hw_init(vbox);
    408422        if (ret)
    409                 goto out_free;
     423                return ret;
    410424
    411425        ret = vbox_mm_init(vbox);
    412426        if (ret)
    413                 goto out_free;
     427                goto err_hw_fini;
    414428
    415429        drm_mode_config_init(dev);
     
    424438        ret = vbox_mode_init(dev);
    425439        if (ret)
    426                 goto out_free;
     440                goto err_drm_mode_cleanup;
    427441
    428442        ret = vbox_irq_init(vbox);
    429443        if (ret)
    430                 goto out_free;
     444                goto err_mode_fini;
    431445
    432446        ret = vbox_fbdev_init(dev);
    433447        if (ret)
    434                 goto out_free;
    435 
    436         return 0;
    437 
    438 out_free:
    439         vbox_driver_unload(dev);
     448                goto err_irq_fini;
     449
     450        return 0;
     451
     452err_irq_fini:
     453        vbox_irq_fini(vbox);
     454err_mode_fini:
     455        vbox_mode_fini(dev);
     456err_drm_mode_cleanup:
     457        drm_mode_config_cleanup(dev);
     458        vbox_mm_fini(vbox);
     459err_hw_fini:
     460        vbox_hw_fini(vbox);
    440461        return ret;
    441462}
     
    452473        vbox_irq_fini(vbox);
    453474        vbox_mode_fini(dev);
    454         if (dev->mode_config.funcs)
    455                 drm_mode_config_cleanup(dev);
    456 
     475        drm_mode_config_cleanup(dev);
     476        vbox_mm_fini(vbox);
    457477        vbox_hw_fini(vbox);
    458         vbox_mm_fini(vbox);
    459         if (vbox->guest_pool)
    460                 gen_pool_destroy(vbox->guest_pool);
    461         if (vbox->guest_heap)
    462                 pci_iounmap(dev->pdev, vbox->guest_heap);
    463         kfree(vbox);
    464         dev->dev_private = NULL;
    465478#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) && !defined(RHEL_75)
    466479        return 0;
  • trunk/src/VBox/Additions/linux/drm/vbox_mode.c

    r74730 r74773  
    108108        flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
    109109        VBoxHGSMIProcessDisplayInfo(vbox->guest_pool, vbox_crtc->crtc_id,
    110                                     x_offset, y_offset,
    111                                     crtc->x * bpp / 8 + crtc->y * pitch,
    112                                     pitch, width, height,
    113                                     vbox_crtc->blanked ? 0 : bpp, flags);
     110                                   x_offset, y_offset,
     111                                   crtc->x * bpp / 8 + crtc->y * pitch,
     112                                   pitch, width, height,
     113                                   vbox_crtc->blanked ? 0 : bpp, flags);
    114114}
    115115
     
    118118        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
    119119        struct vbox_private *vbox = crtc->dev->dev_private;
    120         void *p;
     120        VBVAINFOVIEW *p;
    121121
    122122        /*
     
    131131         * buffer and so on.
    132132         */
    133         p = VBoxHGSMIBufferAlloc(vbox->guest_pool, sizeof(VBVAINFOVIEW),
    134                                  HGSMI_CH_VBVA, VBVA_INFO_VIEW);
    135         if (p) {
    136                 VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *) p;
    137 
    138                 pInfo->u32ViewIndex = vbox_crtc->crtc_id;
    139                 pInfo->u32ViewOffset = vbox_crtc->fb_offset;
    140                 pInfo->u32ViewSize =
    141                     vbox->available_vram_size - vbox_crtc->fb_offset +
    142                     vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
    143                 pInfo->u32MaxScreenSize =
    144                     vbox->available_vram_size - vbox_crtc->fb_offset;
    145                 VBoxHGSMIBufferSubmit(vbox->guest_pool, p);
    146                 VBoxHGSMIBufferFree(vbox->guest_pool, p);
    147         } else {
     133        p = VBoxHGSMIBufferAlloc(vbox->guest_pool, sizeof(*p),
     134                               HGSMI_CH_VBVA, VBVA_INFO_VIEW);
     135        if (!p)
    148136                return -ENOMEM;
    149         }
     137
     138        p->u32ViewIndex = vbox_crtc->crtc_id;
     139        p->u32ViewOffset = vbox_crtc->fb_offset;
     140        p->u32ViewSize = vbox->available_vram_size - vbox_crtc->fb_offset +
     141                       vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
     142        p->u32MaxScreenSize = vbox->available_vram_size - vbox_crtc->fb_offset;
     143
     144        VBoxHGSMIBufferSubmit(vbox->guest_pool, p);
     145        VBoxHGSMIBufferFree(vbox->guest_pool, p);
    150146
    151147        return 0;
     
    213209                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
    214210                                    head) {
    215                         if (to_vbox_crtc(crtci)->crtc_id == 0) {
    216                                 vbox->single_framebuffer = true;
    217                                 vbox->input_mapping_width =
    218                                     CRTC_FB(crtci)->width;
    219                                 vbox->input_mapping_height =
    220                                     CRTC_FB(crtci)->height;
    221                                 return old_single_framebuffer !=
    222                                     vbox->single_framebuffer;
    223                         }
     211                        if (to_vbox_crtc(crtci)->crtc_id != 0)
     212                                continue;
     213
     214                        vbox->single_framebuffer = true;
     215                        vbox->input_mapping_width = CRTC_FB(crtci)->width;
     216                        vbox->input_mapping_height = CRTC_FB(crtci)->height;
     217                        return old_single_framebuffer !=
     218                               vbox->single_framebuffer;
    224219                }
    225220        }
     
    283278        }
    284279
     280        if (&vbox->fbdev->afb == vbox_fb)
     281                vbox_fbdev_set_base(vbox, gpu_addr);
     282
    285283        vbox_crtc->fb_offset = gpu_addr;
    286284        if (vbox_set_up_input_mapping(vbox)) {
     
    303301{
    304302        struct vbox_private *vbox = crtc->dev->dev_private;
    305         int rc = vbox_crtc_set_base(crtc, old_fb, x, y);
    306         if (rc)
    307                 return rc;
     303        int ret = vbox_crtc_set_base(crtc, old_fb, x, y);
     304        if (ret)
     305                return ret;
    308306        mutex_lock(&vbox->hw_mutex);
    309         rc = vbox_set_view(crtc);
    310         if (!rc)
     307        ret = vbox_set_view(crtc);
     308        if (!ret)
    311309                vbox_do_modeset(crtc, mode);
    312310        VBoxHGSMIUpdateInputMapping(vbox->guest_pool, 0, 0,
    313                                     vbox->input_mapping_width,
    314                                     vbox->input_mapping_height);
     311                                   vbox->input_mapping_width,
     312                                   vbox->input_mapping_height);
    315313        mutex_unlock(&vbox->hw_mutex);
    316314
    317         return rc;
     315        return ret;
    318316}
    319317
     
    455453
    456454        drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
    457                          DRM_MODE_ENCODER_DAC
    458455#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) || defined(RHEL_73)
    459                          , NULL
    460 #endif
    461             );
     456                         DRM_MODE_ENCODER_DAC, NULL);
     457#else
     458                         DRM_MODE_ENCODER_DAC);
     459#endif
    462460        drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
    463461
     
    564562         */
    565563        VBoxHGSMIReportFlagsLocation(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
    566                                      HOST_FLAGS_OFFSET);
     564                                    HOST_FLAGS_OFFSET);
    567565        if (vbox_connector->vbox_crtc->crtc_id == 0)
    568566                vbox_report_caps(vbox);
     
    621619static void vbox_connector_destroy(struct drm_connector *connector)
    622620{
    623         struct vbox_connector *vbox_connector = NULL;
     621        struct vbox_connector *vbox_connector;
    624622
    625623        vbox_connector = to_vbox_connector(connector);
     
    636634vbox_connector_detect(struct drm_connector *connector, bool force)
    637635{
    638         struct vbox_connector *vbox_connector = NULL;
    639 
    640         (void)force;
     636        struct vbox_connector *vbox_connector;
     637
    641638        vbox_connector = to_vbox_connector(connector);
    642639
     
    724721        struct vbox_crtc *vbox_crtc;
    725722        unsigned int i;
     723        int ret;
    726724
    727725        /* vbox_cursor_init(dev); */
     
    733731                if (!encoder)
    734732                        return -ENOMEM;
    735                 vbox_connector_init(dev, vbox_crtc, encoder);
     733                ret = vbox_connector_init(dev, vbox_crtc, encoder);
     734                if (ret)
     735                        return ret;
    736736        }
    737737
     
    768768        struct vbox_private *vbox = crtc->dev->dev_private;
    769769        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
     770        struct ttm_bo_kmap_obj uobj_map;
     771        size_t data_size, mask_size;
    770772        struct drm_gem_object *obj;
     773        u32 flags, caps = 0;
    771774        struct vbox_bo *bo;
    772         int ret, rc;
    773         struct ttm_bo_kmap_obj uobj_map;
     775        bool src_isiomem;
     776        u8 *dst = NULL;
    774777        u8 *src;
    775         u8 *dst = NULL;
    776         u32 caps = 0;
    777         size_t data_size, mask_size;
    778         bool src_isiomem;
     778        int ret;
    779779
    780780        if (!handle) {
     
    785785                vbox_crtc->cursor_enabled = false;
    786786                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
    787                                     head)
     787                                    head) {
    788788                        if (to_vbox_crtc(crtci)->cursor_enabled)
    789789                                cursor_enabled = true;
     790                        }
    790791
    791792                if (!cursor_enabled)
    792793                        VBoxHGSMIUpdatePointerShape(vbox->guest_pool, 0, 0, 0,
    793                                                     0, 0, NULL, 0);
     794                                                   0, 0, NULL, 0);
    794795                return 0;
    795796        }
     797
    796798        vbox_crtc->cursor_enabled = true;
     799
    797800        if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
    798801            width == 0 || height == 0)
    799802                return -EINVAL;
    800         rc = VBoxQueryConfHGSMI(vbox->guest_pool,
     803        ret = VBoxQueryConfHGSMI(vbox->guest_pool,
    801804                                VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
    802         ret = rc == VINF_SUCCESS ? 0 : rc == VERR_NO_MEMORY ? -ENOMEM : -EINVAL;
    803805        if (ret)
    804                 return ret;
    805 
    806         if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE))
     806                return ret == VERR_NO_MEMORY ? -ENOMEM : -EINVAL;
     807
     808        if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
    807809                /*
    808810                 * -EINVAL means cursor_set2() not supported, -EAGAIN means
     
    810812                 */
    811813                return -EBUSY;
     814        }
    812815
    813816#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) || defined(RHEL_74)
     
    816819        obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
    817820#endif
    818         if (obj) {
    819                 bo = gem_to_vbox_bo(obj);
    820                 ret = vbox_bo_reserve(bo, false);
    821                 if (!ret) {
    822                         /*
    823                          * The mask must be calculated based on the alpha
    824                          * channel, one bit per ARGB word, and must be 32-bit
    825                          * padded.
    826                          */
    827                         mask_size = ((width + 7) / 8 * height + 3) & ~3;
    828                         data_size = width * height * 4 + mask_size;
    829                         vbox->cursor_hot_x = hot_x;
    830                         vbox->cursor_hot_y = hot_y;
    831                         vbox->cursor_width = width;
    832                         vbox->cursor_height = height;
    833                         vbox->cursor_data_size = data_size;
    834                         dst = vbox->cursor_data;
    835                         ret =
    836                             ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
    837                                         &uobj_map);
    838                         if (!ret) {
    839                                 src =
    840                                     ttm_kmap_obj_virtual(&uobj_map,
    841                                                          &src_isiomem);
    842                                 if (!src_isiomem) {
    843                                         u32 flags =
    844                                             VBOX_MOUSE_POINTER_VISIBLE |
    845                                             VBOX_MOUSE_POINTER_SHAPE |
    846                                             VBOX_MOUSE_POINTER_ALPHA;
    847                                         copy_cursor_image(src, dst, width,
    848                                                           height, mask_size);
    849                                         rc = VBoxHGSMIUpdatePointerShape(
    850                                                 vbox->guest_pool, flags,
    851                                                 vbox->cursor_hot_x,
    852                                                 vbox->cursor_hot_y,
    853                                                 width, height, dst, data_size);
    854                                         ret =
    855                                             rc == VINF_SUCCESS ? 0 : rc ==
    856                                             VERR_NO_MEMORY ? -ENOMEM : rc ==
    857                                             VERR_NOT_SUPPORTED ? -EBUSY :
    858                                             -EINVAL;
    859                                 } else {
    860                                         DRM_ERROR("src cursor bo should be in main memory\n");
    861                                 }
    862                                 ttm_bo_kunmap(&uobj_map);
    863                         } else {
    864                                 vbox->cursor_data_size = 0;
    865                         }
    866                         vbox_bo_unreserve(bo);
    867                 }
    868                 drm_gem_object_unreference_unlocked(obj);
    869         } else {
     821        if (!obj) {
    870822                DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
    871                 ret = -ENOENT;
    872         }
     823                return -ENOENT;
     824        }
     825
     826        bo = gem_to_vbox_bo(obj);
     827        ret = vbox_bo_reserve(bo, false);
     828        if (ret)
     829                goto out_unref_obj;
     830
     831        /*
     832         * The mask must be calculated based on the alpha
     833         * channel, one bit per ARGB word, and must be 32-bit
     834         * padded.
     835         */
     836        mask_size = ((width + 7) / 8 * height + 3) & ~3;
     837        data_size = width * height * 4 + mask_size;
     838        vbox->cursor_hot_x = hot_x;
     839        vbox->cursor_hot_y = hot_y;
     840        vbox->cursor_width = width;
     841        vbox->cursor_height = height;
     842        vbox->cursor_data_size = data_size;
     843        dst = vbox->cursor_data;
     844
     845        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
     846        if (ret) {
     847                vbox->cursor_data_size = 0;
     848                goto out_unreserve_bo;
     849        }
     850
     851        src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
     852        if (src_isiomem) {
     853                DRM_ERROR("src cursor bo not in main memory\n");
     854                ret = -EIO;
     855                goto out_unmap_bo;
     856        }
     857
     858        copy_cursor_image(src, dst, width, height, mask_size);
     859
     860        flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
     861                VBOX_MOUSE_POINTER_ALPHA;
     862        ret = VBoxHGSMIUpdatePointerShape(vbox->guest_pool, flags,
     863                                         vbox->cursor_hot_x, vbox->cursor_hot_y,
     864                                         width, height, dst, data_size);
     865        ret = ret == VINF_SUCCESS ? 0 : ret == VERR_NO_MEMORY ? -ENOMEM :
     866                ret == VERR_NOT_SUPPORTED ? -EBUSY : -EINVAL;
     867
     868out_unmap_bo:
     869        ttm_bo_kunmap(&uobj_map);
     870out_unreserve_bo:
     871        vbox_bo_unreserve(bo);
     872out_unref_obj:
     873        drm_gem_object_unreference_unlocked(obj);
    873874
    874875        return ret;
     
    882883        s32 crtc_y =
    883884            vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
    884         int rc;
     885        int ret;
    885886
    886887        x += vbox->cursor_hot_x;
     
    891892                vbox->cursor_data_size == 0)
    892893                return 0;
    893         rc = VBoxHGSMICursorPosition(vbox->guest_pool, true, x + crtc_x,
     894        ret = VBoxHGSMICursorPosition(vbox->guest_pool, true, x + crtc_x,
    894895                                         y + crtc_y, NULL, NULL);
    895         return rc == VINF_SUCCESS ? 0 : rc == VERR_NO_MEMORY ? -ENOMEM : rc ==
     896        return ret == VINF_SUCCESS ? 0 : ret == VERR_NO_MEMORY ? -ENOMEM : ret ==
    896897                VERR_NOT_SUPPORTED ? -EBUSY : -EINVAL;
    897898}
  • trunk/src/VBox/Additions/linux/drm/vbox_prime.c

    r74615 r74773  
    11/*
    22 * Copyright (C) 2017 Oracle Corporation
    3  * This file is based on ????.c?
    43 * Copyright 2017 Canonical
    54 *
     
    5049}
    5150
    52 struct drm_gem_object *vbox_gem_prime_import_sg_table(struct drm_device *dev,
    5351#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) && !defined(RHEL_72)
    54                                                       size_t size,
     52struct drm_gem_object *vbox_gem_prime_import_sg_table(
     53        struct drm_device *dev, size_t size, struct sg_table *table)
    5554#else
    56                                                       struct dma_buf_attachment
    57                                                       *attach,
     55struct drm_gem_object *vbox_gem_prime_import_sg_table(
     56        struct drm_device *dev, struct dma_buf_attachment *attach,
     57        struct sg_table *table)
    5858#endif
    59                                                       struct sg_table *table)
    6059{
    6160        WARN_ONCE(1, "not implemented");
  • trunk/src/VBox/Additions/linux/drm/vbox_ttm.c

    r74615 r74773  
    6363{
    6464        struct drm_global_reference *global_ref;
    65         int r;
     65        int ret;
    6666
    6767        global_ref = &vbox->ttm.mem_global_ref;
     
    7070        global_ref->init = &vbox_ttm_mem_global_init;
    7171        global_ref->release = &vbox_ttm_mem_global_release;
    72         r = drm_global_item_ref(global_ref);
    73         if (r != 0) {
    74                 DRM_ERROR("Failed setting up TTM memory accounting subsystem.\n");
    75                 return r;
     72        ret = drm_global_item_ref(global_ref);
     73        if (ret) {
     74                DRM_ERROR("Failed setting up TTM memory subsystem.\n");
     75                return ret;
    7676        }
    7777
     
    8383        global_ref->release = &ttm_bo_global_release;
    8484
    85         r = drm_global_item_ref(global_ref);
    86         if (r != 0) {
     85        ret = drm_global_item_ref(global_ref);
     86        if (ret) {
    8787                DRM_ERROR("Failed setting up TTM BO subsystem.\n");
    8888                drm_global_item_unref(&vbox->ttm.mem_global_ref);
    89                 return r;
     89                return ret;
    9090        }
    9191
     
    9898static void vbox_ttm_global_release(struct vbox_private *vbox)
    9999{
    100         if (!vbox->ttm.mem_global_ref.release)
    101                 return;
    102 
    103100        drm_global_item_unref(&vbox->ttm.bo_global_ref.ref);
    104101        drm_global_item_unref(&vbox->ttm.mem_global_ref);
    105         vbox->ttm.mem_global_ref.release = NULL;
    106102}
    107103
     
    305301        if (ret) {
    306302                DRM_ERROR("Error initialising bo driver; %d\n", ret);
    307                 return ret;
     303                goto err_ttm_global_release;
    308304        }
    309305
     
    312308        if (ret) {
    313309                DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
    314                 return ret;
    315         }
     310                goto err_device_release;
     311        }
     312
    316313#ifdef DRM_MTRR_WC
    317314        vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
     
    322319                                         pci_resource_len(dev->pdev, 0));
    323320#endif
    324 
    325         vbox->ttm.mm_initialised = true;
    326 
    327         return 0;
     321        return 0;
     322
     323err_device_release:
     324        ttm_bo_device_release(&vbox->ttm.bdev);
     325err_ttm_global_release:
     326        vbox_ttm_global_release(vbox);
     327        return ret;
    328328}
    329329
    330330void vbox_mm_fini(struct vbox_private *vbox)
    331331{
    332 #ifdef DRM_MTRR_WC
    333         struct drm_device *dev = vbox->dev;
    334 #endif
    335         if (!vbox->ttm.mm_initialised)
    336                 return;
    337         ttm_bo_device_release(&vbox->ttm.bdev);
    338 
    339         vbox_ttm_global_release(vbox);
    340 
    341332#ifdef DRM_MTRR_WC
    342333        drm_mtrr_del(vbox->fb_mtrr,
    343                      pci_resource_start(dev->pdev, 0),
    344                      pci_resource_len(dev->pdev, 0), DRM_MTRR_WC);
     334                     pci_resource_start(vbox->dev->pdev, 0),
     335                     pci_resource_len(vbox->dev->pdev, 0), DRM_MTRR_WC);
    345336#else
    346337        arch_phys_wc_del(vbox->fb_mtrr);
    347338#endif
     339        ttm_bo_device_release(&vbox->ttm.bdev);
     340        vbox_ttm_global_release(vbox);
    348341}
    349342
     
    373366        bo->placement.num_placement = c;
    374367        bo->placement.num_busy_placement = c;
     368
    375369#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) || defined(RHEL_72)
    376370        for (i = 0; i < c; ++i) {
     
    394388
    395389        ret = drm_gem_object_init(dev, &vboxbo->gem, size);
    396         if (ret) {
    397                 kfree(vboxbo);
    398                 return ret;
    399         }
     390        if (ret)
     391                goto err_free_vboxbo;
    400392
    401393        vboxbo->bo.bdev = &vbox->ttm.bdev;
     
    417409#endif
    418410#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) || defined(RHEL_72)
    419                           NULL,
    420 #endif
     411                          NULL, NULL, vbox_bo_ttm_destroy);
     412#else
    421413                          NULL, vbox_bo_ttm_destroy);
     414#endif
    422415        if (ret)
    423                 return ret;
     416                goto err_free_vboxbo;
    424417
    425418        *pvboxbo = vboxbo;
    426419
    427420        return 0;
     421
     422err_free_vboxbo:
     423        kfree(vboxbo);
     424        return ret;
    428425}
    429426
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette