mirror of
https://github.com/qemu/qemu.git
synced 2025-07-31 17:56:52 +00:00
fixes for console, audio, usb, vga.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCgAGBQJfrnw4AAoJEEy22O7T6HE4LlYP/1hwAAtg6nKERX7AlSw5BuzY Px8MbtqcvQTMiYqOnLviQaszawG51WKi/WMk6/smql2viaaP2RTBpudSBVpcPSui wJfjWSeFOiBdrdVbbXNnFb2xfuOyyKt8axL8Iyo+rL088Hr1llh1CecYjf32tycv bAniOTMnbuox074C9j2X4b3Xk/cwsDVcqQGDLKvjjdaHxDwu3mXuxKqalzccIBSa puKCU0PTkgxb5Q9/Zb+akxKjHlMPhwCOMKVeORmhcnz8qBoXLT7tg7IPvs+wjnqH jJlnb2vOOHFek2nIPX/8ZnP+SvyAJMHn+25NNpjEL8HFRG3X74vxOndvCXWx+YR0 5of6rsooSEFeY4DVMsGKexsFtCHCvLJYJmeTxDB4kGqSU6XR6YkdjkXxj7qXesJj oNM7ox1KyiCCgtVt4a8okt8dVxxwlHO+f04DZyAwuUkTiu1xAuF6z5fCbiWrm9Yt 4ISoCOonm+QRpRYMgYPAUlaeWFkIbl2WHQ7jl6zQPQLSEYmUdzr0maL6hWH91/eA jykuirVEpEdNfF2jZIWDy116m2bRyAp9NxrhA1RhfmPCJuQTD2d6nEHrAIx9DDOT j8DyKAwrYCXq36dpnHqpFAqcqYnumqCemqnUJQprG8ltme5AlKrm0ucjd4oH51Yk DLQ7RGAUd/5k8NES5rCO =h/Rx -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20201113-pull-request' into staging fixes for console, audio, usb, vga. # gpg: Signature made Fri 13 Nov 2020 12:29:44 GMT # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/fixes-20201113-pull-request: xhci: fix nec-usb-xhci properties hw/display/cirrus_vga: Fix hexadecimal format string specifier hw/display/cirrus_vga: Remove debugging code commented out hw/usb/Kconfig: Fix USB_XHCI_NEC (depends on USB_XHCI_PCI) console: avoid passing con=NULL to graphic_hw_update_done() audio/jack: fix use after free segfault Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6980c128b5
@ -25,6 +25,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/atomic.h"
|
#include "qemu/atomic.h"
|
||||||
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ typedef struct QJackClient {
|
|||||||
QJackState state;
|
QJackState state;
|
||||||
jack_client_t *client;
|
jack_client_t *client;
|
||||||
jack_nframes_t freq;
|
jack_nframes_t freq;
|
||||||
|
QEMUBH *shutdown_bh;
|
||||||
|
|
||||||
struct QJack *j;
|
struct QJack *j;
|
||||||
int nchannels;
|
int nchannels;
|
||||||
@ -87,6 +89,7 @@ QJackIn;
|
|||||||
static int qjack_client_init(QJackClient *c);
|
static int qjack_client_init(QJackClient *c);
|
||||||
static void qjack_client_connect_ports(QJackClient *c);
|
static void qjack_client_connect_ports(QJackClient *c);
|
||||||
static void qjack_client_fini(QJackClient *c);
|
static void qjack_client_fini(QJackClient *c);
|
||||||
|
static QemuMutex qjack_shutdown_lock;
|
||||||
|
|
||||||
static void qjack_buffer_create(QJackBuffer *buffer, int channels, int frames)
|
static void qjack_buffer_create(QJackBuffer *buffer, int channels, int frames)
|
||||||
{
|
{
|
||||||
@ -306,21 +309,27 @@ static int qjack_xrun(void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qjack_shutdown_bh(void *opaque)
|
||||||
|
{
|
||||||
|
QJackClient *c = (QJackClient *)opaque;
|
||||||
|
qjack_client_fini(c);
|
||||||
|
}
|
||||||
|
|
||||||
static void qjack_shutdown(void *arg)
|
static void qjack_shutdown(void *arg)
|
||||||
{
|
{
|
||||||
QJackClient *c = (QJackClient *)arg;
|
QJackClient *c = (QJackClient *)arg;
|
||||||
c->state = QJACK_STATE_SHUTDOWN;
|
c->state = QJACK_STATE_SHUTDOWN;
|
||||||
|
qemu_bh_schedule(c->shutdown_bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qjack_client_recover(QJackClient *c)
|
static void qjack_client_recover(QJackClient *c)
|
||||||
{
|
{
|
||||||
if (c->state == QJACK_STATE_SHUTDOWN) {
|
if (c->state != QJACK_STATE_DISCONNECTED) {
|
||||||
qjack_client_fini(c);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* packets is used simply to throttle this */
|
/* packets is used simply to throttle this */
|
||||||
if (c->state == QJACK_STATE_DISCONNECTED &&
|
if (c->packets % 100 == 0) {
|
||||||
c->packets % 100 == 0) {
|
|
||||||
|
|
||||||
/* if enabled then attempt to recover */
|
/* if enabled then attempt to recover */
|
||||||
if (c->enabled) {
|
if (c->enabled) {
|
||||||
@ -489,15 +498,16 @@ static int qjack_init_out(HWVoiceOut *hw, struct audsettings *as,
|
|||||||
QJackOut *jo = (QJackOut *)hw;
|
QJackOut *jo = (QJackOut *)hw;
|
||||||
Audiodev *dev = (Audiodev *)drv_opaque;
|
Audiodev *dev = (Audiodev *)drv_opaque;
|
||||||
|
|
||||||
qjack_client_fini(&jo->c);
|
|
||||||
|
|
||||||
jo->c.out = true;
|
jo->c.out = true;
|
||||||
jo->c.enabled = false;
|
jo->c.enabled = false;
|
||||||
jo->c.nchannels = as->nchannels;
|
jo->c.nchannels = as->nchannels;
|
||||||
jo->c.opt = dev->u.jack.out;
|
jo->c.opt = dev->u.jack.out;
|
||||||
|
|
||||||
|
jo->c.shutdown_bh = qemu_bh_new(qjack_shutdown_bh, &jo->c);
|
||||||
|
|
||||||
int ret = qjack_client_init(&jo->c);
|
int ret = qjack_client_init(&jo->c);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
qemu_bh_delete(jo->c.shutdown_bh);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,15 +535,16 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings *as,
|
|||||||
QJackIn *ji = (QJackIn *)hw;
|
QJackIn *ji = (QJackIn *)hw;
|
||||||
Audiodev *dev = (Audiodev *)drv_opaque;
|
Audiodev *dev = (Audiodev *)drv_opaque;
|
||||||
|
|
||||||
qjack_client_fini(&ji->c);
|
|
||||||
|
|
||||||
ji->c.out = false;
|
ji->c.out = false;
|
||||||
ji->c.enabled = false;
|
ji->c.enabled = false;
|
||||||
ji->c.nchannels = as->nchannels;
|
ji->c.nchannels = as->nchannels;
|
||||||
ji->c.opt = dev->u.jack.in;
|
ji->c.opt = dev->u.jack.in;
|
||||||
|
|
||||||
|
ji->c.shutdown_bh = qemu_bh_new(qjack_shutdown_bh, &ji->c);
|
||||||
|
|
||||||
int ret = qjack_client_init(&ji->c);
|
int ret = qjack_client_init(&ji->c);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
qemu_bh_delete(ji->c.shutdown_bh);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,7 +566,7 @@ static int qjack_init_in(HWVoiceIn *hw, struct audsettings *as,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qjack_client_fini(QJackClient *c)
|
static void qjack_client_fini_locked(QJackClient *c)
|
||||||
{
|
{
|
||||||
switch (c->state) {
|
switch (c->state) {
|
||||||
case QJACK_STATE_RUNNING:
|
case QJACK_STATE_RUNNING:
|
||||||
@ -564,28 +575,40 @@ static void qjack_client_fini(QJackClient *c)
|
|||||||
|
|
||||||
case QJACK_STATE_SHUTDOWN:
|
case QJACK_STATE_SHUTDOWN:
|
||||||
jack_client_close(c->client);
|
jack_client_close(c->client);
|
||||||
|
c->client = NULL;
|
||||||
|
|
||||||
|
qjack_buffer_free(&c->fifo);
|
||||||
|
g_free(c->port);
|
||||||
|
|
||||||
|
c->state = QJACK_STATE_DISCONNECTED;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
|
||||||
case QJACK_STATE_DISCONNECTED:
|
case QJACK_STATE_DISCONNECTED:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qjack_buffer_free(&c->fifo);
|
static void qjack_client_fini(QJackClient *c)
|
||||||
g_free(c->port);
|
{
|
||||||
|
qemu_mutex_lock(&qjack_shutdown_lock);
|
||||||
c->state = QJACK_STATE_DISCONNECTED;
|
qjack_client_fini_locked(c);
|
||||||
|
qemu_mutex_unlock(&qjack_shutdown_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qjack_fini_out(HWVoiceOut *hw)
|
static void qjack_fini_out(HWVoiceOut *hw)
|
||||||
{
|
{
|
||||||
QJackOut *jo = (QJackOut *)hw;
|
QJackOut *jo = (QJackOut *)hw;
|
||||||
qjack_client_fini(&jo->c);
|
qjack_client_fini(&jo->c);
|
||||||
|
|
||||||
|
qemu_bh_delete(jo->c.shutdown_bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qjack_fini_in(HWVoiceIn *hw)
|
static void qjack_fini_in(HWVoiceIn *hw)
|
||||||
{
|
{
|
||||||
QJackIn *ji = (QJackIn *)hw;
|
QJackIn *ji = (QJackIn *)hw;
|
||||||
qjack_client_fini(&ji->c);
|
qjack_client_fini(&ji->c);
|
||||||
|
|
||||||
|
qemu_bh_delete(ji->c.shutdown_bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qjack_enable_out(HWVoiceOut *hw, bool enable)
|
static void qjack_enable_out(HWVoiceOut *hw, bool enable)
|
||||||
@ -662,6 +685,7 @@ static void qjack_info(const char *msg)
|
|||||||
|
|
||||||
static void register_audio_jack(void)
|
static void register_audio_jack(void)
|
||||||
{
|
{
|
||||||
|
qemu_mutex_init(&qjack_shutdown_lock);
|
||||||
audio_driver_register(&jack_driver);
|
audio_driver_register(&jack_driver);
|
||||||
jack_set_thread_creator(qjack_thread_creator);
|
jack_set_thread_creator(qjack_thread_creator);
|
||||||
jack_set_error_function(qjack_error);
|
jack_set_error_function(qjack_error);
|
||||||
|
@ -2105,7 +2105,7 @@ static void cirrus_vga_mem_write(void *opaque,
|
|||||||
} else {
|
} else {
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
"cirrus: mem_writeb 0x" TARGET_FMT_plx " "
|
"cirrus: mem_writeb 0x" TARGET_FMT_plx " "
|
||||||
"value 0x%02" PRIu64 "\n", addr, mem_value);
|
"value 0x%02" PRIx64 "\n", addr, mem_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2532,9 +2532,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
|
|||||||
case 0x3c5:
|
case 0x3c5:
|
||||||
val = cirrus_vga_read_sr(c);
|
val = cirrus_vga_read_sr(c);
|
||||||
break;
|
break;
|
||||||
#ifdef DEBUG_VGA_REG
|
|
||||||
printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case 0x3c6:
|
case 0x3c6:
|
||||||
val = cirrus_read_hidden_dac(c);
|
val = cirrus_read_hidden_dac(c);
|
||||||
@ -2560,9 +2557,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
|
|||||||
break;
|
break;
|
||||||
case 0x3cf:
|
case 0x3cf:
|
||||||
val = cirrus_vga_read_gr(c, s->gr_index);
|
val = cirrus_vga_read_gr(c, s->gr_index);
|
||||||
#ifdef DEBUG_VGA_REG
|
|
||||||
printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case 0x3b4:
|
case 0x3b4:
|
||||||
case 0x3d4:
|
case 0x3d4:
|
||||||
@ -2571,9 +2565,6 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr,
|
|||||||
case 0x3b5:
|
case 0x3b5:
|
||||||
case 0x3d5:
|
case 0x3d5:
|
||||||
val = cirrus_vga_read_cr(c, s->cr_index);
|
val = cirrus_vga_read_cr(c, s->cr_index);
|
||||||
#ifdef DEBUG_VGA_REG
|
|
||||||
printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case 0x3ba:
|
case 0x3ba:
|
||||||
case 0x3da:
|
case 0x3da:
|
||||||
@ -2645,9 +2636,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
s->sr_index = val;
|
s->sr_index = val;
|
||||||
break;
|
break;
|
||||||
case 0x3c5:
|
case 0x3c5:
|
||||||
#ifdef DEBUG_VGA_REG
|
|
||||||
printf("vga: write SR%x = 0x%02" PRIu64 "\n", s->sr_index, val);
|
|
||||||
#endif
|
|
||||||
cirrus_vga_write_sr(c, val);
|
cirrus_vga_write_sr(c, val);
|
||||||
break;
|
break;
|
||||||
case 0x3c6:
|
case 0x3c6:
|
||||||
@ -2670,9 +2658,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
s->gr_index = val;
|
s->gr_index = val;
|
||||||
break;
|
break;
|
||||||
case 0x3cf:
|
case 0x3cf:
|
||||||
#ifdef DEBUG_VGA_REG
|
|
||||||
printf("vga: write GR%x = 0x%02" PRIu64 "\n", s->gr_index, val);
|
|
||||||
#endif
|
|
||||||
cirrus_vga_write_gr(c, s->gr_index, val);
|
cirrus_vga_write_gr(c, s->gr_index, val);
|
||||||
break;
|
break;
|
||||||
case 0x3b4:
|
case 0x3b4:
|
||||||
@ -2681,9 +2666,6 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
break;
|
break;
|
||||||
case 0x3b5:
|
case 0x3b5:
|
||||||
case 0x3d5:
|
case 0x3d5:
|
||||||
#ifdef DEBUG_VGA_REG
|
|
||||||
printf("vga: write CR%x = 0x%02"PRIu64"\n", s->cr_index, val);
|
|
||||||
#endif
|
|
||||||
cirrus_vga_write_cr(c, val);
|
cirrus_vga_write_cr(c, val);
|
||||||
break;
|
break;
|
||||||
case 0x3ba:
|
case 0x3ba:
|
||||||
|
@ -43,8 +43,7 @@ config USB_XHCI_PCI
|
|||||||
config USB_XHCI_NEC
|
config USB_XHCI_NEC
|
||||||
bool
|
bool
|
||||||
default y if PCI_DEVICES
|
default y if PCI_DEVICES
|
||||||
depends on PCI
|
select USB_XHCI_PCI
|
||||||
select USB_XHCI
|
|
||||||
|
|
||||||
config USB_XHCI_SYSBUS
|
config USB_XHCI_SYSBUS
|
||||||
bool
|
bool
|
||||||
|
@ -27,18 +27,37 @@
|
|||||||
|
|
||||||
#include "hcd-xhci-pci.h"
|
#include "hcd-xhci-pci.h"
|
||||||
|
|
||||||
|
typedef struct XHCINecState {
|
||||||
|
/*< private >*/
|
||||||
|
XHCIPciState parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t intrs;
|
||||||
|
uint32_t slots;
|
||||||
|
} XHCINecState;
|
||||||
|
|
||||||
static Property nec_xhci_properties[] = {
|
static Property nec_xhci_properties[] = {
|
||||||
DEFINE_PROP_ON_OFF_AUTO("msi", XHCIPciState, msi, ON_OFF_AUTO_AUTO),
|
DEFINE_PROP_ON_OFF_AUTO("msi", XHCIPciState, msi, ON_OFF_AUTO_AUTO),
|
||||||
DEFINE_PROP_ON_OFF_AUTO("msix", XHCIPciState, msix, ON_OFF_AUTO_AUTO),
|
DEFINE_PROP_ON_OFF_AUTO("msix", XHCIPciState, msix, ON_OFF_AUTO_AUTO),
|
||||||
DEFINE_PROP_BIT("superspeed-ports-first", XHCIPciState,
|
DEFINE_PROP_BIT("superspeed-ports-first", XHCINecState, flags,
|
||||||
xhci.flags, XHCI_FLAG_SS_FIRST, true),
|
XHCI_FLAG_SS_FIRST, true),
|
||||||
DEFINE_PROP_BIT("force-pcie-endcap", XHCIPciState, xhci.flags,
|
DEFINE_PROP_BIT("force-pcie-endcap", XHCINecState, flags,
|
||||||
XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
|
XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
|
||||||
DEFINE_PROP_UINT32("intrs", XHCIPciState, xhci.numintrs, XHCI_MAXINTRS),
|
DEFINE_PROP_UINT32("intrs", XHCINecState, intrs, XHCI_MAXINTRS),
|
||||||
DEFINE_PROP_UINT32("slots", XHCIPciState, xhci.numslots, XHCI_MAXSLOTS),
|
DEFINE_PROP_UINT32("slots", XHCINecState, slots, XHCI_MAXSLOTS),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void nec_xhci_instance_init(Object *obj)
|
||||||
|
{
|
||||||
|
XHCIPciState *pci = XHCI_PCI(obj);
|
||||||
|
XHCINecState *nec = container_of(pci, XHCINecState, parent_obj);
|
||||||
|
|
||||||
|
pci->xhci.flags = nec->flags;
|
||||||
|
pci->xhci.numintrs = nec->intrs;
|
||||||
|
pci->xhci.numslots = nec->slots;
|
||||||
|
}
|
||||||
|
|
||||||
static void nec_xhci_class_init(ObjectClass *klass, void *data)
|
static void nec_xhci_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
@ -53,6 +72,8 @@ static void nec_xhci_class_init(ObjectClass *klass, void *data)
|
|||||||
static const TypeInfo nec_xhci_info = {
|
static const TypeInfo nec_xhci_info = {
|
||||||
.name = TYPE_NEC_XHCI,
|
.name = TYPE_NEC_XHCI,
|
||||||
.parent = TYPE_XHCI_PCI,
|
.parent = TYPE_XHCI_PCI,
|
||||||
|
.instance_size = sizeof(XHCINecState),
|
||||||
|
.instance_init = nec_xhci_instance_init,
|
||||||
.class_init = nec_xhci_class_init,
|
.class_init = nec_xhci_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -270,10 +270,11 @@ void graphic_hw_update_done(QemuConsole *con)
|
|||||||
void graphic_hw_update(QemuConsole *con)
|
void graphic_hw_update(QemuConsole *con)
|
||||||
{
|
{
|
||||||
bool async = false;
|
bool async = false;
|
||||||
|
con = con ? con : active_console;
|
||||||
if (!con) {
|
if (!con) {
|
||||||
con = active_console;
|
return;
|
||||||
}
|
}
|
||||||
if (con && con->hw_ops->gfx_update) {
|
if (con->hw_ops->gfx_update) {
|
||||||
con->hw_ops->gfx_update(con->hw);
|
con->hw_ops->gfx_update(con->hw);
|
||||||
async = con->hw_ops->gfx_update_async;
|
async = con->hw_ops->gfx_update_async;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user