Commit bcb53e57 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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"
source "drivers/staging/typec/Kconfig"
source "drivers/staging/vboxvideo/Kconfig"
endif # STAGING
......@@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
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,
/* following line: 2-1 per STC */
ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_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 - 1, NISTC_AO_UI_LOADA_REG);
ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG);
} else { /* TRIG_EXT */
/* FIXME: assert scan_begin_arg != 0, ret failure otherwise */
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)
ibmsg = tx->tx_msg;
ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, IBLND_MSG_SIZE,
&from);
rc = copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, payload_nob,
&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]);
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,
break;
}
copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload,
IBLND_MSG_SIZE, to);
rc = copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload, rlen,
to);
if (rc != rlen) {
rc = -EFAULT;
break;
}
rc = 0;
lnet_finalize(ni, lntmsg, 0);
break;
......
......@@ -132,7 +132,7 @@ void rtw_free_cmd_obj(struct cmd_obj *pcmd)
kfree(pcmd->parmbuf);
}
if (!pcmd->rsp) {
if (pcmd->rsp) {
if (pcmd->rspsz != 0) {
/* free rsp in cmd_obj */
kfree(pcmd->rsp);
......
......@@ -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, 0x3310)}, /* Dlink DWA-123 REV D1 */
{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 */
{} /* Terminating entry */
};
......
......@@ -40,7 +40,7 @@ static unsigned int get_mxclk_freq(void)
pll_reg = peek32(MXCLK_PLL_CTRL);
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;
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)
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,
const struct pci_device_id *ent)
{
......@@ -1061,6 +1081,10 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
int fbidx;
int err;
err = lynxfb_kick_out_firmware_fb(pdev);
if (err)
return err;
/* enable device */
err = pcim_enable_device(pdev);
if (err)
......
......@@ -2314,6 +2314,7 @@ static void __exit speakup_exit(void)
mutex_lock(&spk_mutex);
synth_release();
mutex_unlock(&spk_mutex);
spk_ttyio_unregister_ldisc();
speakup_kobj_exit();
......@@ -2376,6 +2377,7 @@ static int __init speakup_init(void)
if (err)
goto error_kobjects;
spk_ttyio_register_ldisc();
synth_init(synth_name);
speakup_register_devsynth();
/*
......
......@@ -48,6 +48,8 @@ void spk_stop_serial_interrupt(void);
int spk_wait_for_xmitr(struct spk_synth *in_synth);
void spk_serial_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);
u16 synth_buffer_getc(void);
......
......@@ -154,12 +154,6 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
struct ktermios tmp_termios;
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);
if (ret)
return ret;
......@@ -196,10 +190,24 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
tty_unlock(tty);
ret = tty_set_ldisc(tty, N_SPEAKUP);
if (ret)
pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
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)
{
if (in_synth->alive && speakup_tty && speakup_tty->ops->write) {
......@@ -300,7 +308,7 @@ void spk_ttyio_release(void)
tty_ldisc_flush(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);
......
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.