Commit bcb53e57 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver fixes from Greg KH:
 "Here are some small staging driver fixes for reported issues for
  4.13-rc2.

  Also in here is a new driver, the virtualbox DRM driver. It's
  stand-alone and got acks from the DRM developers to go in through this
  tree. It's a new thing, but it should be fine for this point in the rc
  cycle due to it being independent.

  All of this has been in linux-next for a while with no reported
  issues"

* tag 'staging-4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: rtl8188eu: add TL-WN722N v2 support
  staging: speakup: safely register and unregister ldisc
  staging: speakup: add functions to register and unregister ldisc
  staging: speakup: safely close tty
  staging: sm750fb: avoid conflicting vesafb
  staging: lustre: ko2iblnd: check copy_from_iter/copy_to_iter return code
  staging: vboxvideo: Add vboxvideo to drivers/staging
  staging: sm750fb: fixed a assignment typo
  staging: rtl8188eu: memory leak in rtw_free_cmd_obj()
  staging: vchiq_arm: fix error codes in probe
  staging: comedi: ni_mio_common: fix AO timer off-by-one regression
parents 82abbea7 5a1d4c5d
...@@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig" ...@@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig"
source "drivers/staging/typec/Kconfig" source "drivers/staging/typec/Kconfig"
source "drivers/staging/vboxvideo/Kconfig"
endif # STAGING endif # STAGING
...@@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/ ...@@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/ obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/
...@@ -3116,8 +3116,7 @@ static void ni_ao_cmd_set_update(struct comedi_device *dev, ...@@ -3116,8 +3116,7 @@ static void ni_ao_cmd_set_update(struct comedi_device *dev,
/* following line: 2-1 per STC */ /* following line: 2-1 per STC */
ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG); ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG);
ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG); ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG);
/* following line: N-1 per STC */ ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG);
ni_stc_writel(dev, trigvar - 1, NISTC_AO_UI_LOADA_REG);
} else { /* TRIG_EXT */ } else { /* TRIG_EXT */
/* FIXME: assert scan_begin_arg != 0, ret failure otherwise */ /* FIXME: assert scan_begin_arg != 0, ret failure otherwise */
devpriv->ao_cmd2 |= NISTC_AO_CMD2_BC_GATE_ENA; devpriv->ao_cmd2 |= NISTC_AO_CMD2_BC_GATE_ENA;
......
...@@ -1640,8 +1640,13 @@ kiblnd_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg) ...@@ -1640,8 +1640,13 @@ kiblnd_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg)
ibmsg = tx->tx_msg; ibmsg = tx->tx_msg;
ibmsg->ibm_u.immediate.ibim_hdr = *hdr; ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, IBLND_MSG_SIZE, rc = copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, payload_nob,
&from); &from);
if (rc != payload_nob) {
kiblnd_pool_free_node(&tx->tx_pool->tpo_pool, &tx->tx_list);
return -EFAULT;
}
nob = offsetof(struct kib_immediate_msg, ibim_payload[payload_nob]); nob = offsetof(struct kib_immediate_msg, ibim_payload[payload_nob]);
kiblnd_init_tx_msg(ni, tx, IBLND_MSG_IMMEDIATE, nob); kiblnd_init_tx_msg(ni, tx, IBLND_MSG_IMMEDIATE, nob);
...@@ -1741,8 +1746,14 @@ kiblnd_recv(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg, ...@@ -1741,8 +1746,14 @@ kiblnd_recv(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg,
break; break;
} }
copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload, rc = copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload, rlen,
IBLND_MSG_SIZE, to); to);
if (rc != rlen) {
rc = -EFAULT;
break;
}
rc = 0;
lnet_finalize(ni, lntmsg, 0); lnet_finalize(ni, lntmsg, 0);
break; break;
......
...@@ -132,7 +132,7 @@ void rtw_free_cmd_obj(struct cmd_obj *pcmd) ...@@ -132,7 +132,7 @@ void rtw_free_cmd_obj(struct cmd_obj *pcmd)
kfree(pcmd->parmbuf); kfree(pcmd->parmbuf);
} }
if (!pcmd->rsp) { if (pcmd->rsp) {
if (pcmd->rspsz != 0) { if (pcmd->rspsz != 0) {
/* free rsp in cmd_obj */ /* free rsp in cmd_obj */
kfree(pcmd->rsp); kfree(pcmd->rsp);
......
...@@ -43,6 +43,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = { ...@@ -43,6 +43,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = {
{USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
{USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
{USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */ {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
{USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
{} /* Terminating entry */ {} /* Terminating entry */
}; };
......
...@@ -40,7 +40,7 @@ static unsigned int get_mxclk_freq(void) ...@@ -40,7 +40,7 @@ static unsigned int get_mxclk_freq(void)
pll_reg = peek32(MXCLK_PLL_CTRL); pll_reg = peek32(MXCLK_PLL_CTRL);
M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT; M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT;
N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_M_SHIFT; N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_N_SHIFT;
OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT; OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT;
POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT; POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT;
......
...@@ -1053,6 +1053,26 @@ static int sm750fb_frambuffer_alloc(struct sm750_dev *sm750_dev, int fbidx) ...@@ -1053,6 +1053,26 @@ static int sm750fb_frambuffer_alloc(struct sm750_dev *sm750_dev, int fbidx)
return err; return err;
} }
static int lynxfb_kick_out_firmware_fb(struct pci_dev *pdev)
{
struct apertures_struct *ap;
bool primary = false;
ap = alloc_apertures(1);
if (!ap)
return -ENOMEM;
ap->ranges[0].base = pci_resource_start(pdev, 0);
ap->ranges[0].size = pci_resource_len(pdev, 0);
#ifdef CONFIG_X86
primary = pdev->resource[PCI_ROM_RESOURCE].flags &
IORESOURCE_ROM_SHADOW;
#endif
remove_conflicting_framebuffers(ap, "sm750_fb1", primary);
kfree(ap);
return 0;
}
static int lynxfb_pci_probe(struct pci_dev *pdev, static int lynxfb_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
...@@ -1061,6 +1081,10 @@ static int lynxfb_pci_probe(struct pci_dev *pdev, ...@@ -1061,6 +1081,10 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
int fbidx; int fbidx;
int err; int err;
err = lynxfb_kick_out_firmware_fb(pdev);
if (err)
return err;
/* enable device */ /* enable device */
err = pcim_enable_device(pdev); err = pcim_enable_device(pdev);
if (err) if (err)
......
...@@ -2314,6 +2314,7 @@ static void __exit speakup_exit(void) ...@@ -2314,6 +2314,7 @@ static void __exit speakup_exit(void)
mutex_lock(&spk_mutex); mutex_lock(&spk_mutex);
synth_release(); synth_release();
mutex_unlock(&spk_mutex); mutex_unlock(&spk_mutex);
spk_ttyio_unregister_ldisc();
speakup_kobj_exit(); speakup_kobj_exit();
...@@ -2376,6 +2377,7 @@ static int __init speakup_init(void) ...@@ -2376,6 +2377,7 @@ static int __init speakup_init(void)
if (err) if (err)
goto error_kobjects; goto error_kobjects;
spk_ttyio_register_ldisc();
synth_init(synth_name); synth_init(synth_name);
speakup_register_devsynth(); speakup_register_devsynth();
/* /*
......
...@@ -48,6 +48,8 @@ void spk_stop_serial_interrupt(void); ...@@ -48,6 +48,8 @@ void spk_stop_serial_interrupt(void);
int spk_wait_for_xmitr(struct spk_synth *in_synth); int spk_wait_for_xmitr(struct spk_synth *in_synth);
void spk_serial_release(void); void spk_serial_release(void);
void spk_ttyio_release(void); void spk_ttyio_release(void);
void spk_ttyio_register_ldisc(void);
void spk_ttyio_unregister_ldisc(void);
void synth_buffer_skip_nonlatin1(void); void synth_buffer_skip_nonlatin1(void);
u16 synth_buffer_getc(void); u16 synth_buffer_getc(void);
......
...@@ -154,12 +154,6 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) ...@@ -154,12 +154,6 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
struct ktermios tmp_termios; struct ktermios tmp_termios;
dev_t dev; dev_t dev;
ret = tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops);
if (ret) {
pr_err("Error registering line discipline.\n");
return ret;
}
ret = get_dev_to_use(synth, &dev); ret = get_dev_to_use(synth, &dev);
if (ret) if (ret)
return ret; return ret;
...@@ -196,10 +190,24 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) ...@@ -196,10 +190,24 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
tty_unlock(tty); tty_unlock(tty);
ret = tty_set_ldisc(tty, N_SPEAKUP); ret = tty_set_ldisc(tty, N_SPEAKUP);
if (ret)
pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
return ret; return ret;
} }
void spk_ttyio_register_ldisc(void)
{
if (tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops))
pr_warn("speakup: Error registering line discipline. Most synths won't work.\n");
}
void spk_ttyio_unregister_ldisc(void)
{
if (tty_unregister_ldisc(N_SPEAKUP))
pr_warn("speakup: Couldn't unregister ldisc\n");
}
static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
{ {
if (in_synth->alive && speakup_tty && speakup_tty->ops->write) { if (in_synth->alive && speakup_tty && speakup_tty->ops->write) {
...@@ -300,7 +308,7 @@ void spk_ttyio_release(void) ...@@ -300,7 +308,7 @@ void spk_ttyio_release(void)
tty_ldisc_flush(speakup_tty); tty_ldisc_flush(speakup_tty);
tty_unlock(speakup_tty); tty_unlock(speakup_tty);
tty_ldisc_release(speakup_tty); tty_release_struct(speakup_tty, speakup_tty->index);
} }
EXPORT_SYMBOL_GPL(spk_ttyio_release); EXPORT_SYMBOL_GPL(spk_ttyio_release);
......
config DRM_VBOXVIDEO
tristate "Virtual Box Graphics Card"
depends on DRM && X86 && PCI
select DRM_KMS_HELPER
help
This is a KMS driver for the virtual Graphics Card used in
Virtual Box virtual machines.
Although it is possible to builtin this module, it is advised
to build this driver as a module, so that it can be updated
independently of the kernel. Select M to built this driver as a
module and add support for these devices via drm/kms interfaces.
ccflags-y := -Iinclude/drm
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
TODO:
-Move the driver over to the atomic API
-Stop using old load / unload drm_driver hooks
-Get a full review from the drm-maintainers on dri-devel done on this driver
-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> and
Michael Thayer <michael.thayer@oracle.com>.
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "vbox_drv.h"
#include "vbox_err.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.
* @param ctx the context of the guest heap to use.
* @param location the offset chosen for the flags within guest VRAM.
* @returns 0 on success, -errno on failure
*/
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.
* @param ctx the context of the guest heap to use.
* @param caps the capabilities to report, see vbva_caps.
* @returns 0 on success, -errno on failure
*/
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(RT_FAILURE(p->rc));
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.
* @param ctx the context containing the heap used
* @param index the index of the parameter to query,
* @see vbva_conf32::index
* @param value_ret where to store the value of the parameter on success
* @returns 0 on success, -errno on failure
*/
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.
*
* @param ctx the context containing the heap to be used
* @param flags cursor flags, @see VMMDevReqMousePointer::flags
* @param hot_x horizontal position of the hot spot
* @param hot_y vertical position of the hot spot
* @param width width in pixels of the cursor
* @param height height in pixels of the cursor
* @param pixels pixel data, @see VMMDevReqMousePointer for the format
* @param len size in bytes of the pixel data
* @returns 0 on success, -errno on failure
*/
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.
* @param ctx The context containing the heap used.
* @param report_position Are we reporting a position?
* @param x Guest cursor X position.
* @param y Guest cursor Y position.
* @param x_host Host cursor X position is stored here. Optional.
* @param y_host Host cursor Y position is stored here. Optional.
* @returns 0 on success, -errno on failure
*/
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;
}
/**
* @todo Mouse pointer position to be read from VMMDev memory, address of the
* memory region can be queried from VMMDev via an IOCTL. This VMMDev memory
* region will contain host information which is needed by the guest.
*
* Reading will not cause a switch to the host.
*
* Have to take into account:
* * synchronization: host must write to the memory only from EMT,
* large structures must be read under flag, which tells the host
* that the guest is currently reading the memory (OWNER flag?).
* * guest writes: may be allocate a page for the host info and make
* the page readonly for the guest.
* * the information should be available only for additions drivers.
* * VMMDev additions driver will inform the host which version of the info
* it expects, host must support all versions.
*/
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#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. */
/* host->guest commands pending, should be accessed under FIFO lock only */
#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x01u
/* IRQ is fired, should be accessed under VGAState::lock only */
#define HGSMIHOSTFLAGS_IRQ 0x02u
/* vsync interrupt flag, should be accessed under VGAState::lock only */
#define HGSMIHOSTFLAGS_VSYNC 0x10u
/** monitor hotplug flag, should be accessed under VGAState::lock only */
#define HGSMIHOSTFLAGS_HOTPLUG 0x20u
/**
* Cursor capability state change flag, should be accessed under
* VGAState::lock only. @see vbva_conf32.
*/
#define HGSMIHOSTFLAGS_CURSOR_CAPABILITIES 0x40u
struct hgsmi_host_flags {
/*
* Host flags can be accessed and modified in multiple threads
* concurrently, e.g. CrOpenGL HGCM and GUI threads when completing
* HGSMI 3D and Video Accel respectively, EMT thread when dealing with
* HGSMI command processing, etc.
* Besides settings/cleaning flags atomically, some flags have their
* own special sync restrictions, see comments for flags above.
*/
u32 host_flags;
u32 reserved[3];
} __packed;
#endif
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#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
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#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
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "vbox_drv.h"
#include "vbox_err.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.
* @param ctx The context containing the heap to use
* @param display The screen number
* @param origin_x The horizontal displacement relative to the first scrn
* @param origin_y The vertical displacement relative to the first screen
* @param start_offset The offset of the visible area of the framebuffer
* relative to the framebuffer start
* @param pitch The offset in bytes between the starts of two adjecent
* scan lines in video RAM
* @param width The mode width
* @param height The mode height
* @param bpp The colour depth of the mode
* @param 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.
* @param ctx The context containing the heap to use.
* @param origin_x Upper left X co-ordinate relative to the first screen.
* @param origin_y Upper left Y co-ordinate relative to the first screen.
* @param width Rectangle width.
* @param height Rectangle height.
* @returns 0 on success, -errno on failure
*/
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.
* @param ctx The context containing the heap to use.
* @param screens The number of screens to query hints for, starting at 0.
* @param hints Array of vbva_modehint structures for receiving the hints.
* @returns 0 on success, -errno on failure
*/
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 (RT_FAILURE(p->rc)) {
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;
}
/*
* Copyright (C) 2013-2017 Oracle Corporation
* This file is based on ast_drv.c
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* Authors: Dave Airlie <airlied@redhat.com>
* Michael Thayer <michael.thayer@oracle.com,
* Hans de Goede <hdegoede@redhat.com>
*/
#include <linux/module.h>
#include <linux/console.h>
#include <linux/vt_kern.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "vbox_drv.h"
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[] = {
{ 0x80ee, 0xbeef, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, 0, 0},
};
MODULE_DEVICE_TABLE(pci, pciidlist);
static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
return drm_get_pci_dev(pdev, ent, &driver);
}
static void vbox_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
drm_put_dev(dev);
}
static int vbox_drm_freeze(struct drm_device *dev)
{
struct vbox_private *vbox = dev->dev_private;
drm_kms_helper_poll_disable(dev);
pci_save_state(dev->pdev);
drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true);
return 0;
}
static int vbox_drm_thaw(struct drm_device *dev)
{
struct vbox_private *vbox = dev->dev_private;
drm_mode_config_reset(dev);
drm_helper_resume_force_mode(dev);
drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false);
return 0;
}
static int vbox_drm_resume(struct drm_device *dev)
{
int ret;
if (pci_enable_device(dev->pdev))
return -EIO;
ret = vbox_drm_thaw(dev);
if (ret)
return ret;
drm_kms_helper_poll_enable(dev);
return 0;
}
static int vbox_pm_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *ddev = pci_get_drvdata(pdev);
int error;
error = vbox_drm_freeze(ddev);
if (error)
return error;
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
static int vbox_pm_resume(struct device *dev)
{
struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
return vbox_drm_resume(ddev);
}
static int vbox_pm_freeze(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *ddev = pci_get_drvdata(pdev);
if (!ddev || !ddev->dev_private)
return -ENODEV;
return vbox_drm_freeze(ddev);
}
static int vbox_pm_thaw(struct device *dev)
{
struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
return vbox_drm_thaw(ddev);
}
static int vbox_pm_poweroff(struct device *dev)
{
struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
return vbox_drm_freeze(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,
};
static struct pci_driver vbox_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
.probe = vbox_pci_probe,
.remove = vbox_pci_remove,
.driver.pm = &vbox_pm_ops,
};
static const struct file_operations vbox_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
.mmap = vbox_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.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;
mutex_lock(&vbox->hw_mutex);
/*
* Disable VBVA when someone releases master in case the next person
* tries tries to do VESA.
*/
/** @todo work out if anyone is likely to and whether it will work. */
/*
* Update: we also disable it because if the new master does not do
* dirty rectangle reporting (e.g. old versions of Plymouth) then at
* least the first screen will still be updated. We enable it as soon
* as we receive a dirty rectangle report.
*/
vbox_disable_accel(vbox);
mutex_unlock(&vbox->hw_mutex);
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;
mutex_lock(&vbox->hw_mutex);
vbox_disable_accel(vbox);
mutex_unlock(&vbox->hw_mutex);
}
static struct drm_driver driver = {
.driver_features =
DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_PRIME,
.dev_priv_size = 0,
.load = vbox_driver_load,
.unload = vbox_driver_unload,
.lastclose = vbox_driver_lastclose,
.master_set = vbox_master_set,
.master_drop = vbox_master_drop,
.set_busid = drm_pci_set_busid,
.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 = vbox_gem_free_object,
.dumb_create = vbox_dumb_create,
.dumb_map_offset = vbox_dumb_mmap_offset,
.dumb_destroy = drm_gem_dumb_destroy,
.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 drm_pci_init(&driver, &vbox_pci_driver);
}
static void __exit vbox_exit(void)
{
drm_pci_exit(&driver, &vbox_pci_driver);
}
module_init(vbox_init);
module_exit(vbox_exit);
MODULE_AUTHOR("Oracle Corporation");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
/*
* Copyright (C) 2013-2017 Oracle Corporation
* This file is based on ast_drv.h
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* 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/string.h>
#include <linux/version.h>
#include <drm/drmP.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_fbdev;
struct vbox_private {
struct drm_device *dev;
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;
struct vbox_fbdev *fbdev;
int fb_mtrr;
struct {
struct drm_global_reference mem_global_ref;
struct ttm_bo_global_ref bo_global_ref;
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;
u32 cursor_width;
u32 cursor_height;
u32 cursor_hot_x;
u32 cursor_hot_y;
size_t cursor_data_size;
u8 cursor_data[CURSOR_DATA_SIZE];
};
#undef CURSOR_PIXEL_COUNT
#undef CURSOR_DATA_SIZE
int vbox_driver_load(struct drm_device *dev, unsigned long flags);
void vbox_driver_unload(struct drm_device *dev);
void vbox_driver_lastclose(struct drm_device *dev);
struct vbox_gem_object;
struct vbox_connector {
struct drm_connector base;
char name[32];
struct vbox_crtc *vbox_crtc;
struct {
u16 width;
u16 height;
bool disconnected;
} mode_hint;
};
struct vbox_crtc {
struct drm_crtc base;
bool blanked;
bool disconnected;
unsigned int crtc_id;
u32 fb_offset;
bool cursor_enabled;
u16 x_hint;
u16 y_hint;
};
struct vbox_encoder {
struct drm_encoder base;
};
struct vbox_framebuffer {
struct drm_framebuffer base;
struct drm_gem_object *obj;
};
struct vbox_fbdev {
struct drm_fb_helper helper;
struct vbox_framebuffer afb;
int size;
struct ttm_bo_kmap_obj mapping;
int x1, y1, x2, y2; /* dirty rect */
spinlock_t dirty_lock;
};
#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)
int vbox_mode_init(struct drm_device *dev);
void vbox_mode_fini(struct drm_device *dev);
#define DRM_MODE_FB_CMD drm_mode_fb_cmd2
#define CRTC_FB(crtc) ((crtc)->primary->fb)
void vbox_enable_accel(struct vbox_private *vbox);
void vbox_disable_accel(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 drm_device *dev,
struct vbox_framebuffer *vbox_fb,
const struct DRM_MODE_FB_CMD *mode_cmd,
struct drm_gem_object *obj);
int vbox_fbdev_init(struct drm_device *dev);
void vbox_fbdev_fini(struct drm_device *dev);
void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr);
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)
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 drm_device *dev, int size, int align,
u32 flags, struct vbox_bo **pvboxbo);
int vbox_gem_create(struct drm_device *dev,
u32 size, bool iskernel, struct drm_gem_object **obj);
int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr);
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);
/* 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
/*
* Copyright (C) 2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __VBOX_ERR_H__
#define __VBOX_ERR_H__
/**
* @name VirtualBox virtual-hardware error macros
* @{
*/
#define VINF_SUCCESS 0
#define VERR_INVALID_PARAMETER (-2)
#define VERR_INVALID_POINTER (-6)
#define VERR_NO_MEMORY (-8)
#define VERR_NOT_IMPLEMENTED (-12)
#define VERR_INVALID_FUNCTION (-36)
#define VERR_NOT_SUPPORTED (-37)
#define VERR_TOO_MUCH_DATA (-42)
#define VERR_INVALID_STATE (-79)
#define VERR_OUT_OF_RESOURCES (-80)
#define VERR_ALREADY_EXISTS (-105)
#define VERR_INTERNAL_ERROR (-225)
#define RT_SUCCESS_NP(rc) ((int)(rc) >= VINF_SUCCESS)
#define RT_SUCCESS(rc) (likely(RT_SUCCESS_NP(rc)))
#define RT_FAILURE(rc) (unlikely(!RT_SUCCESS_NP(rc)))
/** @} */
#endif
This diff is collapsed.
/*
* Copyright (C) 2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* 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;
}
/*
* Copyright (C) 2016-2017 Oracle Corporation
* This file is based on qxl_irq.c
* Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Dave Airlie
* Alon Levy
* Michael Thayer <michael.thayer@oracle.com,
* Hans de Goede <hdegoede@redhat.com>
*/
#include <drm/drm_crtc_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->dev;
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 & 0x8fff;
vbox_conn->mode_hint.height = hints->cy & 0x8fff;
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->dev);
}
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->dev, vbox->dev->pdev->irq);
}
void vbox_irq_fini(struct vbox_private *vbox)
{
drm_irq_uninstall(vbox->dev);
flush_work(&vbox->hotplug_work);
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2017 Oracle Corporation
* Copyright 2017 Canonical
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* 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;
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#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;
};
/**
* @name Base HGSMI APIs
* @{
*/
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);
/** @} */
/**
* @name VBVA APIs
* @{
*/
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);
/** @} */
/**
* @name Modesetting APIs
* @{
*/
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
/*
* Copyright (C) 2006-2017 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __VBOXVIDEO_VBE_H__
#define __VBOXVIDEO_VBE_H__
/* GUEST <-> HOST Communication API */
/**
* @todo FIXME: Either dynamicly ask host for this or put somewhere high in
* physical memory like 0xE0000000.
*/
#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
/**
* @note this definition is a BOCHS legacy, used only in the video BIOS
* code and ignored by the emulated hardware.
*/
#define VBE_DISPI_LFB_ENABLED 0x40
#define VBE_DISPI_NOCLEARMEM 0x80
#define VGA_PORT_HGSMI_HOST 0x3b0
#define VGA_PORT_HGSMI_GUEST 0x3d0
#endif
This diff is collapsed.
...@@ -3391,7 +3391,6 @@ static int vchiq_probe(struct platform_device *pdev) ...@@ -3391,7 +3391,6 @@ static int vchiq_probe(struct platform_device *pdev)
struct device_node *fw_node; struct device_node *fw_node;
struct rpi_firmware *fw; struct rpi_firmware *fw;
int err; int err;
void *ptr_err;
fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0); fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
if (!fw_node) { if (!fw_node) {
...@@ -3427,14 +3426,14 @@ static int vchiq_probe(struct platform_device *pdev) ...@@ -3427,14 +3426,14 @@ static int vchiq_probe(struct platform_device *pdev)
/* create sysfs entries */ /* create sysfs entries */
vchiq_class = class_create(THIS_MODULE, DEVICE_NAME); vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
ptr_err = vchiq_class; err = PTR_ERR(vchiq_class);
if (IS_ERR(ptr_err)) if (IS_ERR(vchiq_class))
goto failed_class_create; goto failed_class_create;
vchiq_dev = device_create(vchiq_class, NULL, vchiq_dev = device_create(vchiq_class, NULL,
vchiq_devid, NULL, "vchiq"); vchiq_devid, NULL, "vchiq");
ptr_err = vchiq_dev; err = PTR_ERR(vchiq_dev);
if (IS_ERR(ptr_err)) if (IS_ERR(vchiq_dev))
goto failed_device_create; goto failed_device_create;
/* create debugfs entries */ /* create debugfs entries */
...@@ -3455,7 +3454,6 @@ static int vchiq_probe(struct platform_device *pdev) ...@@ -3455,7 +3454,6 @@ static int vchiq_probe(struct platform_device *pdev)
class_destroy(vchiq_class); class_destroy(vchiq_class);
failed_class_create: failed_class_create:
cdev_del(&vchiq_cdev); cdev_del(&vchiq_cdev);
err = PTR_ERR(ptr_err);
failed_cdev_add: failed_cdev_add:
unregister_chrdev_region(vchiq_devid, 1); unregister_chrdev_region(vchiq_devid, 1);
failed_platform_init: failed_platform_init:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment