diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-03-25 11:05:11 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-03-25 11:05:12 +0100 |
commit | 0bec6219e5a0cf2dd17716949a7592807e10f3d7 (patch) | |
tree | 3eabbc70c5d9c053fbdc269bc09bf622b6ad1400 /drivers/staging | |
parent | 535f6f5d7b7f7b3127c1c8172ff0504260d14f45 (diff) | |
parent | ff01e6971ecd9ba6a9c0538c46d713f38a751f11 (diff) |
Merge tag 'drm-misc-next-2019-03-21' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.2:
UAPI Changes:
- Add Colorspace connector property (Uma)
- fourcc: Several new YUV formats from ARM (Brian & Ayan)
- fourcc: Fix merge conflicts between new formats above and Swati's that
went in via topic/hdr-formats-2019-03-07 branch (Maarten)
Cross-subsystem Changes:
- Typed component support via topic/component-typed-2019-02-11 (Maxime/Daniel)
Core Changes:
- Improve component helper documentation (Daniel)
- Avoid calling drm_dev_unregister() twice on unplugged devices (Noralf)
- Add device managed (devm) drm_device init function (Noralf)
- Graduate TINYDRM_MODE to DRM_SIMPLE_MODE in core (Noralf)
- Move MIPI/DSI rate control params computation into core from i915 (David)
- Add support for shmem backed gem objects (Noralf)
Driver Changes:
- various: Use of_node_name_eq for node name comparisons (Rob Herring)
- sun4i: Add DSI burst mode support (Konstantin)
- panel: Add Ronbo RB070D30 MIPI/DSI panel support (Konstantin)
- virtio: A few prime improvements (Gerd)
- tinydrm: Remove tinydrm_device (Noralf)
- vc4: Add load tracker to driver to detect underflow in atomic check (Boris)
- vboxvideo: Move it out of staging \o/ (Hans)
- v3d: Add support for V3D v4.2 (Eric)
Cc: Konstantin Sudakov <k.sudakov@integrasources.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Cc: Noralf Trønnes <noralf@tronnes.org>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: David Francis <David.Francis@amd.com>
Cc: Boris Brezillon <boris.brezillon@bootlin.com>
Cc: Eric Anholt <eric@anholt.net>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Brian Starkey <brian.starkey@arm.com>
Cc: Ayan Kumar Halder <ayan.halder@arm.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20190321170805.GA50145@art_vandelay
Diffstat (limited to 'drivers/staging')
23 files changed, 0 insertions, 4034 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index c0901b96cfe4..dee9e928d9dd 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -96,8 +96,6 @@ source "drivers/staging/greybus/Kconfig" source "drivers/staging/vc04_services/Kconfig" -source "drivers/staging/vboxvideo/Kconfig" - source "drivers/staging/pi433/Kconfig" source "drivers/staging/mt7621-pci/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 57c6bce13ff4..d344078c5458 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_KS7010) += ks7010/ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ -obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ diff --git a/drivers/staging/vboxvideo/Kconfig b/drivers/staging/vboxvideo/Kconfig deleted file mode 100644 index 1f4182e2e980..000000000000 --- a/drivers/staging/vboxvideo/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config DRM_VBOXVIDEO - tristate "Virtual Box Graphics Card" - depends on DRM && X86 && PCI - select DRM_KMS_HELPER - select DRM_TTM - select GENERIC_ALLOCATOR - help - This is a KMS driver for the virtual Graphics Card used in - Virtual Box virtual machines. - - Although it is possible to build this driver built-in to the - kernel, it is advised to build it as a module, so that it can - be updated independently of the kernel. Select M to build this - driver as a module and add support for these devices via drm/kms - interfaces. diff --git a/drivers/staging/vboxvideo/Makefile b/drivers/staging/vboxvideo/Makefile deleted file mode 100644 index 1224f313af0c..000000000000 --- a/drivers/staging/vboxvideo/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -vboxvideo-y := hgsmi_base.o modesetting.o vbva_base.o \ - vbox_drv.o vbox_fb.o vbox_hgsmi.o vbox_irq.o vbox_main.o \ - vbox_mode.o vbox_prime.o vbox_ttm.o - -obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo.o diff --git a/drivers/staging/vboxvideo/TODO b/drivers/staging/vboxvideo/TODO deleted file mode 100644 index 7f97c47a4042..000000000000 --- a/drivers/staging/vboxvideo/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: --Get a full review from the drm-maintainers on dri-devel done on this driver --Drop all the logic around initial_mode_queried, the master_set and - master_drop callbacks and everything related to this. kms clients can handle - hotplugs. --Extend this TODO with the results of that review - -Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>, -Hans de Goede <hdegoede@redhat.com>, Michael Thayer <michael.thayer@oracle.com> -and dri-devel@lists.freedesktop.org . diff --git a/drivers/staging/vboxvideo/hgsmi_base.c b/drivers/staging/vboxvideo/hgsmi_base.c deleted file mode 100644 index 361d3193258e..000000000000 --- a/drivers/staging/vboxvideo/hgsmi_base.c +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: MIT -/* Copyright (C) 2006-2017 Oracle Corporation */ - -#include <linux/vbox_err.h> -#include "vbox_drv.h" -#include "vboxvideo_guest.h" -#include "vboxvideo_vbe.h" -#include "hgsmi_channels.h" -#include "hgsmi_ch_setup.h" - -/** - * Inform the host of the location of the host flags in VRAM via an HGSMI cmd. - * Return: 0 or negative errno value. - * @ctx: The context of the guest heap to use. - * @location: The offset chosen for the flags within guest VRAM. - */ -int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location) -{ - struct hgsmi_buffer_location *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI, - HGSMI_CC_HOST_FLAGS_LOCATION); - if (!p) - return -ENOMEM; - - p->buf_location = location; - p->buf_len = sizeof(struct hgsmi_host_flags); - - hgsmi_buffer_submit(ctx, p); - hgsmi_buffer_free(ctx, p); - - return 0; -} - -/** - * Notify the host of HGSMI-related guest capabilities via an HGSMI command. - * Return: 0 or negative errno value. - * @ctx: The context of the guest heap to use. - * @caps: The capabilities to report, see vbva_caps. - */ -int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps) -{ - struct vbva_caps *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS); - if (!p) - return -ENOMEM; - - p->rc = VERR_NOT_IMPLEMENTED; - p->caps = caps; - - hgsmi_buffer_submit(ctx, p); - - WARN_ON_ONCE(p->rc < 0); - - hgsmi_buffer_free(ctx, p); - - return 0; -} - -int hgsmi_test_query_conf(struct gen_pool *ctx) -{ - u32 value = 0; - int ret; - - ret = hgsmi_query_conf(ctx, U32_MAX, &value); - if (ret) - return ret; - - return value == U32_MAX ? 0 : -EIO; -} - -/** - * Query the host for an HGSMI configuration parameter via an HGSMI command. - * Return: 0 or negative errno value. - * @ctx: The context containing the heap used. - * @index: The index of the parameter to query. - * @value_ret: Where to store the value of the parameter on success. - */ -int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret) -{ - struct vbva_conf32 *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, - VBVA_QUERY_CONF32); - if (!p) - return -ENOMEM; - - p->index = index; - p->value = U32_MAX; - - hgsmi_buffer_submit(ctx, p); - - *value_ret = p->value; - - hgsmi_buffer_free(ctx, p); - - return 0; -} - -/** - * Pass the host a new mouse pointer shape via an HGSMI command. - * Return: 0 or negative errno value. - * @ctx: The context containing the heap to be used. - * @flags: Cursor flags. - * @hot_x: Horizontal position of the hot spot. - * @hot_y: Vertical position of the hot spot. - * @width: Width in pixels of the cursor. - * @height: Height in pixels of the cursor. - * @pixels: Pixel data, @see VMMDevReqMousePointer for the format. - * @len: Size in bytes of the pixel data. - */ -int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags, - u32 hot_x, u32 hot_y, u32 width, u32 height, - u8 *pixels, u32 len) -{ - struct vbva_mouse_pointer_shape *p; - u32 pixel_len = 0; - int rc; - - if (flags & VBOX_MOUSE_POINTER_SHAPE) { - /* - * Size of the pointer data: - * sizeof (AND mask) + sizeof (XOR_MASK) - */ - pixel_len = ((((width + 7) / 8) * height + 3) & ~3) + - width * 4 * height; - if (pixel_len > len) - return -EINVAL; - - /* - * If shape is supplied, then always create the pointer visible. - * See comments in 'vboxUpdatePointerShape' - */ - flags |= VBOX_MOUSE_POINTER_VISIBLE; - } - - p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA, - VBVA_MOUSE_POINTER_SHAPE); - if (!p) - return -ENOMEM; - - p->result = VINF_SUCCESS; - p->flags = flags; - p->hot_X = hot_x; - p->hot_y = hot_y; - p->width = width; - p->height = height; - if (pixel_len) - memcpy(p->data, pixels, pixel_len); - - hgsmi_buffer_submit(ctx, p); - - switch (p->result) { - case VINF_SUCCESS: - rc = 0; - break; - case VERR_NO_MEMORY: - rc = -ENOMEM; - break; - case VERR_NOT_SUPPORTED: - rc = -EBUSY; - break; - default: - rc = -EINVAL; - } - - hgsmi_buffer_free(ctx, p); - - return rc; -} - -/** - * Report the guest cursor position. The host may wish to use this information - * to re-position its own cursor (though this is currently unlikely). The - * current host cursor position is returned. - * Return: 0 or negative errno value. - * @ctx: The context containing the heap used. - * @report_position: Are we reporting a position? - * @x: Guest cursor X position. - * @y: Guest cursor Y position. - * @x_host: Host cursor X position is stored here. Optional. - * @y_host: Host cursor Y position is stored here. Optional. - */ -int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position, - u32 x, u32 y, u32 *x_host, u32 *y_host) -{ - struct vbva_cursor_position *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, - VBVA_CURSOR_POSITION); - if (!p) - return -ENOMEM; - - p->report_position = report_position; - p->x = x; - p->y = y; - - hgsmi_buffer_submit(ctx, p); - - *x_host = p->x; - *y_host = p->y; - - hgsmi_buffer_free(ctx, p); - - return 0; -} diff --git a/drivers/staging/vboxvideo/hgsmi_ch_setup.h b/drivers/staging/vboxvideo/hgsmi_ch_setup.h deleted file mode 100644 index 4e93418d6a13..000000000000 --- a/drivers/staging/vboxvideo/hgsmi_ch_setup.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright (C) 2006-2017 Oracle Corporation */ - -#ifndef __HGSMI_CH_SETUP_H__ -#define __HGSMI_CH_SETUP_H__ - -/* - * Tell the host the location of hgsmi_host_flags structure, where the host - * can write information about pending buffers, etc, and which can be quickly - * polled by the guest without a need to port IO. - */ -#define HGSMI_CC_HOST_FLAGS_LOCATION 0 - -struct hgsmi_buffer_location { - u32 buf_location; - u32 buf_len; -} __packed; - -/* HGSMI setup and configuration data structures. */ - -#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x01u -#define HGSMIHOSTFLAGS_IRQ 0x02u -#define HGSMIHOSTFLAGS_VSYNC 0x10u -#define HGSMIHOSTFLAGS_HOTPLUG 0x20u -#define HGSMIHOSTFLAGS_CURSOR_CAPABILITIES 0x40u - -struct hgsmi_host_flags { - u32 host_flags; - u32 reserved[3]; -} __packed; - -#endif diff --git a/drivers/staging/vboxvideo/hgsmi_channels.h b/drivers/staging/vboxvideo/hgsmi_channels.h deleted file mode 100644 index 9b83f4ff3faf..000000000000 --- a/drivers/staging/vboxvideo/hgsmi_channels.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright (C) 2006-2017 Oracle Corporation */ - -#ifndef __HGSMI_CHANNELS_H__ -#define __HGSMI_CHANNELS_H__ - -/* - * Each channel has an 8 bit identifier. There are a number of predefined - * (hardcoded) channels. - * - * HGSMI_CH_HGSMI channel can be used to map a string channel identifier - * to a free 16 bit numerical value. values are allocated in range - * [HGSMI_CH_STRING_FIRST;HGSMI_CH_STRING_LAST]. - */ - -/* A reserved channel value */ -#define HGSMI_CH_RESERVED 0x00 -/* HGCMI: setup and configuration */ -#define HGSMI_CH_HGSMI 0x01 -/* Graphics: VBVA */ -#define HGSMI_CH_VBVA 0x02 -/* Graphics: Seamless with a single guest region */ -#define HGSMI_CH_SEAMLESS 0x03 -/* Graphics: Seamless with separate host windows */ -#define HGSMI_CH_SEAMLESS2 0x04 -/* Graphics: OpenGL HW acceleration */ -#define HGSMI_CH_OPENGL 0x05 - -/* The first channel index to be used for string mappings (inclusive) */ -#define HGSMI_CH_STRING_FIRST 0x20 -/* The last channel index for string mappings (inclusive) */ -#define HGSMI_CH_STRING_LAST 0xff - -#endif diff --git a/drivers/staging/vboxvideo/hgsmi_defs.h b/drivers/staging/vboxvideo/hgsmi_defs.h deleted file mode 100644 index 6c8df1cdb087..000000000000 --- a/drivers/staging/vboxvideo/hgsmi_defs.h +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright (C) 2006-2017 Oracle Corporation */ - -#ifndef __HGSMI_DEFS_H__ -#define __HGSMI_DEFS_H__ - -/* Buffer sequence type mask. */ -#define HGSMI_BUFFER_HEADER_F_SEQ_MASK 0x03 -/* Single buffer, not a part of a sequence. */ -#define HGSMI_BUFFER_HEADER_F_SEQ_SINGLE 0x00 -/* The first buffer in a sequence. */ -#define HGSMI_BUFFER_HEADER_F_SEQ_START 0x01 -/* A middle buffer in a sequence. */ -#define HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE 0x02 -/* The last buffer in a sequence. */ -#define HGSMI_BUFFER_HEADER_F_SEQ_END 0x03 - -/* 16 bytes buffer header. */ -struct hgsmi_buffer_header { - u32 data_size; /* Size of data that follows the header. */ - u8 flags; /* HGSMI_BUFFER_HEADER_F_* */ - u8 channel; /* The channel the data must be routed to. */ - u16 channel_info; /* Opaque to the HGSMI, used by the channel. */ - - union { - /* Opaque placeholder to make the union 8 bytes. */ - u8 header_data[8]; - - /* HGSMI_BUFFER_HEADER_F_SEQ_SINGLE */ - struct { - u32 reserved1; /* A reserved field, initialize to 0. */ - u32 reserved2; /* A reserved field, initialize to 0. */ - } buffer; - - /* HGSMI_BUFFER_HEADER_F_SEQ_START */ - struct { - /* Must be the same for all buffers in the sequence. */ - u32 sequence_number; - /* The total size of the sequence. */ - u32 sequence_size; - } sequence_start; - - /* - * HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE and - * HGSMI_BUFFER_HEADER_F_SEQ_END - */ - struct { - /* Must be the same for all buffers in the sequence. */ - u32 sequence_number; - /* Data offset in the entire sequence. */ - u32 sequence_offset; - } sequence_continue; - } u; -} __packed; - -/* 8 bytes buffer tail. */ -struct hgsmi_buffer_tail { - /* Reserved, must be initialized to 0. */ - u32 reserved; - /* - * One-at-a-Time Hash: http://www.burtleburtle.net/bob/hash/doobs.html - * Over the header, offset and for first 4 bytes of the tail. - */ - u32 checksum; -} __packed; - -/* - * The size of the array of channels. Array indexes are u8. - * Note: the value must not be changed. - */ -#define HGSMI_NUMBER_OF_CHANNELS 0x100 - -#endif diff --git a/drivers/staging/vboxvideo/modesetting.c b/drivers/staging/vboxvideo/modesetting.c deleted file mode 100644 index 7580b9002379..000000000000 --- a/drivers/staging/vboxvideo/modesetting.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: MIT -/* Copyright (C) 2006-2017 Oracle Corporation */ - -#include <linux/vbox_err.h> -#include "vbox_drv.h" -#include "vboxvideo_guest.h" -#include "vboxvideo_vbe.h" -#include "hgsmi_channels.h" - -/** - * Set a video mode via an HGSMI request. The views must have been - * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being - * set on the first display then it must be set first using registers. - * @ctx: The context containing the heap to use. - * @display: The screen number. - * @origin_x: The horizontal displacement relative to the first scrn. - * @origin_y: The vertical displacement relative to the first screen. - * @start_offset: The offset of the visible area of the framebuffer - * relative to the framebuffer start. - * @pitch: The offset in bytes between the starts of two adjecent - * scan lines in video RAM. - * @width: The mode width. - * @height: The mode height. - * @bpp: The colour depth of the mode. - * @flags: Flags. - */ -void hgsmi_process_display_info(struct gen_pool *ctx, u32 display, - s32 origin_x, s32 origin_y, u32 start_offset, - u32 pitch, u32 width, u32 height, - u16 bpp, u16 flags) -{ - struct vbva_infoscreen *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, - VBVA_INFO_SCREEN); - if (!p) - return; - - p->view_index = display; - p->origin_x = origin_x; - p->origin_y = origin_y; - p->start_offset = start_offset; - p->line_size = pitch; - p->width = width; - p->height = height; - p->bits_per_pixel = bpp; - p->flags = flags; - - hgsmi_buffer_submit(ctx, p); - hgsmi_buffer_free(ctx, p); -} - -/** - * Report the rectangle relative to which absolute pointer events should be - * expressed. This information remains valid until the next VBVA resize event - * for any screen, at which time it is reset to the bounding rectangle of all - * virtual screens. - * Return: 0 or negative errno value. - * @ctx: The context containing the heap to use. - * @origin_x: Upper left X co-ordinate relative to the first screen. - * @origin_y: Upper left Y co-ordinate relative to the first screen. - * @width: Rectangle width. - * @height: Rectangle height. - */ -int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y, - u32 width, u32 height) -{ - struct vbva_report_input_mapping *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, - VBVA_REPORT_INPUT_MAPPING); - if (!p) - return -ENOMEM; - - p->x = origin_x; - p->y = origin_y; - p->cx = width; - p->cy = height; - - hgsmi_buffer_submit(ctx, p); - hgsmi_buffer_free(ctx, p); - - return 0; -} - -/** - * Get most recent video mode hints. - * Return: 0 or negative errno value. - * @ctx: The context containing the heap to use. - * @screens: The number of screens to query hints for, starting at 0. - * @hints: Array of vbva_modehint structures for receiving the hints. - */ -int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens, - struct vbva_modehint *hints) -{ - struct vbva_query_mode_hints *p; - size_t size; - - if (WARN_ON(!hints)) - return -EINVAL; - - size = screens * sizeof(struct vbva_modehint); - p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA, - VBVA_QUERY_MODE_HINTS); - if (!p) - return -ENOMEM; - - p->hints_queried_count = screens; - p->hint_structure_guest_size = sizeof(struct vbva_modehint); - p->rc = VERR_NOT_SUPPORTED; - - hgsmi_buffer_submit(ctx, p); - - if (p->rc < 0) { - hgsmi_buffer_free(ctx, p); - return -EIO; - } - - memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size); - hgsmi_buffer_free(ctx, p); - - return 0; -} diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c deleted file mode 100644 index e7755a179850..000000000000 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ /dev/null @@ -1,283 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2013-2017 Oracle Corporation - * This file is based on ast_drv.c - * Copyright 2012 Red Hat Inc. - * Authors: Dave Airlie <airlied@redhat.com> - * Michael Thayer <michael.thayer@oracle.com, - * Hans de Goede <hdegoede@redhat.com> - */ -#include <linux/console.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/vt_kern.h> - -#include <drm/drm_crtc_helper.h> -#include <drm/drm_drv.h> -#include <drm/drm_file.h> -#include <drm/drm_ioctl.h> - -#include "vbox_drv.h" - -static int vbox_modeset = -1; - -MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); -module_param_named(modeset, vbox_modeset, int, 0400); - -static struct drm_driver driver; - -static const struct pci_device_id pciidlist[] = { - { PCI_DEVICE(0x80ee, 0xbeef) }, - { } -}; -MODULE_DEVICE_TABLE(pci, pciidlist); - -static struct drm_fb_helper_funcs vbox_fb_helper_funcs = { - .fb_probe = vboxfb_create, -}; - -static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct vbox_private *vbox; - int ret = 0; - - if (!vbox_check_supported(VBE_DISPI_ID_HGSMI)) - return -ENODEV; - - vbox = kzalloc(sizeof(*vbox), GFP_KERNEL); - if (!vbox) - return -ENOMEM; - - ret = drm_dev_init(&vbox->ddev, &driver, &pdev->dev); - if (ret) { - kfree(vbox); - return ret; - } - - vbox->ddev.pdev = pdev; - vbox->ddev.dev_private = vbox; - pci_set_drvdata(pdev, vbox); - mutex_init(&vbox->hw_mutex); - - ret = pci_enable_device(pdev); - if (ret) - goto err_dev_put; - - ret = vbox_hw_init(vbox); - if (ret) - goto err_pci_disable; - - ret = vbox_mm_init(vbox); - if (ret) - goto err_hw_fini; - - ret = vbox_mode_init(vbox); - if (ret) - goto err_mm_fini; - - ret = vbox_irq_init(vbox); - if (ret) - goto err_mode_fini; - - ret = drm_fb_helper_fbdev_setup(&vbox->ddev, &vbox->fb_helper, - &vbox_fb_helper_funcs, 32, - vbox->num_crtcs); - if (ret) - goto err_irq_fini; - - ret = drm_dev_register(&vbox->ddev, 0); - if (ret) - goto err_fbdev_fini; - - return 0; - -err_fbdev_fini: - vbox_fbdev_fini(vbox); -err_irq_fini: - vbox_irq_fini(vbox); -err_mode_fini: - vbox_mode_fini(vbox); -err_mm_fini: - vbox_mm_fini(vbox); -err_hw_fini: - vbox_hw_fini(vbox); -err_pci_disable: - pci_disable_device(pdev); -err_dev_put: - drm_dev_put(&vbox->ddev); - return ret; -} - -static void vbox_pci_remove(struct pci_dev *pdev) -{ - struct vbox_private *vbox = pci_get_drvdata(pdev); - - drm_dev_unregister(&vbox->ddev); - vbox_fbdev_fini(vbox); - vbox_irq_fini(vbox); - vbox_mode_fini(vbox); - vbox_mm_fini(vbox); - vbox_hw_fini(vbox); - drm_dev_put(&vbox->ddev); -} - -#ifdef CONFIG_PM_SLEEP -static int vbox_pm_suspend(struct device *dev) -{ - struct vbox_private *vbox = dev_get_drvdata(dev); - int error; - - error = drm_mode_config_helper_suspend(&vbox->ddev); - if (error) - return error; - - pci_save_state(vbox->ddev.pdev); - pci_disable_device(vbox->ddev.pdev); - pci_set_power_state(vbox->ddev.pdev, PCI_D3hot); - - return 0; -} - -static int vbox_pm_resume(struct device *dev) -{ - struct vbox_private *vbox = dev_get_drvdata(dev); - - if (pci_enable_device(vbox->ddev.pdev)) - return -EIO; - - return drm_mode_config_helper_resume(&vbox->ddev); -} - -static int vbox_pm_freeze(struct device *dev) -{ - struct vbox_private *vbox = dev_get_drvdata(dev); - - return drm_mode_config_helper_suspend(&vbox->ddev); -} - -static int vbox_pm_thaw(struct device *dev) -{ - struct vbox_private *vbox = dev_get_drvdata(dev); - - return drm_mode_config_helper_resume(&vbox->ddev); -} - -static int vbox_pm_poweroff(struct device *dev) -{ - struct vbox_private *vbox = dev_get_drvdata(dev); - - return drm_mode_config_helper_suspend(&vbox->ddev); -} - -static const struct dev_pm_ops vbox_pm_ops = { - .suspend = vbox_pm_suspend, - .resume = vbox_pm_resume, - .freeze = vbox_pm_freeze, - .thaw = vbox_pm_thaw, - .poweroff = vbox_pm_poweroff, - .restore = vbox_pm_resume, -}; -#endif - -static struct pci_driver vbox_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = vbox_pci_probe, - .remove = vbox_pci_remove, -#ifdef CONFIG_PM_SLEEP - .driver.pm = &vbox_pm_ops, -#endif -}; - -static const struct file_operations vbox_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .compat_ioctl = drm_compat_ioctl, - .mmap = vbox_mmap, - .poll = drm_poll, - .read = drm_read, -}; - -static int vbox_master_set(struct drm_device *dev, - struct drm_file *file_priv, bool from_open) -{ - struct vbox_private *vbox = dev->dev_private; - - /* - * We do not yet know whether the new owner can handle hotplug, so we - * do not advertise dynamic modes on the first query and send a - * tentative hotplug notification after that to see if they query again. - */ - vbox->initial_mode_queried = false; - - return 0; -} - -static void vbox_master_drop(struct drm_device *dev, struct drm_file *file_priv) -{ - struct vbox_private *vbox = dev->dev_private; - - /* See vbox_master_set() */ - vbox->initial_mode_queried = false; -} - -static struct drm_driver driver = { - .driver_features = - DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, - - .lastclose = drm_fb_helper_lastclose, - .master_set = vbox_master_set, - .master_drop = vbox_master_drop, - - .fops = &vbox_fops, - .irq_handler = vbox_irq_handler, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, - - .gem_free_object_unlocked = vbox_gem_free_object, - .dumb_create = vbox_dumb_create, - .dumb_map_offset = vbox_dumb_mmap_offset, - .prime_handle_to_fd = drm_gem_prime_handle_to_fd, - .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, - .gem_prime_pin = vbox_gem_prime_pin, - .gem_prime_unpin = vbox_gem_prime_unpin, - .gem_prime_get_sg_table = vbox_gem_prime_get_sg_table, - .gem_prime_import_sg_table = vbox_gem_prime_import_sg_table, - .gem_prime_vmap = vbox_gem_prime_vmap, - .gem_prime_vunmap = vbox_gem_prime_vunmap, - .gem_prime_mmap = vbox_gem_prime_mmap, -}; - -static int __init vbox_init(void) -{ -#ifdef CONFIG_VGA_CONSOLE - if (vgacon_text_force() && vbox_modeset == -1) - return -EINVAL; -#endif - - if (vbox_modeset == 0) - return -EINVAL; - - return pci_register_driver(&vbox_pci_driver); -} - -static void __exit vbox_exit(void) -{ - pci_unregister_driver(&vbox_pci_driver); -} - -module_init(vbox_init); -module_exit(vbox_exit); - -MODULE_AUTHOR("Oracle Corporation"); -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h deleted file mode 100644 index aa40e5cc2861..000000000000 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ /dev/null @@ -1,280 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright (C) 2013-2017 Oracle Corporation - * This file is based on ast_drv.h - * Copyright 2012 Red Hat Inc. - * Authors: Dave Airlie <airlied@redhat.com> - * Michael Thayer <michael.thayer@oracle.com, - * Hans de Goede <hdegoede@redhat.com> - */ -#ifndef __VBOX_DRV_H__ -#define __VBOX_DRV_H__ - -#include <linux/genalloc.h> -#include <linux/io.h> -#include <linux/irqreturn.h> -#include <linux/string.h> -#include <linux/version.h> - -#include <drm/drm_encoder.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_gem.h> - -#include <drm/ttm/ttm_bo_api.h> -#include <drm/ttm/ttm_bo_driver.h> -#include <drm/ttm/ttm_placement.h> -#include <drm/ttm/ttm_memory.h> -#include <drm/ttm/ttm_module.h> - -#include "vboxvideo_guest.h" -#include "vboxvideo_vbe.h" -#include "hgsmi_ch_setup.h" - -#define DRIVER_NAME "vboxvideo" -#define DRIVER_DESC "Oracle VM VirtualBox Graphics Card" -#define DRIVER_DATE "20130823" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define VBOX_MAX_CURSOR_WIDTH 64 -#define VBOX_MAX_CURSOR_HEIGHT 64 -#define CURSOR_PIXEL_COUNT (VBOX_MAX_CURSOR_WIDTH * VBOX_MAX_CURSOR_HEIGHT) -#define CURSOR_DATA_SIZE (CURSOR_PIXEL_COUNT * 4 + CURSOR_PIXEL_COUNT / 8) - -#define VBOX_MAX_SCREENS 32 - -#define GUEST_HEAP_OFFSET(vbox) ((vbox)->full_vram_size - \ - VBVA_ADAPTER_INFORMATION_SIZE) -#define GUEST_HEAP_SIZE VBVA_ADAPTER_INFORMATION_SIZE -#define GUEST_HEAP_USABLE_SIZE (VBVA_ADAPTER_INFORMATION_SIZE - \ - sizeof(struct hgsmi_host_flags)) -#define HOST_FLAGS_OFFSET GUEST_HEAP_USABLE_SIZE - -struct vbox_framebuffer { - struct drm_framebuffer base; - struct drm_gem_object *obj; -}; - -struct vbox_private { - /* Must be first; or we must define our own release callback */ - struct drm_device ddev; - struct drm_fb_helper fb_helper; - struct vbox_framebuffer afb; - - u8 __iomem *guest_heap; - u8 __iomem *vbva_buffers; - struct gen_pool *guest_pool; - struct vbva_buf_ctx *vbva_info; - bool any_pitch; - u32 num_crtcs; - /* Amount of available VRAM, including space used for buffers. */ - u32 full_vram_size; - /* Amount of available VRAM, not including space used for buffers. */ - u32 available_vram_size; - /* Array of structures for receiving mode hints. */ - struct vbva_modehint *last_mode_hints; - - int fb_mtrr; - - struct { - struct ttm_bo_device bdev; - } ttm; - - struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */ - /* - * We decide whether or not user-space supports display hot-plug - * depending on whether they react to a hot-plug event after the initial - * mode query. - */ - bool initial_mode_queried; - struct work_struct hotplug_work; - u32 input_mapping_width; - u32 input_mapping_height; - /* - * Is user-space using an X.Org-style layout of one large frame-buffer - * encompassing all screen ones or is the fbdev console active? - */ - bool single_framebuffer; - u8 cursor_data[CURSOR_DATA_SIZE]; -}; - -#undef CURSOR_PIXEL_COUNT -#undef CURSOR_DATA_SIZE - -struct vbox_gem_object; - -struct vbox_connector { - struct drm_connector base; - char name[32]; - struct vbox_crtc *vbox_crtc; - struct { - u32 width; - u32 height; - bool disconnected; - } mode_hint; -}; - -struct vbox_crtc { - struct drm_crtc base; - bool disconnected; - unsigned int crtc_id; - u32 fb_offset; - bool cursor_enabled; - u32 x_hint; - u32 y_hint; - /* - * When setting a mode we not only pass the mode to the hypervisor, - * but also information on how to map / translate input coordinates - * for the emulated USB tablet. This input-mapping may change when - * the mode on *another* crtc changes. - * - * This means that sometimes we must do a modeset on other crtc-s then - * the one being changed to update the input-mapping. Including crtc-s - * which may be disabled inside the guest (shown as a black window - * on the host unless closed by the user). - * - * With atomic modesetting the mode-info of disabled crtcs gets zeroed - * yet we need it when updating the input-map to avoid resizing the - * window as a side effect of a mode_set on another crtc. Therefor we - * cache the info of the last mode below. - */ - u32 width; - u32 height; - u32 x; - u32 y; -}; - -struct vbox_encoder { - struct drm_encoder base; -}; - -#define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base) -#define to_vbox_connector(x) container_of(x, struct vbox_connector, base) -#define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base) -#define to_vbox_framebuffer(x) container_of(x, struct vbox_framebuffer, base) - -bool vbox_check_supported(u16 id); -int vbox_hw_init(struct vbox_private *vbox); -void vbox_hw_fini(struct vbox_private *vbox); - -int vbox_mode_init(struct vbox_private *vbox); -void vbox_mode_fini(struct vbox_private *vbox); - -void vbox_report_caps(struct vbox_private *vbox); - -void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb, - struct drm_clip_rect *rects, - unsigned int num_rects); - -int vbox_framebuffer_init(struct vbox_private *vbox, - struct vbox_framebuffer *vbox_fb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); - -int vboxfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes); -void vbox_fbdev_fini(struct vbox_private *vbox); - -struct vbox_bo { - struct ttm_buffer_object bo; - struct ttm_placement placement; - struct ttm_bo_kmap_obj kmap; - struct drm_gem_object gem; - struct ttm_place placements[3]; - int pin_count; -}; - -#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem) - -static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo) -{ - return container_of(bo, struct vbox_bo, bo); -} - -#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base) - -static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo) -{ - return bo->bo.offset; -} - -int vbox_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args); - -void vbox_gem_free_object(struct drm_gem_object *obj); -int vbox_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - u32 handle, u64 *offset); - -#define DRM_FILE_PAGE_OFFSET (0x10000000ULL >> PAGE_SHIFT) - -int vbox_mm_init(struct vbox_private *vbox); -void vbox_mm_fini(struct vbox_private *vbox); - -int vbox_bo_create(struct vbox_private *vbox, int size, int align, - u32 flags, struct vbox_bo **pvboxbo); - -int vbox_gem_create(struct vbox_private *vbox, - u32 size, bool iskernel, struct drm_gem_object **obj); - -int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag); -int vbox_bo_unpin(struct vbox_bo *bo); - -static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait) -{ - int ret; - - ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL); - if (ret) { - if (ret != -ERESTARTSYS && ret != -EBUSY) - DRM_ERROR("reserve failed %p\n", bo); - return ret; - } - return 0; -} - -static inline void vbox_bo_unreserve(struct vbox_bo *bo) -{ - ttm_bo_unreserve(&bo->bo); -} - -void vbox_ttm_placement(struct vbox_bo *bo, int domain); -int vbox_bo_push_sysram(struct vbox_bo *bo); -int vbox_mmap(struct file *filp, struct vm_area_struct *vma); -void *vbox_bo_kmap(struct vbox_bo *bo); -void vbox_bo_kunmap(struct vbox_bo *bo); - -/* vbox_prime.c */ -int vbox_gem_prime_pin(struct drm_gem_object *obj); -void vbox_gem_prime_unpin(struct drm_gem_object *obj); -struct sg_table *vbox_gem_prime_get_sg_table(struct drm_gem_object *obj); -struct drm_gem_object *vbox_gem_prime_import_sg_table( - struct drm_device *dev, struct dma_buf_attachment *attach, - struct sg_table *table); -void *vbox_gem_prime_vmap(struct drm_gem_object *obj); -void vbox_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); -int vbox_gem_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *area); - -/* vbox_irq.c */ -int vbox_irq_init(struct vbox_private *vbox); -void vbox_irq_fini(struct vbox_private *vbox); -void vbox_report_hotplug(struct vbox_private *vbox); -irqreturn_t vbox_irq_handler(int irq, void *arg); - -/* vbox_hgsmi.c */ -void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size, - u8 channel, u16 channel_info); -void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf); -int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf); - -static inline void vbox_write_ioport(u16 index, u16 data) -{ - outw(index, VBE_DISPI_IOPORT_INDEX); - outw(data, VBE_DISPI_IOPORT_DATA); -} - -#endif diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c deleted file mode 100644 index 83a04afd1766..000000000000 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2013-2017 Oracle Corporation - * This file is based on ast_fb.c - * Copyright 2012 Red Hat Inc. - * Authors: Dave Airlie <airlied@redhat.com> - * Michael Thayer <michael.thayer@oracle.com, - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/string.h> -#include <linux/sysrq.h> -#include <linux/tty.h> - -#include <drm/drm_crtc.h> -#include <drm/drm_crtc_helper.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_fourcc.h> - -#include "vbox_drv.h" -#include "vboxvideo.h" - -#ifdef CONFIG_DRM_KMS_FB_HELPER -static struct fb_deferred_io vbox_defio = { - .delay = HZ / 30, - .deferred_io = drm_fb_helper_deferred_io, -}; -#endif - -static struct fb_ops vboxfb_ops = { - .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, - .fb_fillrect = drm_fb_helper_sys_fillrect, - .fb_copyarea = drm_fb_helper_sys_copyarea, - .fb_imageblit = drm_fb_helper_sys_imageblit, -}; - -int vboxfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct vbox_private *vbox = - container_of(helper, struct vbox_private, fb_helper); - struct pci_dev *pdev = vbox->ddev.pdev; - struct drm_mode_fb_cmd2 mode_cmd; - struct drm_framebuffer *fb; - struct fb_info *info; - struct drm_gem_object *gobj; - struct vbox_bo *bo; - int size, ret; - u64 gpu_addr; - u32 pitch; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - pitch = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - mode_cmd.pitches[0] = pitch; - - size = pitch * mode_cmd.height; - - ret = vbox_gem_create(vbox, size, true, &gobj); - if (ret) { - DRM_ERROR("failed to create fbcon backing object %d\n", ret); - return ret; - } - - ret = vbox_framebuffer_init(vbox, &vbox->afb, &mode_cmd, gobj); - if (ret) - return ret; - - bo = gem_to_vbox_bo(gobj); - - ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM); - if (ret) - return ret; - - info = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(info)) - return PTR_ERR(info); - - info->screen_size = size; - info->screen_base = (char __iomem *)vbox_bo_kmap(bo); - if (IS_ERR(info->screen_base)) - return PTR_ERR(info->screen_base); - - info->par = helper; - - fb = &vbox->afb.base; - helper->fb = fb; - - strcpy(info->fix.id, "vboxdrmfb"); - - info->fbops = &vboxfb_ops; - - /* - * This seems to be done for safety checking that the framebuffer - * is not registered twice by different drivers. - */ - info->apertures->ranges[0].base = pci_resource_start(pdev, 0); - info->apertures->ranges[0].size = pci_resource_len(pdev, 0); - - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); - drm_fb_helper_fill_var(info, helper, sizes->fb_width, - sizes->fb_height); - - gpu_addr = vbox_bo_gpu_offset(bo); - info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr; - info->fix.smem_len = vbox->available_vram_size - gpu_addr; - -#ifdef CONFIG_DRM_KMS_FB_HELPER - info->fbdefio = &vbox_defio; - fb_deferred_io_init(info); -#endif - - info->pixmap.flags = FB_PIXMAP_SYSTEM; - - DRM_DEBUG_KMS("allocated %dx%d\n", fb->width, fb->height); - - return 0; -} - -void vbox_fbdev_fini(struct vbox_private *vbox) -{ - struct vbox_framebuffer *afb = &vbox->afb; - -#ifdef CONFIG_DRM_KMS_FB_HELPER - if (vbox->fb_helper.fbdev && vbox->fb_helper.fbdev->fbdefio) - fb_deferred_io_cleanup(vbox->fb_helper.fbdev); -#endif - - drm_fb_helper_unregister_fbi(&vbox->fb_helper); - - if (afb->obj) { - struct vbox_bo *bo = gem_to_vbox_bo(afb->obj); - - vbox_bo_kunmap(bo); - - if (bo->pin_count) - vbox_bo_unpin(bo); - - drm_gem_object_put_unlocked(afb->obj); - afb->obj = NULL; - } - drm_fb_helper_fini(&vbox->fb_helper); - - drm_framebuffer_unregister_private(&afb->base); - drm_framebuffer_cleanup(&afb->base); -} diff --git a/drivers/staging/vboxvideo/vbox_hgsmi.c b/drivers/staging/vboxvideo/vbox_hgsmi.c deleted file mode 100644 index 94b60654a012..000000000000 --- a/drivers/staging/vboxvideo/vbox_hgsmi.c +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2017 Oracle Corporation - * Authors: Hans de Goede <hdegoede@redhat.com> - */ - -#include "vbox_drv.h" -#include "vboxvideo_vbe.h" -#include "hgsmi_defs.h" - -/* One-at-a-Time Hash from http://www.burtleburtle.net/bob/hash/doobs.html */ -static u32 hgsmi_hash_process(u32 hash, const u8 *data, int size) -{ - while (size--) { - hash += *data++; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - return hash; -} - -static u32 hgsmi_hash_end(u32 hash) -{ - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash; -} - -/* Not really a checksum but that is the naming used in all vbox code */ -static u32 hgsmi_checksum(u32 offset, - const struct hgsmi_buffer_header *header, - const struct hgsmi_buffer_tail *tail) -{ - u32 checksum; - - checksum = hgsmi_hash_process(0, (u8 *)&offset, sizeof(offset)); - checksum = hgsmi_hash_process(checksum, (u8 *)header, sizeof(*header)); - /* 4 -> Do not checksum the checksum itself */ - checksum = hgsmi_hash_process(checksum, (u8 *)tail, 4); - - return hgsmi_hash_end(checksum); -} - -void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size, - u8 channel, u16 channel_info) -{ - struct hgsmi_buffer_header *h; - struct hgsmi_buffer_tail *t; - size_t total_size; - dma_addr_t offset; - - total_size = size + sizeof(*h) + sizeof(*t); - h = gen_pool_dma_alloc(guest_pool, total_size, &offset); - if (!h) - return NULL; - - t = (struct hgsmi_buffer_tail *)((u8 *)h + sizeof(*h) + size); - - h->flags = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE; - h->data_size = size; - h->channel = channel; - h->channel_info = channel_info; - memset(&h->u.header_data, 0, sizeof(h->u.header_data)); - - t->reserved = 0; - t->checksum = hgsmi_checksum(offset, h, t); - - return (u8 *)h + sizeof(*h); -} - -void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf) -{ - struct hgsmi_buffer_header *h = - (struct hgsmi_buffer_header *)((u8 *)buf - sizeof(*h)); - size_t total_size = h->data_size + sizeof(*h) + - sizeof(struct hgsmi_buffer_tail); - - gen_pool_free(guest_pool, (unsigned long)h, total_size); -} - -int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf) -{ - phys_addr_t offset; - - offset = gen_pool_virt_to_phys(guest_pool, (unsigned long)buf - - sizeof(struct hgsmi_buffer_header)); - outl(offset, VGA_PORT_HGSMI_GUEST); - /* Make the compiler aware that the host has changed memory. */ - mb(); - - return 0; -} diff --git a/drivers/staging/vboxvideo/vbox_irq.c b/drivers/staging/vboxvideo/vbox_irq.c deleted file mode 100644 index 195484713365..000000000000 --- a/drivers/staging/vboxvideo/vbox_irq.c +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2016-2017 Oracle Corporation - * This file is based on qxl_irq.c - * Copyright 2013 Red Hat Inc. - * Authors: Dave Airlie - * Alon Levy - * Michael Thayer <michael.thayer@oracle.com, - * Hans de Goede <hdegoede@redhat.com> - */ - -#include <linux/pci.h> -#include <drm/drm_irq.h> -#include <drm/drm_probe_helper.h> - -#include "vbox_drv.h" -#include "vboxvideo.h" - -static void vbox_clear_irq(void) -{ - outl((u32)~0, VGA_PORT_HGSMI_HOST); -} - -static u32 vbox_get_flags(struct vbox_private *vbox) -{ - return readl(vbox->guest_heap + HOST_FLAGS_OFFSET); -} - -void vbox_report_hotplug(struct vbox_private *vbox) -{ - schedule_work(&vbox->hotplug_work); -} - -irqreturn_t vbox_irq_handler(int irq, void *arg) -{ - struct drm_device *dev = (struct drm_device *)arg; - struct vbox_private *vbox = (struct vbox_private *)dev->dev_private; - u32 host_flags = vbox_get_flags(vbox); - - if (!(host_flags & HGSMIHOSTFLAGS_IRQ)) - return IRQ_NONE; - - /* - * Due to a bug in the initial host implementation of hot-plug irqs, - * the hot-plug and cursor capability flags were never cleared. - * Fortunately we can tell when they would have been set by checking - * that the VSYNC flag is not set. - */ - if (host_flags & - (HGSMIHOSTFLAGS_HOTPLUG | HGSMIHOSTFLAGS_CURSOR_CAPABILITIES) && - !(host_flags & HGSMIHOSTFLAGS_VSYNC)) - vbox_report_hotplug(vbox); - - vbox_clear_irq(); - - return IRQ_HANDLED; -} - -/* - * Check that the position hints provided by the host are suitable for GNOME - * shell (i.e. all screens disjoint and hints for all enabled screens) and if - * not replace them with default ones. Providing valid hints improves the - * chances that we will get a known screen layout for pointer mapping. - */ -static void validate_or_set_position_hints(struct vbox_private *vbox) -{ - struct vbva_modehint *hintsi, *hintsj; - bool valid = true; - u16 currentx = 0; - int i, j; - - for (i = 0; i < vbox->num_crtcs; ++i) { - for (j = 0; j < i; ++j) { - hintsi = &vbox->last_mode_hints[i]; - hintsj = &vbox->last_mode_hints[j]; - - if (hintsi->enabled && hintsj->enabled) { - if (hintsi->dx >= 0xffff || - hintsi->dy >= 0xffff || - hintsj->dx >= 0xffff || - hintsj->dy >= 0xffff || - (hintsi->dx < - hintsj->dx + (hintsj->cx & 0x8fff) && - hintsi->dx + (hintsi->cx & 0x8fff) > - hintsj->dx) || - (hintsi->dy < - hintsj->dy + (hintsj->cy & 0x8fff) && - hintsi->dy + (hintsi->cy & 0x8fff) > - hintsj->dy)) - valid = false; - } - } - } - if (!valid) - for (i = 0; i < vbox->num_crtcs; ++i) { - if (vbox->last_mode_hints[i].enabled) { - vbox->last_mode_hints[i].dx = currentx; - vbox->last_mode_hints[i].dy = 0; - currentx += - vbox->last_mode_hints[i].cx & 0x8fff; - } - } -} - -/* Query the host for the most recent video mode hints. */ -static void vbox_update_mode_hints(struct vbox_private *vbox) -{ - struct drm_device *dev = &vbox->ddev; - struct drm_connector *connector; - struct vbox_connector *vbox_conn; - struct vbva_modehint *hints; - u16 flags; - bool disconnected; - unsigned int crtc_id; - int ret; - - ret = hgsmi_get_mode_hints(vbox->guest_pool, vbox->num_crtcs, - vbox->last_mode_hints); - if (ret) { - DRM_ERROR("vboxvideo: hgsmi_get_mode_hints failed: %d\n", ret); - return; - } - - validate_or_set_position_hints(vbox); - drm_modeset_lock_all(dev); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - vbox_conn = to_vbox_connector(connector); - - hints = &vbox->last_mode_hints[vbox_conn->vbox_crtc->crtc_id]; - if (hints->magic != VBVAMODEHINT_MAGIC) - continue; - - disconnected = !(hints->enabled); - crtc_id = vbox_conn->vbox_crtc->crtc_id; - vbox_conn->mode_hint.width = hints->cx; - vbox_conn->mode_hint.height = hints->cy; - vbox_conn->vbox_crtc->x_hint = hints->dx; - vbox_conn->vbox_crtc->y_hint = hints->dy; - vbox_conn->mode_hint.disconnected = disconnected; - - if (vbox_conn->vbox_crtc->disconnected == disconnected) - continue; - - if (disconnected) - flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED; - else - flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_BLANK; - - hgsmi_process_display_info(vbox->guest_pool, crtc_id, 0, 0, 0, - hints->cx * 4, hints->cx, - hints->cy, 0, flags); - - vbox_conn->vbox_crtc->disconnected = disconnected; - } - drm_modeset_unlock_all(dev); -} - -static void vbox_hotplug_worker(struct work_struct *work) -{ - struct vbox_private *vbox = container_of(work, struct vbox_private, - hotplug_work); - - vbox_update_mode_hints(vbox); - drm_kms_helper_hotplug_event(&vbox->ddev); -} - -int vbox_irq_init(struct vbox_private *vbox) -{ - INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker); - vbox_update_mode_hints(vbox); - - return drm_irq_install(&vbox->ddev, vbox->ddev.pdev->irq); -} - -void vbox_irq_fini(struct vbox_private *vbox) -{ - drm_irq_uninstall(&vbox->ddev); - flush_work(&vbox->hotplug_work); -} diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c deleted file mode 100644 index e1fb70a42d32..000000000000 --- a/drivers/staging/vboxvideo/vbox_main.c +++ /dev/null @@ -1,361 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2013-2017 Oracle Corporation - * This file is based on ast_main.c - * Copyright 2012 Red Hat Inc. - * Authors: Dave Airlie <airlied@redhat.com>, - * Michael Thayer <michael.thayer@oracle.com, - * Hans de Goede <hdegoede@redhat.com> - */ - -#include <linux/vbox_err.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_crtc_helper.h> - -#include "vbox_drv.h" -#include "vboxvideo_guest.h" -#include "vboxvideo_vbe.h" - -static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb); - - if (vbox_fb->obj) - drm_gem_object_put_unlocked(vbox_fb->obj); - - drm_framebuffer_cleanup(fb); - kfree(fb); -} - -void vbox_report_caps(struct vbox_private *vbox) -{ - u32 caps = VBVACAPS_DISABLE_CURSOR_INTEGRATION | - VBVACAPS_IRQ | VBVACAPS_USE_VBVA_ONLY; - - if (vbox->initial_mode_queried) - caps |= VBVACAPS_VIDEO_MODE_HINTS; - - hgsmi_send_caps_info(vbox->guest_pool, caps); -} - -/* Send information about dirty rectangles to VBVA. */ -void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb, - struct drm_clip_rect *rects, - unsigned int num_rects) -{ - struct vbox_private *vbox = fb->dev->dev_private; - struct drm_display_mode *mode; - struct drm_crtc *crtc; - int crtc_x, crtc_y; - unsigned int i; - - mutex_lock(&vbox->hw_mutex); - list_for_each_entry(crtc, &fb->dev->mode_config.crtc_list, head) { - if (crtc->primary->state->fb != fb) - continue; - - mode = &crtc->state->mode; - crtc_x = crtc->primary->state->src_x >> 16; - crtc_y = crtc->primary->state->src_y >> 16; - - for (i = 0; i < num_rects; ++i) { - struct vbva_cmd_hdr cmd_hdr; - unsigned int crtc_id = to_vbox_crtc(crtc)->crtc_id; - - if (rects[i].x1 > crtc_x + mode->hdisplay || - rects[i].y1 > crtc_y + mode->vdisplay || - rects[i].x2 < crtc_x || - rects[i].y2 < crtc_y) - continue; - - cmd_hdr.x = (s16)rects[i].x1; - cmd_hdr.y = (s16)rects[i].y1; - cmd_hdr.w = (u16)rects[i].x2 - rects[i].x1; - cmd_hdr.h = (u16)rects[i].y2 - rects[i].y1; - - if (!vbva_buffer_begin_update(&vbox->vbva_info[crtc_id], - vbox->guest_pool)) - continue; - - vbva_write(&vbox->vbva_info[crtc_id], vbox->guest_pool, - &cmd_hdr, sizeof(cmd_hdr)); - vbva_buffer_end_update(&vbox->vbva_info[crtc_id]); - } - } - mutex_unlock(&vbox->hw_mutex); -} - -static int vbox_user_framebuffer_dirty(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int flags, unsigned int color, - struct drm_clip_rect *rects, - unsigned int num_rects) -{ - vbox_framebuffer_dirty_rectangles(fb, rects, num_rects); - - return 0; -} - -static const struct drm_framebuffer_funcs vbox_fb_funcs = { - .destroy = vbox_user_framebuffer_destroy, - .dirty = vbox_user_framebuffer_dirty, -}; - -int vbox_framebuffer_init(struct vbox_private *vbox, - struct vbox_framebuffer *vbox_fb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) -{ - int ret; - - drm_helper_mode_fill_fb_struct(&vbox->ddev, &vbox_fb->base, mode_cmd); - vbox_fb->obj = obj; - ret = drm_framebuffer_init(&vbox->ddev, &vbox_fb->base, &vbox_fb_funcs); - if (ret) { - DRM_ERROR("framebuffer init failed %d\n", ret); - return ret; - } - - return 0; -} - -static int vbox_accel_init(struct vbox_private *vbox) -{ - struct vbva_buffer *vbva; - unsigned int i; - - vbox->vbva_info = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, - sizeof(*vbox->vbva_info), GFP_KERNEL); - if (!vbox->vbva_info) - return -ENOMEM; - - /* Take a command buffer for each screen from the end of usable VRAM. */ - vbox->available_vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE; - - vbox->vbva_buffers = pci_iomap_range(vbox->ddev.pdev, 0, - vbox->available_vram_size, - vbox->num_crtcs * - VBVA_MIN_BUFFER_SIZE); - if (!vbox->vbva_buffers) - return -ENOMEM; - - for (i = 0; i < vbox->num_crtcs; ++i) { - vbva_setup_buffer_context(&vbox->vbva_info[i], - vbox->available_vram_size + - i * VBVA_MIN_BUFFER_SIZE, - VBVA_MIN_BUFFER_SIZE); - vbva = (void __force *)vbox->vbva_buffers + - i * VBVA_MIN_BUFFER_SIZE; - if (!vbva_enable(&vbox->vbva_info[i], - vbox->guest_pool, vbva, i)) { - /* very old host or driver error. */ - DRM_ERROR("vboxvideo: vbva_enable failed\n"); - } - } - - return 0; -} - -static void vbox_accel_fini(struct vbox_private *vbox) -{ - unsigned int i; - - for (i = 0; i < vbox->num_crtcs; ++i) - vbva_disable(&vbox->vbva_info[i], vbox->guest_pool, i); - - pci_iounmap(vbox->ddev.pdev, vbox->vbva_buffers); -} - -/* Do we support the 4.3 plus mode hint reporting interface? */ -static bool have_hgsmi_mode_hints(struct vbox_private *vbox) -{ - u32 have_hints, have_cursor; - int ret; - - ret = hgsmi_query_conf(vbox->guest_pool, - VBOX_VBVA_CONF32_MODE_HINT_REPORTING, - &have_hints); - if (ret) - return false; - - ret = hgsmi_query_conf(vbox->guest_pool, - VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING, - &have_cursor); - if (ret) - return false; - - return have_hints == VINF_SUCCESS && have_cursor == VINF_SUCCESS; -} - -bool vbox_check_supported(u16 id) -{ - u16 dispi_id; - - vbox_write_ioport(VBE_DISPI_INDEX_ID, id); - dispi_id = inw(VBE_DISPI_IOPORT_DATA); - - return dispi_id == id; -} - -int vbox_hw_init(struct vbox_private *vbox) -{ - int ret = -ENOMEM; - - vbox->full_vram_size = inl(VBE_DISPI_IOPORT_DATA); - vbox->any_pitch = vbox_check_supported(VBE_DISPI_ID_ANYX); - - DRM_INFO("VRAM %08x\n", vbox->full_vram_size); - - /* Map guest-heap at end of vram */ - vbox->guest_heap = - pci_iomap_range(vbox->ddev.pdev, 0, GUEST_HEAP_OFFSET(vbox), - GUEST_HEAP_SIZE); - if (!vbox->guest_heap) - return -ENOMEM; - - /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ - vbox->guest_pool = gen_pool_create(4, -1); - if (!vbox->guest_pool) - goto err_unmap_guest_heap; - - ret = gen_pool_add_virt(vbox->guest_pool, - (unsigned long)vbox->guest_heap, - GUEST_HEAP_OFFSET(vbox), - GUEST_HEAP_USABLE_SIZE, -1); - if (ret) - goto err_destroy_guest_pool; - - ret = hgsmi_test_query_conf(vbox->guest_pool); - if (ret) { - DRM_ERROR("vboxvideo: hgsmi_test_query_conf failed\n"); - goto err_destroy_guest_pool; - } - - /* Reduce available VRAM size to reflect the guest heap. */ - vbox->available_vram_size = GUEST_HEAP_OFFSET(vbox); - /* Linux drm represents monitors as a 32-bit array. */ - hgsmi_query_conf(vbox->guest_pool, VBOX_VBVA_CONF32_MONITOR_COUNT, - &vbox->num_crtcs); - vbox->num_crtcs = clamp_t(u32, vbox->num_crtcs, 1, VBOX_MAX_SCREENS); - - if (!have_hgsmi_mode_hints(vbox)) { - ret = -ENOTSUPP; - goto err_destroy_guest_pool; - } - - vbox->last_mode_hints = devm_kcalloc(vbox->ddev.dev, vbox->num_crtcs, - sizeof(struct vbva_modehint), - GFP_KERNEL); - if (!vbox->last_mode_hints) { - ret = -ENOMEM; - goto err_destroy_guest_pool; - } - - ret = vbox_accel_init(vbox); - if (ret) - goto err_destroy_guest_pool; - - return 0; - -err_destroy_guest_pool: - gen_pool_destroy(vbox->guest_pool); -err_unmap_guest_heap: - pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); - return ret; -} - -void vbox_hw_fini(struct vbox_private *vbox) -{ - vbox_accel_fini(vbox); - gen_pool_destroy(vbox->guest_pool); - pci_iounmap(vbox->ddev.pdev, vbox->guest_heap); -} - -int vbox_gem_create(struct vbox_private *vbox, - u32 size, bool iskernel, struct drm_gem_object **obj) -{ - struct vbox_bo *vboxbo; - int ret; - - *obj = NULL; - - size = roundup(size, PAGE_SIZE); - if (size == 0) - return -EINVAL; - - ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR("failed to allocate GEM object\n"); - return ret; - } - - *obj = &vboxbo->gem; - - return 0; -} - -int vbox_dumb_create(struct drm_file *file, - struct drm_device *dev, struct drm_mode_create_dumb *args) -{ - struct vbox_private *vbox = - container_of(dev, struct vbox_private, ddev); - struct drm_gem_object *gobj; - u32 handle; - int ret; - - args->pitch = args->width * ((args->bpp + 7) / 8); - args->size = args->pitch * args->height; - - ret = vbox_gem_create(vbox, args->size, false, &gobj); - if (ret) - return ret; - - ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_put_unlocked(gobj); - if (ret) - return ret; - - args->handle = handle; - - return 0; -} - -void vbox_gem_free_object(struct drm_gem_object *obj) -{ - struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj); - - ttm_bo_put(&vbox_bo->bo); -} - -static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo) -{ - return drm_vma_node_offset_addr(&bo->bo.vma_node); -} - -int -vbox_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - u32 handle, u64 *offset) -{ - struct drm_gem_object *obj; - int ret; - struct vbox_bo *bo; - - mutex_lock(&dev->struct_mutex); - obj = drm_gem_object_lookup(file, handle); - if (!obj) { - ret = -ENOENT; - goto out_unlock; - } - - bo = gem_to_vbox_bo(obj); - *offset = vbox_bo_mmap_offset(bo); - - drm_gem_object_put(obj); - ret = 0; - -out_unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c deleted file mode 100644 index 213551394495..000000000000 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ /dev/null @@ -1,957 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2013-2017 Oracle Corporation - * This file is based on ast_mode.c - * Copyright 2012 Red Hat Inc. - * Parts based on xf86-video-ast - * Copyright (c) 2005 ASPEED Technology Inc. - * Authors: Dave Airlie <airlied@redhat.com> - * Michael Thayer <michael.thayer@oracle.com, - * Hans de Goede <hdegoede@redhat.com> - */ -#include <linux/export.h> - -#include <drm/drm_atomic.h> -#include <drm/drm_atomic_helper.h> -#include <drm/drm_fourcc.h> -#include <drm/drm_plane_helper.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_vblank.h> - -#include "hgsmi_channels.h" -#include "vbox_drv.h" -#include "vboxvideo.h" - -/* - * Set a graphics mode. Poke any required values into registers, do an HGSMI - * mode set and tell the host we support advanced graphics functions. - */ -static void vbox_do_modeset(struct drm_crtc *crtc) -{ - struct drm_framebuffer *fb = crtc->primary->state->fb; - struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); - struct vbox_private *vbox; - int width, height, bpp, pitch; - u16 flags; - s32 x_offset, y_offset; - - vbox = crtc->dev->dev_private; - width = vbox_crtc->width ? vbox_crtc->width : 640; - height = vbox_crtc->height ? vbox_crtc->height : 480; - bpp = fb ? fb->format->cpp[0] * 8 : 32; - pitch = fb ? fb->pitches[0] : width * bpp / 8; - x_offset = vbox->single_framebuffer ? vbox_crtc->x : vbox_crtc->x_hint; - y_offset = vbox->single_framebuffer ? vbox_crtc->y : vbox_crtc->y_hint; - - /* - * This is the old way of setting graphics modes. It assumed one screen - * and a frame-buffer at the start of video RAM. On older versions of - * VirtualBox, certain parts of the code still assume that the first - * screen is programmed this way, so try to fake it. - */ - if (vbox_crtc->crtc_id == 0 && fb && - vbox_crtc->fb_offset / pitch < 0xffff - crtc->y && - vbox_crtc->fb_offset % (bpp / 8) == 0) { - vbox_write_ioport(VBE_DISPI_INDEX_XRES, width); - vbox_write_ioport(VBE_DISPI_INDEX_YRES, height); - vbox_write_ioport(VBE_DISPI_INDEX_VIRT_WIDTH, pitch * 8 / bpp); - vbox_write_ioport(VBE_DISPI_INDEX_BPP, bpp); - vbox_write_ioport(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED); - vbox_write_ioport( - VBE_DISPI_INDEX_X_OFFSET, - vbox_crtc->fb_offset % pitch / bpp * 8 + vbox_crtc->x); - vbox_write_ioport(VBE_DISPI_INDEX_Y_OFFSET, - vbox_crtc->fb_offset / pitch + vbox_crtc->y); - } - - flags = VBVA_SCREEN_F_ACTIVE; - flags |= (fb && crtc->state->enable) ? 0 : VBVA_SCREEN_F_BLANK; - flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0; - hgsmi_process_display_info(vbox->guest_pool, vbox_crtc->crtc_id, - x_offset, y_offset, - vbox_crtc->x * bpp / 8 + - vbox_crtc->y * pitch, - pitch, width, height, bpp, flags); -} - -static int vbox_set_view(struct drm_crtc *crtc) -{ - struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); - struct vbox_private *vbox = crtc->dev->dev_private; - struct vbva_infoview *p; - - /* - * Tell the host about the view. This design originally targeted the - * Windows XP driver architecture and assumed that each screen would - * have a dedicated frame buffer with the command buffer following it, - * the whole being a "view". The host works out which screen a command - * buffer belongs to by checking whether it is in the first view, then - * whether it is in the second and so on. The first match wins. We - * cheat around this by making the first view be the managed memory - * plus the first command buffer, the second the same plus the second - * buffer and so on. - */ - p = hgsmi_buffer_alloc(vbox->guest_pool, sizeof(*p), - HGSMI_CH_VBVA, VBVA_INFO_VIEW); - if (!p) - return -ENOMEM; - - p->view_index = vbox_crtc->crtc_id; - p->view_offset = vbox_crtc->fb_offset; - p->view_size = vbox->available_vram_size - vbox_crtc->fb_offset + - vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE; - p->max_screen_size = vbox->available_vram_size - vbox_crtc->fb_offset; - - hgsmi_buffer_submit(vbox->guest_pool, p); - hgsmi_buffer_free(vbox->guest_pool, p); - - return 0; -} - -/* - * Try to map the layout of virtual screens to the range of the input device. - * Return true if we need to re-set the crtc modes due to screen offset - * changes. - */ -static bool vbox_set_up_input_mapping(struct vbox_private *vbox) -{ - struct drm_crtc *crtci; - struct drm_connector *connectori; - struct drm_framebuffer *fb, *fb1 = NULL; - bool single_framebuffer = true; - bool old_single_framebuffer = vbox->single_framebuffer; - u16 width = 0, height = 0; - - /* - * Are we using an X.Org-style single large frame-buffer for all crtcs? - * If so then screen layout can be deduced from the crtc offsets. - * Same fall-back if this is the fbdev frame-buffer. - */ - list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { - fb = crtci->primary->state->fb; - if (!fb) - continue; - - if (!fb1) { - fb1 = fb; - if (to_vbox_framebuffer(fb1) == &vbox->afb) - break; - } else if (fb != fb1) { - single_framebuffer = false; - } - } - if (!fb1) - return false; - - if (single_framebuffer) { - vbox->single_framebuffer = true; - vbox->input_mapping_width = fb1->width; - vbox->input_mapping_height = fb1->height; - return old_single_framebuffer != vbox->single_framebuffer; - } - /* Otherwise calculate the total span of all screens. */ - list_for_each_entry(connectori, &vbox->ddev.mode_config.connector_list, - head) { - struct vbox_connector *vbox_connector = - to_vbox_connector(connectori); - struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc; - - width = max_t(u16, width, vbox_crtc->x_hint + - vbox_connector->mode_hint.width); - height = max_t(u16, height, vbox_crtc->y_hint + - vbox_connector->mode_hint.height); - } - - vbox->single_framebuffer = false; - vbox->input_mapping_width = width; - vbox->input_mapping_height = height; - - return old_single_framebuffer != vbox->single_framebuffer; -} - -static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y) -{ - struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); - struct vbox_private *vbox = crtc->dev->dev_private; - struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); - bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state); - - mutex_lock(&vbox->hw_mutex); - - if (crtc->state->enable) { - vbox_crtc->width = crtc->state->mode.hdisplay; - vbox_crtc->height = crtc->state->mode.vdisplay; - } - - vbox_crtc->x = x; - vbox_crtc->y = y; - vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo); - - /* vbox_do_modeset() checks vbox->single_framebuffer so update it now */ - if (needs_modeset && vbox_set_up_input_mapping(vbox)) { - struct drm_crtc *crtci; - - list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, - head) { - if (crtci == crtc) - continue; - vbox_do_modeset(crtci); - } - } - - vbox_set_view(crtc); - vbox_do_modeset(crtc); - - if (needs_modeset) - hgsmi_update_input_mapping(vbox->guest_pool, 0, 0, - vbox->input_mapping_width, - vbox->input_mapping_height); - - mutex_unlock(&vbox->hw_mutex); -} - -static void vbox_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) -{ -} - -static void vbox_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) -{ -} - -static void vbox_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) -{ - struct drm_pending_vblank_event *event; - unsigned long flags; - - if (crtc->state && crtc->state->event) { - event = crtc->state->event; - crtc->state->event = NULL; - - spin_lock_irqsave(&crtc->dev->event_lock, flags); - drm_crtc_send_vblank_event(crtc, event); - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - } -} - -static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = { - .atomic_enable = vbox_crtc_atomic_enable, - .atomic_disable = vbox_crtc_atomic_disable, - .atomic_flush = vbox_crtc_atomic_flush, -}; - -static void vbox_crtc_destroy(struct drm_crtc *crtc) -{ - drm_crtc_cleanup(crtc); - kfree(crtc); -} - -static const struct drm_crtc_funcs vbox_crtc_funcs = { - .set_config = drm_atomic_helper_set_config, - .page_flip = drm_atomic_helper_page_flip, - /* .gamma_set = vbox_crtc_gamma_set, */ - .destroy = vbox_crtc_destroy, - .reset = drm_atomic_helper_crtc_reset, - .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, -}; - -static int vbox_primary_atomic_check(struct drm_plane *plane, - struct drm_plane_state *new_state) -{ - struct drm_crtc_state *crtc_state = NULL; - - if (new_state->crtc) { - crtc_state = drm_atomic_get_existing_crtc_state( - new_state->state, new_state->crtc); - if (WARN_ON(!crtc_state)) - return -EINVAL; - } - - return drm_atomic_helper_check_plane_state(new_state, crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, true); -} - -static void vbox_primary_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct drm_crtc *crtc = plane->state->crtc; - struct drm_framebuffer *fb = plane->state->fb; - - vbox_crtc_set_base_and_mode(crtc, fb, - plane->state->src_x >> 16, - plane->state->src_y >> 16); -} - -static void vbox_primary_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct drm_crtc *crtc = old_state->crtc; - - /* vbox_do_modeset checks plane->state->fb and will disable if NULL */ - vbox_crtc_set_base_and_mode(crtc, old_state->fb, - old_state->src_x >> 16, - old_state->src_y >> 16); -} - -static int vbox_primary_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *new_state) -{ - struct vbox_bo *bo; - int ret; - - if (!new_state->fb) - return 0; - - bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj); - ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM); - if (ret) - DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret); - - return ret; -} - -static void vbox_primary_cleanup_fb(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct vbox_bo *bo; - - if (!old_state->fb) - return; - - bo = gem_to_vbox_bo(to_vbox_framebuffer(old_state->fb)->obj); - vbox_bo_unpin(bo); -} - -static int vbox_cursor_atomic_check(struct drm_plane *plane, - struct drm_plane_state *new_state) -{ - struct drm_crtc_state *crtc_state = NULL; - u32 width = new_state->crtc_w; - u32 height = new_state->crtc_h; - int ret; - - if (new_state->crtc) { - crtc_state = drm_atomic_get_existing_crtc_state( - new_state->state, new_state->crtc); - if (WARN_ON(!crtc_state)) - return -EINVAL; - } - - ret = drm_atomic_helper_check_plane_state(new_state, crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - true, true); - if (ret) - return ret; - - if (!new_state->fb) - return 0; - - if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT || - width == 0 || height == 0) - return -EINVAL; - - return 0; -} - -/* - * Copy the ARGB image and generate the mask, which is needed in case the host - * does not support ARGB cursors. The mask is a 1BPP bitmap with the bit set - * if the corresponding alpha value in the ARGB image is greater than 0xF0. - */ -static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height, - size_t mask_size) -{ - size_t line_size = (width + 7) / 8; - u32 i, j; - - memcpy(dst + mask_size, src, width * height * 4); - for (i = 0; i < height; ++i) - for (j = 0; j < width; ++j) - if (((u32 *)src)[i * width + j] > 0xf0000000) - dst[i * line_size + j / 8] |= (0x80 >> (j % 8)); -} - -static void vbox_cursor_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct vbox_private *vbox = - container_of(plane->dev, struct vbox_private, ddev); - struct vbox_crtc *vbox_crtc = to_vbox_crtc(plane->state->crtc); - struct drm_framebuffer *fb = plane->state->fb; - struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj); - u32 width = plane->state->crtc_w; - u32 height = plane->state->crtc_h; - size_t data_size, mask_size; - u32 flags; - u8 *src; - - /* - * VirtualBox uses the host windowing system to draw the cursor so - * moves are a no-op, we only need to upload new cursor sprites. - */ - if (fb == old_state->fb) - return; - - mutex_lock(&vbox->hw_mutex); - - vbox_crtc->cursor_enabled = true; - - /* pinning is done in prepare/cleanup framebuffer */ - src = vbox_bo_kmap(bo); - if (IS_ERR(src)) { - mutex_unlock(&vbox->hw_mutex); - DRM_WARN("Could not kmap cursor bo, skipping update\n"); - return; - } - - /* - * The mask must be calculated based on the alpha - * channel, one bit per ARGB word, and must be 32-bit - * padded. - */ - mask_size = ((width + 7) / 8 * height + 3) & ~3; - data_size = width * height * 4 + mask_size; - - copy_cursor_image(src, vbox->cursor_data, width, height, mask_size); - vbox_bo_kunmap(bo); - - flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE | - VBOX_MOUSE_POINTER_ALPHA; - hgsmi_update_pointer_shape(vbox->guest_pool, flags, - min_t(u32, max(fb->hot_x, 0), width), - min_t(u32, max(fb->hot_y, 0), height), - width, height, vbox->cursor_data, data_size); - - mutex_unlock(&vbox->hw_mutex); -} - -static void vbox_cursor_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct vbox_private *vbox = - container_of(plane->dev, struct vbox_private, ddev); - struct vbox_crtc *vbox_crtc = to_vbox_crtc(old_state->crtc); - bool cursor_enabled = false; - struct drm_crtc *crtci; - - mutex_lock(&vbox->hw_mutex); - - vbox_crtc->cursor_enabled = false; - - list_for_each_entry(crtci, &vbox->ddev.mode_config.crtc_list, head) { - if (to_vbox_crtc(crtci)->cursor_enabled) - cursor_enabled = true; - } - - if (!cursor_enabled) - hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0, - 0, 0, NULL, 0); - - mutex_unlock(&vbox->hw_mutex); -} - -static int vbox_cursor_prepare_fb(struct drm_plane *plane, - struct drm_plane_state *new_state) -{ - struct vbox_bo *bo; - - if (!new_state->fb) - return 0; - - bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj); - return vbox_bo_pin(bo, TTM_PL_FLAG_SYSTEM); -} - -static void vbox_cursor_cleanup_fb(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct vbox_bo *bo; - - if (!plane->state->fb) - return; - - bo = gem_to_vbox_bo(to_vbox_framebuffer(plane->state->fb)->obj); - vbox_bo_unpin(bo); -} - -static const u32 vbox_cursor_plane_formats[] = { - DRM_FORMAT_ARGB8888, -}; - -static const struct drm_plane_helper_funcs vbox_cursor_helper_funcs = { - .atomic_check = vbox_cursor_atomic_check, - .atomic_update = vbox_cursor_atomic_update, - .atomic_disable = vbox_cursor_atomic_disable, - .prepare_fb = vbox_cursor_prepare_fb, - .cleanup_fb = vbox_cursor_cleanup_fb, -}; - -static const struct drm_plane_funcs vbox_cursor_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, - .destroy = drm_primary_helper_destroy, - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, -}; - -static const u32 vbox_primary_plane_formats[] = { - DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, -}; - -static const struct drm_plane_helper_funcs vbox_primary_helper_funcs = { - .atomic_check = vbox_primary_atomic_check, - .atomic_update = vbox_primary_atomic_update, - .atomic_disable = vbox_primary_atomic_disable, - .prepare_fb = vbox_primary_prepare_fb, - .cleanup_fb = vbox_primary_cleanup_fb, -}; - -static const struct drm_plane_funcs vbox_primary_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, - .destroy = drm_primary_helper_destroy, - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, -}; - -static struct drm_plane *vbox_create_plane(struct vbox_private *vbox, - unsigned int possible_crtcs, - enum drm_plane_type type) -{ - const struct drm_plane_helper_funcs *helper_funcs = NULL; - const struct drm_plane_funcs *funcs; - struct drm_plane *plane; - const u32 *formats; - int num_formats; - int err; - - if (type == DRM_PLANE_TYPE_PRIMARY) { - funcs = &vbox_primary_plane_funcs; - formats = vbox_primary_plane_formats; - helper_funcs = &vbox_primary_helper_funcs; - num_formats = ARRAY_SIZE(vbox_primary_plane_formats); - } else if (type == DRM_PLANE_TYPE_CURSOR) { - funcs = &vbox_cursor_plane_funcs; - formats = vbox_cursor_plane_formats; - helper_funcs = &vbox_cursor_helper_funcs; - num_formats = ARRAY_SIZE(vbox_cursor_plane_formats); - } else { - return ERR_PTR(-EINVAL); - } - - plane = kzalloc(sizeof(*plane), GFP_KERNEL); - if (!plane) - return ERR_PTR(-ENOMEM); - - err = drm_universal_plane_init(&vbox->ddev, plane, possible_crtcs, - funcs, formats, num_formats, - NULL, type, NULL); - if (err) - goto free_plane; - - drm_plane_helper_add(plane, helper_funcs); - - return plane; - -free_plane: - kfree(plane); - return ERR_PTR(-EINVAL); -} - -static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i) -{ - struct vbox_private *vbox = - container_of(dev, struct vbox_private, ddev); - struct drm_plane *cursor = NULL; - struct vbox_crtc *vbox_crtc; - struct drm_plane *primary; - u32 caps = 0; - int ret; - - ret = hgsmi_query_conf(vbox->guest_pool, - VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps); - if (ret) - return ERR_PTR(ret); - - vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL); - if (!vbox_crtc) - return ERR_PTR(-ENOMEM); - - primary = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_PRIMARY); - if (IS_ERR(primary)) { - ret = PTR_ERR(primary); - goto free_mem; - } - - if ((caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) { - cursor = vbox_create_plane(vbox, 1 << i, DRM_PLANE_TYPE_CURSOR); - if (IS_ERR(cursor)) { - ret = PTR_ERR(cursor); - goto clean_primary; - } - } else { - DRM_WARN("VirtualBox host is too old, no cursor support\n"); - } - - vbox_crtc->crtc_id = i; - - ret = drm_crtc_init_with_planes(dev, &vbox_crtc->base, primary, cursor, - &vbox_crtc_funcs, NULL); - if (ret) - goto clean_cursor; - - drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256); - drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs); - - return vbox_crtc; - -clean_cursor: - if (cursor) { - drm_plane_cleanup(cursor); - kfree(cursor); - } -clean_primary: - drm_plane_cleanup(primary); - kfree(primary); -free_mem: - kfree(vbox_crtc); - return ERR_PTR(ret); -} - -static void vbox_encoder_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); - kfree(encoder); -} - -static const struct drm_encoder_funcs vbox_enc_funcs = { - .destroy = vbox_encoder_destroy, -}; - -static struct drm_encoder *vbox_encoder_init(struct drm_device *dev, - unsigned int i) -{ - struct vbox_encoder *vbox_encoder; - - vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL); - if (!vbox_encoder) - return NULL; - - drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs, - DRM_MODE_ENCODER_DAC, NULL); - - vbox_encoder->base.possible_crtcs = 1 << i; - return &vbox_encoder->base; -} - -/* - * Generate EDID data with a mode-unique serial number for the virtual - * monitor to try to persuade Unity that different modes correspond to - * different monitors and it should not try to force the same resolution on - * them. - */ -static void vbox_set_edid(struct drm_connector *connector, int width, - int height) -{ - enum { EDID_SIZE = 128 }; - unsigned char edid[EDID_SIZE] = { - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */ - 0x58, 0x58, /* manufacturer (VBX) */ - 0x00, 0x00, /* product code */ - 0x00, 0x00, 0x00, 0x00, /* serial number goes here */ - 0x01, /* week of manufacture */ - 0x00, /* year of manufacture */ - 0x01, 0x03, /* EDID version */ - 0x80, /* capabilities - digital */ - 0x00, /* horiz. res in cm, zero for projectors */ - 0x00, /* vert. res in cm */ - 0x78, /* display gamma (120 == 2.2). */ - 0xEE, /* features (standby, suspend, off, RGB, std */ - /* colour space, preferred timing mode) */ - 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54, - /* chromaticity for standard colour space. */ - 0x00, 0x00, 0x00, /* no default timings */ - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, /* no standard timings */ - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02, - 0x02, 0x02, - /* descriptor block 1 goes below */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* descriptor block 2, monitor ranges */ - 0x00, 0x00, 0x00, 0xFD, 0x00, - 0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, - 0x20, 0x20, - /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */ - 0x20, - /* descriptor block 3, monitor name */ - 0x00, 0x00, 0x00, 0xFC, 0x00, - 'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', - '\n', - /* descriptor block 4: dummy data */ - 0x00, 0x00, 0x00, 0x10, 0x00, - 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, - 0x00, /* number of extensions */ - 0x00 /* checksum goes here */ - }; - int clock = (width + 6) * (height + 6) * 60 / 10000; - unsigned int i, sum = 0; - - edid[12] = width & 0xff; - edid[13] = width >> 8; - edid[14] = height & 0xff; - edid[15] = height >> 8; - edid[54] = clock & 0xff; - edid[55] = clock >> 8; - edid[56] = width & 0xff; - edid[58] = (width >> 4) & 0xf0; - edid[59] = height & 0xff; - edid[61] = (height >> 4) & 0xf0; - for (i = 0; i < EDID_SIZE - 1; ++i) - sum += edid[i]; - edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF; - drm_connector_update_edid_property(connector, (struct edid *)edid); -} - -static int vbox_get_modes(struct drm_connector *connector) -{ - struct vbox_connector *vbox_connector = NULL; - struct drm_display_mode *mode = NULL; - struct vbox_private *vbox = NULL; - unsigned int num_modes = 0; - int preferred_width, preferred_height; - - vbox_connector = to_vbox_connector(connector); - vbox = connector->dev->dev_private; - /* - * Heuristic: we do not want to tell the host that we support dynamic - * resizing unless we feel confident that the user space client using - * the video driver can handle hot-plug events. So the first time modes - * are queried after a "master" switch we tell the host that we do not, - * and immediately after we send the client a hot-plug notification as - * a test to see if they will respond and query again. - * That is also the reason why capabilities are reported to the host at - * this place in the code rather than elsewhere. - * We need to report the flags location before reporting the IRQ - * capability. - */ - hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) + - HOST_FLAGS_OFFSET); - if (vbox_connector->vbox_crtc->crtc_id == 0) - vbox_report_caps(vbox); - if (!vbox->initial_mode_queried) { - if (vbox_connector->vbox_crtc->crtc_id == 0) { - vbox->initial_mode_queried = true; - vbox_report_hotplug(vbox); - } - return drm_add_modes_noedid(connector, 800, 600); - } - num_modes = drm_add_modes_noedid(connector, 2560, 1600); - preferred_width = vbox_connector->mode_hint.width ? - vbox_connector->mode_hint.width : 1024; - preferred_height = vbox_connector->mode_hint.height ? - vbox_connector->mode_hint.height : 768; - mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height, - 60, false, false, false); - if (mode) { - mode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, mode); - ++num_modes; - } - vbox_set_edid(connector, preferred_width, preferred_height); - - if (vbox_connector->vbox_crtc->x_hint != -1) - drm_object_property_set_value(&connector->base, - vbox->ddev.mode_config.suggested_x_property, - vbox_connector->vbox_crtc->x_hint); - else - drm_object_property_set_value(&connector->base, - vbox->ddev.mode_config.suggested_x_property, 0); - - if (vbox_connector->vbox_crtc->y_hint != -1) - drm_object_property_set_value(&connector->base, - vbox->ddev.mode_config.suggested_y_property, - vbox_connector->vbox_crtc->y_hint); - else - drm_object_property_set_value(&connector->base, - vbox->ddev.mode_config.suggested_y_property, 0); - - return num_modes; -} - -static void vbox_connector_destroy(struct drm_connector *connector) -{ - drm_connector_unregister(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static enum drm_connector_status -vbox_connector_detect(struct drm_connector *connector, bool force) -{ - struct vbox_connector *vbox_connector; - - vbox_connector = to_vbox_connector(connector); - - return vbox_connector->mode_hint.disconnected ? - connector_status_disconnected : connector_status_connected; -} - -static int vbox_fill_modes(struct drm_connector *connector, u32 max_x, - u32 max_y) -{ - struct vbox_connector *vbox_connector; - struct drm_device *dev; - struct drm_display_mode *mode, *iterator; - - vbox_connector = to_vbox_connector(connector); - dev = vbox_connector->base.dev; - list_for_each_entry_safe(mode, iterator, &connector->modes, head) { - list_del(&mode->head); - drm_mode_destroy(dev, mode); - } - - return drm_helper_probe_single_connector_modes(connector, max_x, max_y); -} - -static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = { - .get_modes = vbox_get_modes, -}; - -static const struct drm_connector_funcs vbox_connector_funcs = { - .detect = vbox_connector_detect, - .fill_modes = vbox_fill_modes, - .destroy = vbox_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int vbox_connector_init(struct drm_device *dev, - struct vbox_crtc *vbox_crtc, - struct drm_encoder *encoder) -{ - struct vbox_connector *vbox_connector; - struct drm_connector *connector; - - vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL); - if (!vbox_connector) - return -ENOMEM; - - connector = &vbox_connector->base; - vbox_connector->vbox_crtc = vbox_crtc; - - drm_connector_init(dev, connector, &vbox_connector_funcs, - DRM_MODE_CONNECTOR_VGA); - drm_connector_helper_add(connector, &vbox_connector_helper_funcs); - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_mode_create_suggested_offset_properties(dev); - drm_object_attach_property(&connector->base, - dev->mode_config.suggested_x_property, 0); - drm_object_attach_property(&connector->base, - dev->mode_config.suggested_y_property, 0); - - drm_connector_attach_encoder(connector, encoder); - - return 0; -} - -static struct drm_framebuffer *vbox_user_framebuffer_create( - struct drm_device *dev, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct vbox_private *vbox = - container_of(dev, struct vbox_private, ddev); - struct drm_gem_object *obj; - struct vbox_framebuffer *vbox_fb; - int ret = -ENOMEM; - - obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); - if (!obj) - return ERR_PTR(-ENOENT); - - vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL); - if (!vbox_fb) - goto err_unref_obj; - - ret = vbox_framebuffer_init(vbox, vbox_fb, mode_cmd, obj); - if (ret) - goto err_free_vbox_fb; - - return &vbox_fb->base; - -err_free_vbox_fb: - kfree(vbox_fb); -err_unref_obj: - drm_gem_object_put_unlocked(obj); - return ERR_PTR(ret); -} - -static const struct drm_mode_config_funcs vbox_mode_funcs = { - .fb_create = vbox_user_framebuffer_create, - .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, -}; - -int vbox_mode_init(struct vbox_private *vbox) -{ - struct drm_device *dev = &vbox->ddev; - struct drm_encoder *encoder; - struct vbox_crtc *vbox_crtc; - unsigned int i; - int ret; - - drm_mode_config_init(dev); - - dev->mode_config.funcs = (void *)&vbox_mode_funcs; - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - dev->mode_config.preferred_depth = 24; - dev->mode_config.max_width = VBE_DISPI_MAX_XRES; - dev->mode_config.max_height = VBE_DISPI_MAX_YRES; - - for (i = 0; i < vbox->num_crtcs; ++i) { - vbox_crtc = vbox_crtc_init(dev, i); - if (IS_ERR(vbox_crtc)) { - ret = PTR_ERR(vbox_crtc); - goto err_drm_mode_cleanup; - } - encoder = vbox_encoder_init(dev, i); - if (!encoder) { - ret = -ENOMEM; - goto err_drm_mode_cleanup; - } - ret = vbox_connector_init(dev, vbox_crtc, encoder); - if (ret) - goto err_drm_mode_cleanup; - } - - drm_mode_config_reset(dev); - return 0; - -err_drm_mode_cleanup: - drm_mode_config_cleanup(dev); - return ret; -} - -void vbox_mode_fini(struct vbox_private *vbox) -{ - drm_mode_config_cleanup(&vbox->ddev); -} diff --git a/drivers/staging/vboxvideo/vbox_prime.c b/drivers/staging/vboxvideo/vbox_prime.c deleted file mode 100644 index d61985b0c6eb..000000000000 --- a/drivers/staging/vboxvideo/vbox_prime.c +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2017 Oracle Corporation - * Copyright 2017 Canonical - * Authors: Andreas Pokorny - */ - -#include "vbox_drv.h" - -/* - * Based on qxl_prime.c: - * Empty Implementations as there should not be any other driver for a virtual - * device that might share buffers with vboxvideo - */ - -int vbox_gem_prime_pin(struct drm_gem_object *obj) -{ - WARN_ONCE(1, "not implemented"); - return -ENOSYS; -} - -void vbox_gem_prime_unpin(struct drm_gem_object *obj) -{ - WARN_ONCE(1, "not implemented"); -} - -struct sg_table *vbox_gem_prime_get_sg_table(struct drm_gem_object *obj) -{ - WARN_ONCE(1, "not implemented"); - return ERR_PTR(-ENOSYS); -} - -struct drm_gem_object *vbox_gem_prime_import_sg_table( - struct drm_device *dev, struct dma_buf_attachment *attach, - struct sg_table *table) -{ - WARN_ONCE(1, "not implemented"); - return ERR_PTR(-ENOSYS); -} - -void *vbox_gem_prime_vmap(struct drm_gem_object *obj) -{ - WARN_ONCE(1, "not implemented"); - return ERR_PTR(-ENOSYS); -} - -void vbox_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) -{ - WARN_ONCE(1, "not implemented"); -} - -int vbox_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *area) -{ - WARN_ONCE(1, "not implemented"); - return -ENOSYS; -} diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c deleted file mode 100644 index 30f270027acf..000000000000 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ /dev/null @@ -1,394 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright (C) 2013-2017 Oracle Corporation - * This file is based on ast_ttm.c - * Copyright 2012 Red Hat Inc. - * Authors: Dave Airlie <airlied@redhat.com> - * Michael Thayer <michael.thayer@oracle.com> - */ -#include <linux/pci.h> -#include <drm/drm_file.h> -#include <drm/ttm/ttm_page_alloc.h> -#include "vbox_drv.h" - -static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd) -{ - return container_of(bd, struct vbox_private, ttm.bdev); -} - -static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo) -{ - struct vbox_bo *bo; - - bo = container_of(tbo, struct vbox_bo, bo); - - drm_gem_object_release(&bo->gem); - kfree(bo); -} - -static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo) -{ - if (bo->destroy == &vbox_bo_ttm_destroy) - return true; - - return false; -} - -static int -vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type, - struct ttm_mem_type_manager *man) -{ - switch (type) { - case TTM_PL_SYSTEM: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_VRAM: - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type); - return -EINVAL; - } - - return 0; -} - -static void -vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) -{ - struct vbox_bo *vboxbo = vbox_bo(bo); - - if (!vbox_ttm_bo_is_vbox_bo(bo)) - return; - - vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM); - *pl = vboxbo->placement; -} - -static int vbox_bo_verify_access(struct ttm_buffer_object *bo, - struct file *filp) -{ - return 0; -} - -static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct vbox_private *vbox = vbox_bdev(bdev); - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - return 0; - case TTM_PL_VRAM: - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0); - mem->bus.is_iomem = true; - break; - default: - return -EINVAL; - } - return 0; -} - -static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ -} - -static void vbox_ttm_backend_destroy(struct ttm_tt *tt) -{ - ttm_tt_fini(tt); - kfree(tt); -} - -static struct ttm_backend_func vbox_tt_backend_func = { - .destroy = &vbox_ttm_backend_destroy, -}; - -static struct ttm_tt *vbox_ttm_tt_create(struct ttm_buffer_object *bo, - u32 page_flags) -{ - struct ttm_tt *tt; - - tt = kzalloc(sizeof(*tt), GFP_KERNEL); - if (!tt) - return NULL; - - tt->func = &vbox_tt_backend_func; - if (ttm_tt_init(tt, bo, page_flags)) { - kfree(tt); - return NULL; - } - - return tt; -} - -static struct ttm_bo_driver vbox_bo_driver = { - .ttm_tt_create = vbox_ttm_tt_create, - .init_mem_type = vbox_bo_init_mem_type, - .eviction_valuable = ttm_bo_eviction_valuable, - .evict_flags = vbox_bo_evict_flags, - .verify_access = vbox_bo_verify_access, - .io_mem_reserve = &vbox_ttm_io_mem_reserve, - .io_mem_free = &vbox_ttm_io_mem_free, -}; - -int vbox_mm_init(struct vbox_private *vbox) -{ - int ret; - struct drm_device *dev = &vbox->ddev; - struct ttm_bo_device *bdev = &vbox->ttm.bdev; - - ret = ttm_bo_device_init(&vbox->ttm.bdev, - &vbox_bo_driver, - dev->anon_inode->i_mapping, - DRM_FILE_PAGE_OFFSET, true); - if (ret) { - DRM_ERROR("Error initialising bo driver; %d\n", ret); - return ret; - } - - ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, - vbox->available_vram_size >> PAGE_SHIFT); - if (ret) { - DRM_ERROR("Failed ttm VRAM init: %d\n", ret); - goto err_device_release; - } - -#ifdef DRM_MTRR_WC - vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0), - DRM_MTRR_WC); -#else - vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), - pci_resource_len(dev->pdev, 0)); -#endif - return 0; - -err_device_release: - ttm_bo_device_release(&vbox->ttm.bdev); - return ret; -} - -void vbox_mm_fini(struct vbox_private *vbox) -{ -#ifdef DRM_MTRR_WC - drm_mtrr_del(vbox->fb_mtrr, - pci_resource_start(vbox->ddev.pdev, 0), - pci_resource_len(vbox->ddev.pdev, 0), DRM_MTRR_WC); -#else - arch_phys_wc_del(vbox->fb_mtrr); -#endif - ttm_bo_device_release(&vbox->ttm.bdev); -} - -void vbox_ttm_placement(struct vbox_bo *bo, int domain) -{ - unsigned int i; - u32 c = 0; - - bo->placement.placement = bo->placements; - bo->placement.busy_placement = bo->placements; - - if (domain & TTM_PL_FLAG_VRAM) - bo->placements[c++].flags = - TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; - if (domain & TTM_PL_FLAG_SYSTEM) - bo->placements[c++].flags = - TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - if (!c) - bo->placements[c++].flags = - TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - - bo->placement.num_placement = c; - bo->placement.num_busy_placement = c; - - for (i = 0; i < c; ++i) { - bo->placements[i].fpfn = 0; - bo->placements[i].lpfn = 0; - } -} - -int vbox_bo_create(struct vbox_private *vbox, int size, int align, - u32 flags, struct vbox_bo **pvboxbo) -{ - struct vbox_bo *vboxbo; - size_t acc_size; - int ret; - - vboxbo = kzalloc(sizeof(*vboxbo), GFP_KERNEL); - if (!vboxbo) - return -ENOMEM; - - ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size); - if (ret) - goto err_free_vboxbo; - - vboxbo->bo.bdev = &vbox->ttm.bdev; - - vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); - - acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size, - sizeof(struct vbox_bo)); - - ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size, - ttm_bo_type_device, &vboxbo->placement, - align >> PAGE_SHIFT, false, acc_size, - NULL, NULL, vbox_bo_ttm_destroy); - if (ret) - goto err_free_vboxbo; - - *pvboxbo = vboxbo; - - return 0; - -err_free_vboxbo: - kfree(vboxbo); - return ret; -} - -int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (bo->pin_count) { - bo->pin_count++; - return 0; - } - - ret = vbox_bo_reserve(bo, false); - if (ret) - return ret; - - vbox_ttm_placement(bo, pl_flag); - - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret == 0) - bo->pin_count = 1; - - vbox_bo_unreserve(bo); - - return ret; -} - -int vbox_bo_unpin(struct vbox_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - - ret = vbox_bo_reserve(bo, false); - if (ret) { - DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret); - return ret; - } - - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - - vbox_bo_unreserve(bo); - - return ret; -} - -/* - * Move a vbox-owned buffer object to system memory if no one else has it - * pinned. The caller must have pinned it previously, and this call will - * release the caller's pin. - */ -int vbox_bo_push_sysram(struct vbox_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - - if (bo->kmap.virtual) { - ttm_bo_kunmap(&bo->kmap); - bo->kmap.virtual = NULL; - } - - vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM); - - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) { - DRM_ERROR("pushing to VRAM failed\n"); - return ret; - } - - return 0; -} - -int vbox_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv; - struct vbox_private *vbox; - - if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) - return -EINVAL; - - file_priv = filp->private_data; - vbox = file_priv->minor->dev->dev_private; - - return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev); -} - -void *vbox_bo_kmap(struct vbox_bo *bo) -{ - int ret; - - if (bo->kmap.virtual) - return bo->kmap.virtual; - - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) { - DRM_ERROR("Error kmapping bo: %d\n", ret); - return NULL; - } - - return bo->kmap.virtual; -} - -void vbox_bo_kunmap(struct vbox_bo *bo) -{ - if (bo->kmap.virtual) { - ttm_bo_kunmap(&bo->kmap); - bo->kmap.virtual = NULL; - } -} diff --git a/drivers/staging/vboxvideo/vboxvideo.h b/drivers/staging/vboxvideo/vboxvideo.h deleted file mode 100644 index 0592004f71aa..000000000000 --- a/drivers/staging/vboxvideo/vboxvideo.h +++ /dev/null @@ -1,442 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright (C) 2006-2016 Oracle Corporation */ - -#ifndef __VBOXVIDEO_H__ -#define __VBOXVIDEO_H__ - -#define VBOX_VIDEO_MAX_SCREENS 64 - -/* - * The last 4096 bytes of the guest VRAM contains the generic info for all - * DualView chunks: sizes and offsets of chunks. This is filled by miniport. - * - * Last 4096 bytes of each chunk contain chunk specific data: framebuffer info, - * etc. This is used exclusively by the corresponding instance of a display - * driver. - * - * The VRAM layout: - * Last 4096 bytes - Adapter information area. - * 4096 bytes aligned miniport heap (value specified in the config rouded up). - * Slack - what left after dividing the VRAM. - * 4096 bytes aligned framebuffers: - * last 4096 bytes of each framebuffer is the display information area. - * - * The Virtual Graphics Adapter information in the guest VRAM is stored by the - * guest video driver using structures prepended by VBOXVIDEOINFOHDR. - * - * When the guest driver writes dword 0 to the VBE_DISPI_INDEX_VBOX_VIDEO - * the host starts to process the info. The first element at the start of - * the 4096 bytes region should be normally be a LINK that points to - * actual information chain. That way the guest driver can have some - * fixed layout of the information memory block and just rewrite - * the link to point to relevant memory chain. - * - * The processing stops at the END element. - * - * The host can access the memory only when the port IO is processed. - * All data that will be needed later must be copied from these 4096 bytes. - * But other VRAM can be used by host until the mode is disabled. - * - * The guest driver writes dword 0xffffffff to the VBE_DISPI_INDEX_VBOX_VIDEO - * to disable the mode. - * - * VBE_DISPI_INDEX_VBOX_VIDEO is used to read the configuration information - * from the host and issue commands to the host. - * - * The guest writes the VBE_DISPI_INDEX_VBOX_VIDEO index register, the the - * following operations with the VBE data register can be performed: - * - * Operation Result - * write 16 bit value NOP - * read 16 bit value count of monitors - * write 32 bit value set the vbox cmd value and the cmd processed by the host - * read 32 bit value result of the last vbox command is returned - */ - -struct vbva_cmd_hdr { - s16 x; - s16 y; - u16 w; - u16 h; -} __packed; - -/* - * The VBVA ring buffer is suitable for transferring large (< 2GB) amount of - * data. For example big bitmaps which do not fit to the buffer. - * - * Guest starts writing to the buffer by initializing a record entry in the - * records queue. VBVA_F_RECORD_PARTIAL indicates that the record is being - * written. As data is written to the ring buffer, the guest increases - * free_offset. - * - * The host reads the records on flushes and processes all completed records. - * When host encounters situation when only a partial record presents and - * len_and_flags & ~VBVA_F_RECORD_PARTIAL >= VBVA_RING_BUFFER_SIZE - - * VBVA_RING_BUFFER_THRESHOLD, the host fetched all record data and updates - * data_offset. After that on each flush the host continues fetching the data - * until the record is completed. - */ - -#define VBVA_RING_BUFFER_SIZE (4194304 - 1024) -#define VBVA_RING_BUFFER_THRESHOLD (4096) - -#define VBVA_MAX_RECORDS (64) - -#define VBVA_F_MODE_ENABLED 0x00000001u -#define VBVA_F_MODE_VRDP 0x00000002u -#define VBVA_F_MODE_VRDP_RESET 0x00000004u -#define VBVA_F_MODE_VRDP_ORDER_MASK 0x00000008u - -#define VBVA_F_STATE_PROCESSING 0x00010000u - -#define VBVA_F_RECORD_PARTIAL 0x80000000u - -struct vbva_record { - u32 len_and_flags; -} __packed; - -/* - * The minimum HGSMI heap size is PAGE_SIZE (4096 bytes) and is a restriction of - * the runtime heapsimple API. Use minimum 2 pages here, because the info area - * also may contain other data (for example hgsmi_host_flags structure). - */ -#define VBVA_ADAPTER_INFORMATION_SIZE 65536 -#define VBVA_MIN_BUFFER_SIZE 65536 - -/* The value for port IO to let the adapter to interpret the adapter memory. */ -#define VBOX_VIDEO_DISABLE_ADAPTER_MEMORY 0xFFFFFFFF - -/* The value for port IO to let the adapter to interpret the adapter memory. */ -#define VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY 0x00000000 - -/* - * The value for port IO to let the adapter to interpret the display memory. - * The display number is encoded in low 16 bits. - */ -#define VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE 0x00010000 - -struct vbva_host_flags { - u32 host_events; - u32 supported_orders; -} __packed; - -struct vbva_buffer { - struct vbva_host_flags host_flags; - - /* The offset where the data start in the buffer. */ - u32 data_offset; - /* The offset where next data must be placed in the buffer. */ - u32 free_offset; - - /* The queue of record descriptions. */ - struct vbva_record records[VBVA_MAX_RECORDS]; - u32 record_first_index; - u32 record_free_index; - - /* Space to leave free when large partial records are transferred. */ - u32 partial_write_tresh; - - u32 data_len; - /* variable size for the rest of the vbva_buffer area in VRAM. */ - u8 data[0]; -} __packed; - -#define VBVA_MAX_RECORD_SIZE (128 * 1024 * 1024) - -/* guest->host commands */ -#define VBVA_QUERY_CONF32 1 -#define VBVA_SET_CONF32 2 -#define VBVA_INFO_VIEW 3 -#define VBVA_INFO_HEAP 4 -#define VBVA_FLUSH 5 -#define VBVA_INFO_SCREEN 6 -#define VBVA_ENABLE 7 -#define VBVA_MOUSE_POINTER_SHAPE 8 -/* informs host about HGSMI caps. see vbva_caps below */ -#define VBVA_INFO_CAPS 12 -/* configures scanline, see VBVASCANLINECFG below */ -#define VBVA_SCANLINE_CFG 13 -/* requests scanline info, see VBVASCANLINEINFO below */ -#define VBVA_SCANLINE_INFO 14 -/* inform host about VBVA Command submission */ -#define VBVA_CMDVBVA_SUBMIT 16 -/* inform host about VBVA Command submission */ -#define VBVA_CMDVBVA_FLUSH 17 -/* G->H DMA command */ -#define VBVA_CMDVBVA_CTL 18 -/* Query most recent mode hints sent */ -#define VBVA_QUERY_MODE_HINTS 19 -/* - * Report the guest virtual desktop position and size for mapping host and - * guest pointer positions. - */ -#define VBVA_REPORT_INPUT_MAPPING 20 -/* Report the guest cursor position and query the host position. */ -#define VBVA_CURSOR_POSITION 21 - -/* host->guest commands */ -#define VBVAHG_EVENT 1 -#define VBVAHG_DISPLAY_CUSTOM 2 - -/* vbva_conf32::index */ -#define VBOX_VBVA_CONF32_MONITOR_COUNT 0 -#define VBOX_VBVA_CONF32_HOST_HEAP_SIZE 1 -/* - * Returns VINF_SUCCESS if the host can report mode hints via VBVA. - * Set value to VERR_NOT_SUPPORTED before calling. - */ -#define VBOX_VBVA_CONF32_MODE_HINT_REPORTING 2 -/* - * Returns VINF_SUCCESS if the host can report guest cursor enabled status via - * VBVA. Set value to VERR_NOT_SUPPORTED before calling. - */ -#define VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING 3 -/* - * Returns the currently available host cursor capabilities. Available if - * VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING returns success. - */ -#define VBOX_VBVA_CONF32_CURSOR_CAPABILITIES 4 -/* Returns the supported flags in vbva_infoscreen.flags. */ -#define VBOX_VBVA_CONF32_SCREEN_FLAGS 5 -/* Returns the max size of VBVA record. */ -#define VBOX_VBVA_CONF32_MAX_RECORD_SIZE 6 - -struct vbva_conf32 { - u32 index; - u32 value; -} __packed; - -/* Reserved for historical reasons. */ -#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED0 BIT(0) -/* - * Guest cursor capability: can the host show a hardware cursor at the host - * pointer location? - */ -#define VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE BIT(1) -/* Reserved for historical reasons. */ -#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED2 BIT(2) -/* Reserved for historical reasons. Must always be unset. */ -#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED3 BIT(3) -/* Reserved for historical reasons. */ -#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED4 BIT(4) -/* Reserved for historical reasons. */ -#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED5 BIT(5) - -struct vbva_infoview { - /* Index of the screen, assigned by the guest. */ - u32 view_index; - - /* The screen offset in VRAM, the framebuffer starts here. */ - u32 view_offset; - - /* The size of the VRAM memory that can be used for the view. */ - u32 view_size; - - /* The recommended maximum size of the VRAM memory for the screen. */ - u32 max_screen_size; -} __packed; - -struct vbva_flush { - u32 reserved; -} __packed; - -/* vbva_infoscreen.flags */ -#define VBVA_SCREEN_F_NONE 0x0000 -#define VBVA_SCREEN_F_ACTIVE 0x0001 -/* - * The virtual monitor has been disabled by the guest and should be removed - * by the host and ignored for purposes of pointer position calculation. - */ -#define VBVA_SCREEN_F_DISABLED 0x0002 -/* - * The virtual monitor has been blanked by the guest and should be blacked - * out by the host using width, height, etc values from the vbva_infoscreen - * request. - */ -#define VBVA_SCREEN_F_BLANK 0x0004 -/* - * The virtual monitor has been blanked by the guest and should be blacked - * out by the host using the previous mode values for width. height, etc. - */ -#define VBVA_SCREEN_F_BLANK2 0x0008 - -struct vbva_infoscreen { - /* Which view contains the screen. */ - u32 view_index; - - /* Physical X origin relative to the primary screen. */ - s32 origin_x; - - /* Physical Y origin relative to the primary screen. */ - s32 origin_y; - - /* Offset of visible framebuffer relative to the framebuffer start. */ - u32 start_offset; - - /* The scan line size in bytes. */ - u32 line_size; - - /* Width of the screen. */ - u32 width; - - /* Height of the screen. */ - u32 height; - - /* Color depth. */ - u16 bits_per_pixel; - - /* VBVA_SCREEN_F_* */ - u16 flags; -} __packed; - -/* vbva_enable.flags */ -#define VBVA_F_NONE 0x00000000 -#define VBVA_F_ENABLE 0x00000001 -#define VBVA_F_DISABLE 0x00000002 -/* extended VBVA to be used with WDDM */ -#define VBVA_F_EXTENDED 0x00000004 -/* vbva offset is absolute VRAM offset */ -#define VBVA_F_ABSOFFSET 0x00000008 - -struct vbva_enable { - u32 flags; - u32 offset; - s32 result; -} __packed; - -struct vbva_enable_ex { - struct vbva_enable base; - u32 screen_id; -} __packed; - -struct vbva_mouse_pointer_shape { - /* The host result. */ - s32 result; - - /* VBOX_MOUSE_POINTER_* bit flags. */ - u32 flags; - - /* X coordinate of the hot spot. */ - u32 hot_X; - - /* Y coordinate of the hot spot. */ - u32 hot_y; - - /* Width of the pointer in pixels. */ - u32 width; - - /* Height of the pointer in scanlines. */ - u32 height; - - /* Pointer data. - * - * The data consists of 1 bpp AND mask followed by 32 bpp XOR (color) - * mask. - * - * For pointers without alpha channel the XOR mask pixels are 32 bit - * values: (lsb)BGR0(msb). For pointers with alpha channel the XOR mask - * consists of (lsb)BGRA(msb) 32 bit values. - * - * Guest driver must create the AND mask for pointers with alpha chan., - * so if host does not support alpha, the pointer could be displayed as - * a normal color pointer. The AND mask can be constructed from alpha - * values. For example alpha value >= 0xf0 means bit 0 in the AND mask. - * - * The AND mask is 1 bpp bitmap with byte aligned scanlines. Size of AND - * mask, therefore, is and_len = (width + 7) / 8 * height. The padding - * bits at the end of any scanline are undefined. - * - * The XOR mask follows the AND mask on the next 4 bytes aligned offset: - * u8 *xor = and + (and_len + 3) & ~3 - * Bytes in the gap between the AND and the XOR mask are undefined. - * XOR mask scanlines have no gap between them and size of XOR mask is: - * xor_len = width * 4 * height. - * - * Preallocate 4 bytes for accessing actual data as p->data. - */ - u8 data[4]; -} __packed; - -/* pointer is visible */ -#define VBOX_MOUSE_POINTER_VISIBLE 0x0001 -/* pointer has alpha channel */ -#define VBOX_MOUSE_POINTER_ALPHA 0x0002 -/* pointerData contains new pointer shape */ -#define VBOX_MOUSE_POINTER_SHAPE 0x0004 - -/* - * The guest driver can handle asynch guest cmd completion by reading the - * command offset from io port. - */ -#define VBVACAPS_COMPLETEGCMD_BY_IOREAD 0x00000001 -/* the guest driver can handle video adapter IRQs */ -#define VBVACAPS_IRQ 0x00000002 -/* The guest can read video mode hints sent via VBVA. */ -#define VBVACAPS_VIDEO_MODE_HINTS 0x00000004 -/* The guest can switch to a software cursor on demand. */ -#define VBVACAPS_DISABLE_CURSOR_INTEGRATION 0x00000008 -/* The guest does not depend on host handling the VBE registers. */ -#define VBVACAPS_USE_VBVA_ONLY 0x00000010 - -struct vbva_caps { - s32 rc; - u32 caps; -} __packed; - -/* Query the most recent mode hints received from the host. */ -struct vbva_query_mode_hints { - /* The maximum number of screens to return hints for. */ - u16 hints_queried_count; - /* The size of the mode hint structures directly following this one. */ - u16 hint_structure_guest_size; - /* Return code for the operation. Initialise to VERR_NOT_SUPPORTED. */ - s32 rc; -} __packed; - -/* - * Structure in which a mode hint is returned. The guest allocates an array - * of these immediately after the vbva_query_mode_hints structure. - * To accommodate future extensions, the vbva_query_mode_hints structure - * specifies the size of the vbva_modehint structures allocated by the guest, - * and the host only fills out structure elements which fit into that size. The - * host should fill any unused members (e.g. dx, dy) or structure space on the - * end with ~0. The whole structure can legally be set to ~0 to skip a screen. - */ -struct vbva_modehint { - u32 magic; - u32 cx; - u32 cy; - u32 bpp; /* Which has never been used... */ - u32 display; - u32 dx; /* X offset into the virtual frame-buffer. */ - u32 dy; /* Y offset into the virtual frame-buffer. */ - u32 enabled; /* Not flags. Add new members for new flags. */ -} __packed; - -#define VBVAMODEHINT_MAGIC 0x0801add9u - -/* - * Report the rectangle relative to which absolute pointer events should be - * expressed. This information remains valid until the next VBVA resize event - * for any screen, at which time it is reset to the bounding rectangle of all - * virtual screens and must be re-set. - */ -struct vbva_report_input_mapping { - s32 x; /* Upper left X co-ordinate relative to the first screen. */ - s32 y; /* Upper left Y co-ordinate relative to the first screen. */ - u32 cx; /* Rectangle width. */ - u32 cy; /* Rectangle height. */ -} __packed; - -/* - * Report the guest cursor position and query the host one. The host may wish - * to use the guest information to re-position its own cursor (though this is - * currently unlikely). - */ -struct vbva_cursor_position { - u32 report_position; /* Are we reporting a position? */ - u32 x; /* Guest cursor X position */ - u32 y; /* Guest cursor Y position */ -} __packed; - -#endif diff --git a/drivers/staging/vboxvideo/vboxvideo_guest.h b/drivers/staging/vboxvideo/vboxvideo_guest.h deleted file mode 100644 index 55fcee3a6470..000000000000 --- a/drivers/staging/vboxvideo/vboxvideo_guest.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright (C) 2006-2016 Oracle Corporation */ - -#ifndef __VBOXVIDEO_GUEST_H__ -#define __VBOXVIDEO_GUEST_H__ - -#include <linux/genalloc.h> -#include "vboxvideo.h" - -/* - * Structure grouping the context needed for sending graphics acceleration - * information to the host via VBVA. Each screen has its own VBVA buffer. - */ -struct vbva_buf_ctx { - /* Offset of the buffer in the VRAM section for the screen */ - u32 buffer_offset; - /* Length of the buffer in bytes */ - u32 buffer_length; - /* Set if we wrote to the buffer faster than the host could read it */ - bool buffer_overflow; - /* VBVA record that we are currently preparing for the host, or NULL */ - struct vbva_record *record; - /* - * Pointer to the VBVA buffer mapped into the current address space. - * Will be NULL if VBVA is not enabled. - */ - struct vbva_buffer *vbva; -}; - -int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location); -int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps); -int hgsmi_test_query_conf(struct gen_pool *ctx); -int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret); -int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags, - u32 hot_x, u32 hot_y, u32 width, u32 height, - u8 *pixels, u32 len); -int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position, - u32 x, u32 y, u32 *x_host, u32 *y_host); - -bool vbva_enable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx, - struct vbva_buffer *vbva, s32 screen); -void vbva_disable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx, - s32 screen); -bool vbva_buffer_begin_update(struct vbva_buf_ctx *vbva_ctx, - struct gen_pool *ctx); -void vbva_buffer_end_update(struct vbva_buf_ctx *vbva_ctx); -bool vbva_write(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx, - const void *p, u32 len); -void vbva_setup_buffer_context(struct vbva_buf_ctx *vbva_ctx, - u32 buffer_offset, u32 buffer_length); - -void hgsmi_process_display_info(struct gen_pool *ctx, u32 display, - s32 origin_x, s32 origin_y, u32 start_offset, - u32 pitch, u32 width, u32 height, - u16 bpp, u16 flags); -int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y, - u32 width, u32 height); -int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens, - struct vbva_modehint *hints); - -#endif diff --git a/drivers/staging/vboxvideo/vboxvideo_vbe.h b/drivers/staging/vboxvideo/vboxvideo_vbe.h deleted file mode 100644 index 427235869297..000000000000 --- a/drivers/staging/vboxvideo/vboxvideo_vbe.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* Copyright (C) 2006-2016 Oracle Corporation */ - -#ifndef __VBOXVIDEO_VBE_H__ -#define __VBOXVIDEO_VBE_H__ - -/* GUEST <-> HOST Communication API */ - -#define VBE_DISPI_BANK_ADDRESS 0xA0000 -#define VBE_DISPI_BANK_SIZE_KB 64 - -#define VBE_DISPI_MAX_XRES 16384 -#define VBE_DISPI_MAX_YRES 16384 -#define VBE_DISPI_MAX_BPP 32 - -#define VBE_DISPI_IOPORT_INDEX 0x01CE -#define VBE_DISPI_IOPORT_DATA 0x01CF - -#define VBE_DISPI_IOPORT_DAC_WRITE_INDEX 0x03C8 -#define VBE_DISPI_IOPORT_DAC_DATA 0x03C9 - -#define VBE_DISPI_INDEX_ID 0x0 -#define VBE_DISPI_INDEX_XRES 0x1 -#define VBE_DISPI_INDEX_YRES 0x2 -#define VBE_DISPI_INDEX_BPP 0x3 -#define VBE_DISPI_INDEX_ENABLE 0x4 -#define VBE_DISPI_INDEX_BANK 0x5 -#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 -#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 -#define VBE_DISPI_INDEX_X_OFFSET 0x8 -#define VBE_DISPI_INDEX_Y_OFFSET 0x9 -#define VBE_DISPI_INDEX_VBOX_VIDEO 0xa -#define VBE_DISPI_INDEX_FB_BASE_HI 0xb - -#define VBE_DISPI_ID0 0xB0C0 -#define VBE_DISPI_ID1 0xB0C1 -#define VBE_DISPI_ID2 0xB0C2 -#define VBE_DISPI_ID3 0xB0C3 -#define VBE_DISPI_ID4 0xB0C4 - -#define VBE_DISPI_ID_VBOX_VIDEO 0xBE00 -/* The VBOX interface id. Indicates support for VBVA shared memory interface. */ -#define VBE_DISPI_ID_HGSMI 0xBE01 -#define VBE_DISPI_ID_ANYX 0xBE02 - -#define VBE_DISPI_DISABLED 0x00 -#define VBE_DISPI_ENABLED 0x01 -#define VBE_DISPI_GETCAPS 0x02 -#define VBE_DISPI_8BIT_DAC 0x20 - -#define VGA_PORT_HGSMI_HOST 0x3b0 -#define VGA_PORT_HGSMI_GUEST 0x3d0 - -#endif diff --git a/drivers/staging/vboxvideo/vbva_base.c b/drivers/staging/vboxvideo/vbva_base.c deleted file mode 100644 index 36bc9824ec3f..000000000000 --- a/drivers/staging/vboxvideo/vbva_base.c +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: MIT -/* Copyright (C) 2006-2017 Oracle Corporation */ - -#include <linux/vbox_err.h> -#include "vbox_drv.h" -#include "vboxvideo_guest.h" -#include "hgsmi_channels.h" - -/* - * There is a hardware ring buffer in the graphics device video RAM, formerly - * in the VBox VMMDev PCI memory space. - * All graphics commands go there serialized by vbva_buffer_begin_update. - * and vbva_buffer_end_update. - * - * free_offset is writing position. data_offset is reading position. - * free_offset == data_offset means buffer is empty. - * There must be always gap between data_offset and free_offset when data - * are in the buffer. - * Guest only changes free_offset, host changes data_offset. - */ - -static u32 vbva_buffer_available(const struct vbva_buffer *vbva) -{ - s32 diff = vbva->data_offset - vbva->free_offset; - - return diff > 0 ? diff : vbva->data_len + diff; -} - -static void vbva_buffer_place_data_at(struct vbva_buf_ctx *vbva_ctx, - const void *p, u32 len, u32 offset) -{ - struct vbva_buffer *vbva = vbva_ctx->vbva; - u32 bytes_till_boundary = vbva->data_len - offset; - u8 *dst = &vbva->data[offset]; - s32 diff = len - bytes_till_boundary; - - if (diff <= 0) { - /* Chunk will not cross buffer boundary. */ - memcpy(dst, p, len); - } else { - /* Chunk crosses buffer boundary. */ - memcpy(dst, p, bytes_till_boundary); - memcpy(&vbva->data[0], (u8 *)p + bytes_till_boundary, diff); - } -} - -static void vbva_buffer_flush(struct gen_pool *ctx) -{ - struct vbva_flush *p; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_FLUSH); - if (!p) - return; - - p->reserved = 0; - - hgsmi_buffer_submit(ctx, p); - hgsmi_buffer_free(ctx, p); -} - -bool vbva_write(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx, - const void *p, u32 len) -{ - struct vbva_record *record; - struct vbva_buffer *vbva; - u32 available; - - vbva = vbva_ctx->vbva; - record = vbva_ctx->record; - - if (!vbva || vbva_ctx->buffer_overflow || - !record || !(record->len_and_flags & VBVA_F_RECORD_PARTIAL)) - return false; - - available = vbva_buffer_available(vbva); - - while (len > 0) { - u32 chunk = len; - - if (chunk >= available) { - vbva_buffer_flush(ctx); - available = vbva_buffer_available(vbva); - } - - if (chunk >= available) { - if (WARN_ON(available <= vbva->partial_write_tresh)) { - vbva_ctx->buffer_overflow = true; - return false; - } - chunk = available - vbva->partial_write_tresh; - } - - vbva_buffer_place_data_at(vbva_ctx, p, chunk, - vbva->free_offset); - - vbva->free_offset = (vbva->free_offset + chunk) % - vbva->data_len; - record->len_and_flags += chunk; - available -= chunk; - len -= chunk; - p += chunk; - } - - return true; -} - -static bool vbva_inform_host(struct vbva_buf_ctx *vbva_ctx, - struct gen_pool *ctx, s32 screen, bool enable) -{ - struct vbva_enable_ex *p; - bool ret; - - p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_ENABLE); - if (!p) - return false; - - p->base.flags = enable ? VBVA_F_ENABLE : VBVA_F_DISABLE; - p->base.offset = vbva_ctx->buffer_offset; - p->base.result = VERR_NOT_SUPPORTED; - if (screen >= 0) { - p->base.flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET; - p->screen_id = screen; - } - - hgsmi_buffer_submit(ctx, p); - - if (enable) - ret = p->base.result >= 0; - else - ret = true; - - hgsmi_buffer_free(ctx, p); - - return ret; -} - -bool vbva_enable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx, - struct vbva_buffer *vbva, s32 screen) -{ - bool ret = false; - - memset(vbva, 0, sizeof(*vbva)); - vbva->partial_write_tresh = 256; - vbva->data_len = vbva_ctx->buffer_length - sizeof(struct vbva_buffer); - vbva_ctx->vbva = vbva; - - ret = vbva_inform_host(vbva_ctx, ctx, screen, true); - if (!ret) - vbva_disable(vbva_ctx, ctx, screen); - - return ret; -} - -void vbva_disable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx, - s32 screen) -{ - vbva_ctx->buffer_overflow = false; - vbva_ctx->record = NULL; - vbva_ctx->vbva = NULL; - - vbva_inform_host(vbva_ctx, ctx, screen, false); -} - -bool vbva_buffer_begin_update(struct vbva_buf_ctx *vbva_ctx, - struct gen_pool *ctx) -{ - struct vbva_record *record; - u32 next; - - if (!vbva_ctx->vbva || - !(vbva_ctx->vbva->host_flags.host_events & VBVA_F_MODE_ENABLED)) - return false; - - WARN_ON(vbva_ctx->buffer_overflow || vbva_ctx->record); - - next = (vbva_ctx->vbva->record_free_index + 1) % VBVA_MAX_RECORDS; - - /* Flush if all slots in the records queue are used */ - if (next == vbva_ctx->vbva->record_first_index) - vbva_buffer_flush(ctx); - - /* If even after flush there is no place then fail the request */ - if (next == vbva_ctx->vbva->record_first_index) - return false; - - record = &vbva_ctx->vbva->records[vbva_ctx->vbva->record_free_index]; - record->len_and_flags = VBVA_F_RECORD_PARTIAL; - vbva_ctx->vbva->record_free_index = next; - /* Remember which record we are using. */ - vbva_ctx->record = record; - - return true; -} - -void vbva_buffer_end_update(struct vbva_buf_ctx *vbva_ctx) -{ - struct vbva_record *record = vbva_ctx->record; - - WARN_ON(!vbva_ctx->vbva || !record || - !(record->len_and_flags & VBVA_F_RECORD_PARTIAL)); - - /* Mark the record completed. */ - record->len_and_flags &= ~VBVA_F_RECORD_PARTIAL; - - vbva_ctx->buffer_overflow = false; - vbva_ctx->record = NULL; -} - -void vbva_setup_buffer_context(struct vbva_buf_ctx *vbva_ctx, - u32 buffer_offset, u32 buffer_length) -{ - vbva_ctx->buffer_offset = buffer_offset; - vbva_ctx->buffer_length = buffer_length; -} |