mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
usb: make usbnet work with xhci.
audio: add sndio backend. misc bugfixes for console, xhci, audio, ati-vga and virtio-gpu. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmMyse8ACgkQTLbY7tPo cTiLrRAAltoyd++jsmhg2wXuJsfekfec3kOro7T+eSznDWfBRvm7VxJ+gswYBYga HbEkHjII0yPbOP9WDMhhHx33g2nYdbhDLPKXHdK8MjHTTPxtYP7XmsWkEVpuuzTx WqeYvGSmUri6QOUz7fd07IhiBT1aQvUQ/vWQ6OhyRVPy41bR8kIbGx3iV0JDxWvz n3xUZALGLz3QAM0lXRzXPYT9JB/RqdbpMM35HNTpN9/xaZmgFWsyuQXSSm61pTtb PS+lILDPjgZeYsfsZRyhZaSZrp2f6WOGm1ZdtSM0rvmRKezOzYnG8fm4fqZQLYSj nrAqUs38sKaM71a3QbpXhDjbv4cpj0K3iSNLmlUq4pgvPiMgwPlgSwwCGlkNDaRo IA1KON1pMH2A5vvtXEUt5RTkbXxHAAKPdpl5sS6kgbs7dgoKDqzaIPFQELam259Z 9nbMBqz/d6gm2CFT5ogrY0q511IC5hWtsmbQZkOZeBd5SvhvyJ59DIabFDcw05fG ixZVapewXYtzFUde2lb8X5qyneUVeGY5D2OJ2uUykHgR2Qz4d3CjXlhnRkLIkMcd Uu6N1LTkjyuuB86BoTSZxk0iz94OvmyDiXpqwmRaCGcdnTOTj0dKrbRrtHdC2vCo cBpUAIdyJvDJSm0X8ZWvvv1sMJCAJ7lofFf/P/jUKlacC2ipgXQ= =QBLK -----END PGP SIGNATURE----- Merge tag 'kraxel-20220927-pull-request' of https://gitlab.com/kraxel/qemu into staging usb: make usbnet work with xhci. audio: add sndio backend. misc bugfixes for console, xhci, audio, ati-vga and virtio-gpu. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmMyse8ACgkQTLbY7tPo # cTiLrRAAltoyd++jsmhg2wXuJsfekfec3kOro7T+eSznDWfBRvm7VxJ+gswYBYga # HbEkHjII0yPbOP9WDMhhHx33g2nYdbhDLPKXHdK8MjHTTPxtYP7XmsWkEVpuuzTx # WqeYvGSmUri6QOUz7fd07IhiBT1aQvUQ/vWQ6OhyRVPy41bR8kIbGx3iV0JDxWvz # n3xUZALGLz3QAM0lXRzXPYT9JB/RqdbpMM35HNTpN9/xaZmgFWsyuQXSSm61pTtb # PS+lILDPjgZeYsfsZRyhZaSZrp2f6WOGm1ZdtSM0rvmRKezOzYnG8fm4fqZQLYSj # nrAqUs38sKaM71a3QbpXhDjbv4cpj0K3iSNLmlUq4pgvPiMgwPlgSwwCGlkNDaRo # IA1KON1pMH2A5vvtXEUt5RTkbXxHAAKPdpl5sS6kgbs7dgoKDqzaIPFQELam259Z # 9nbMBqz/d6gm2CFT5ogrY0q511IC5hWtsmbQZkOZeBd5SvhvyJ59DIabFDcw05fG # ixZVapewXYtzFUde2lb8X5qyneUVeGY5D2OJ2uUykHgR2Qz4d3CjXlhnRkLIkMcd # Uu6N1LTkjyuuB86BoTSZxk0iz94OvmyDiXpqwmRaCGcdnTOTj0dKrbRrtHdC2vCo # cBpUAIdyJvDJSm0X8ZWvvv1sMJCAJ7lofFf/P/jUKlacC2ipgXQ= # =QBLK # -----END PGP SIGNATURE----- # gpg: Signature made Tue 27 Sep 2022 04:18:55 EDT # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # 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 * tag 'kraxel-20220927-pull-request' of https://gitlab.com/kraxel/qemu: (24 commits) virtio-gpu: update scanout if there is any area covered by the rect hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638) audio: remove abort() in audio_bug() Revert "audio: Log context for audio bug" audio: Add sndio backend usbnet: Report link-up via interrupt endpoint in CDC-ECM mode usbnet: Detect short packets as sent by the xHCI controller usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request usbnet: Add missing usb_wakeup() call in usbnet_receive() hcd-xhci: drop operation with secondary stream arrays enabled usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert usb/msd: move usb_msd_packet_complete() hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is zero hw/usb/hcd-xhci: Check whether DMA accesses fail ui/console: fix three double frees in png_save() ui/vdagent: fix serial reset of guest agent ui/clipboard: reset the serial state on reset ui/vdagent: always reset the clipboard serial on caps ui/clipboard: fix serial priority ui: add some vdagent related traces ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
c48c9c6b33
31 changed files with 903 additions and 205 deletions
|
@ -84,7 +84,7 @@ void ati_2d_blt(ATIVGAState *s)
|
|||
DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n",
|
||||
s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset,
|
||||
s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch,
|
||||
s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y,
|
||||
s->regs.src_x, s->regs.src_y, dst_x, dst_y,
|
||||
s->regs.dst_width, s->regs.dst_height,
|
||||
(s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? '>' : '<'),
|
||||
(s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? 'v' : '^'));
|
||||
|
@ -180,11 +180,11 @@ void ati_2d_blt(ATIVGAState *s)
|
|||
dst_stride /= sizeof(uint32_t);
|
||||
DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
|
||||
dst_bits, dst_stride, bpp,
|
||||
s->regs.dst_x, s->regs.dst_y,
|
||||
dst_x, dst_y,
|
||||
s->regs.dst_width, s->regs.dst_height,
|
||||
filler);
|
||||
pixman_fill((uint32_t *)dst_bits, dst_stride, bpp,
|
||||
s->regs.dst_x, s->regs.dst_y,
|
||||
dst_x, dst_y,
|
||||
s->regs.dst_width, s->regs.dst_height,
|
||||
filler);
|
||||
if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
|
||||
|
|
|
@ -515,9 +515,10 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
|
|||
for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
|
||||
scanout = &g->parent_obj.scanout[i];
|
||||
if (scanout->resource_id == res->resource_id &&
|
||||
rf.r.x >= scanout->x && rf.r.y >= scanout->y &&
|
||||
rf.r.x + rf.r.width <= scanout->x + scanout->width &&
|
||||
rf.r.y + rf.r.height <= scanout->y + scanout->height &&
|
||||
rf.r.x < scanout->x + scanout->width &&
|
||||
rf.r.x + rf.r.width >= scanout->x &&
|
||||
rf.r.y < scanout->y + scanout->height &&
|
||||
rf.r.y + rf.r.height >= scanout->y &&
|
||||
console_has_gl(scanout->con)) {
|
||||
dpy_gl_update(scanout->con, 0, 0, scanout->width,
|
||||
scanout->height);
|
||||
|
|
|
@ -91,6 +91,8 @@ enum usbstring_idx {
|
|||
#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43
|
||||
#define USB_CDC_GET_ETHERNET_STATISTIC 0x44
|
||||
|
||||
#define USB_CDC_NETWORK_CONNECTION 0x00
|
||||
|
||||
#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
|
||||
#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
|
||||
|
||||
|
@ -640,6 +642,8 @@ struct USBNetState {
|
|||
uint16_t filter;
|
||||
uint32_t vendorid;
|
||||
|
||||
uint16_t connection;
|
||||
|
||||
unsigned int out_ptr;
|
||||
uint8_t out_buf[2048];
|
||||
|
||||
|
@ -647,6 +651,7 @@ struct USBNetState {
|
|||
uint8_t in_buf[2048];
|
||||
|
||||
USBEndpoint *intr;
|
||||
USBEndpoint *bulk_in;
|
||||
|
||||
char usbstring_mac[13];
|
||||
NICState *nic;
|
||||
|
@ -1121,6 +1126,12 @@ static void usb_net_handle_control(USBDevice *dev, USBPacket *p,
|
|||
#endif
|
||||
break;
|
||||
|
||||
case ClassInterfaceOutRequest | USB_CDC_SET_ETHERNET_PACKET_FILTER:
|
||||
if (is_rndis(s)) {
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fail:
|
||||
fprintf(stderr, "usbnet: failed control transaction: "
|
||||
|
@ -1133,18 +1144,28 @@ static void usb_net_handle_control(USBDevice *dev, USBPacket *p,
|
|||
|
||||
static void usb_net_handle_statusin(USBNetState *s, USBPacket *p)
|
||||
{
|
||||
le32 buf[2];
|
||||
le32 rbuf[2];
|
||||
uint16_t ebuf[4];
|
||||
|
||||
if (p->iov.size < 8) {
|
||||
p->status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = cpu_to_le32(1);
|
||||
buf[1] = cpu_to_le32(0);
|
||||
usb_packet_copy(p, buf, 8);
|
||||
if (!s->rndis_resp.tqh_first) {
|
||||
p->status = USB_RET_NAK;
|
||||
if (is_rndis(s)) {
|
||||
rbuf[0] = cpu_to_le32(1);
|
||||
rbuf[1] = cpu_to_le32(0);
|
||||
usb_packet_copy(p, rbuf, 8);
|
||||
if (!s->rndis_resp.tqh_first) {
|
||||
p->status = USB_RET_NAK;
|
||||
}
|
||||
} else {
|
||||
ebuf[0] =
|
||||
cpu_to_be16(ClassInterfaceRequest | USB_CDC_NETWORK_CONNECTION);
|
||||
ebuf[1] = cpu_to_le16(s->connection);
|
||||
ebuf[2] = cpu_to_le16(1);
|
||||
ebuf[3] = cpu_to_le16(0);
|
||||
usb_packet_copy(p, ebuf, 8);
|
||||
}
|
||||
|
||||
#ifdef TRAFFIC_DEBUG
|
||||
|
@ -1204,7 +1225,7 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
|
|||
s->out_ptr += sz;
|
||||
|
||||
if (!is_rndis(s)) {
|
||||
if (p->iov.size < 64) {
|
||||
if (p->iov.size % 64 || p->iov.size == 0) {
|
||||
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr);
|
||||
s->out_ptr = 0;
|
||||
}
|
||||
|
@ -1317,6 +1338,7 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
|
|||
memcpy(in_buf, buf, size);
|
||||
s->in_len = total_size;
|
||||
s->in_ptr = 0;
|
||||
usb_wakeup(s->bulk_in, 0);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -1358,7 +1380,9 @@ static void usb_net_realize(USBDevice *dev, Error **errp)
|
|||
s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */;
|
||||
s->filter = 0;
|
||||
s->vendorid = 0x1234;
|
||||
s->connection = 1; /* Connected */
|
||||
s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
|
||||
s->bulk_in = usb_ep_get(dev, USB_TOKEN_IN, 2);
|
||||
|
||||
qemu_macaddr_default_if_unset(&s->conf.macaddr);
|
||||
s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
|
||||
|
|
|
@ -177,6 +177,37 @@ static const USBDesc desc = {
|
|||
.str = desc_strings,
|
||||
};
|
||||
|
||||
static void usb_msd_packet_complete(MSDState *s)
|
||||
{
|
||||
USBPacket *p = s->packet;
|
||||
|
||||
/*
|
||||
* Set s->packet to NULL before calling usb_packet_complete
|
||||
* because another request may be issued before
|
||||
* usb_packet_complete returns.
|
||||
*/
|
||||
trace_usb_msd_packet_complete();
|
||||
s->packet = NULL;
|
||||
usb_packet_complete(&s->dev, p);
|
||||
}
|
||||
|
||||
static void usb_msd_fatal_error(MSDState *s)
|
||||
{
|
||||
trace_usb_msd_fatal_error();
|
||||
|
||||
if (s->packet) {
|
||||
s->packet->status = USB_RET_STALL;
|
||||
usb_msd_packet_complete(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Guest messed up up device state with illegal requests. Go
|
||||
* ignore any requests until the guests resets the device (and
|
||||
* brings it into a known state that way).
|
||||
*/
|
||||
s->needs_reset = true;
|
||||
}
|
||||
|
||||
static void usb_msd_copy_data(MSDState *s, USBPacket *p)
|
||||
{
|
||||
uint32_t len;
|
||||
|
@ -208,24 +239,16 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p)
|
|||
memset(&s->csw, 0, sizeof(s->csw));
|
||||
}
|
||||
|
||||
static void usb_msd_packet_complete(MSDState *s)
|
||||
{
|
||||
USBPacket *p = s->packet;
|
||||
|
||||
/* Set s->packet to NULL before calling usb_packet_complete
|
||||
because another request may be issued before
|
||||
usb_packet_complete returns. */
|
||||
trace_usb_msd_packet_complete();
|
||||
s->packet = NULL;
|
||||
usb_packet_complete(&s->dev, p);
|
||||
}
|
||||
|
||||
void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
|
||||
{
|
||||
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
|
||||
USBPacket *p = s->packet;
|
||||
|
||||
assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
|
||||
if ((s->mode == USB_MSDM_DATAOUT) != (req->cmd.mode == SCSI_XFER_TO_DEV)) {
|
||||
usb_msd_fatal_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->scsi_len = len;
|
||||
s->scsi_off = 0;
|
||||
if (p) {
|
||||
|
@ -315,6 +338,8 @@ void usb_msd_handle_reset(USBDevice *dev)
|
|||
|
||||
memset(&s->csw, 0, sizeof(s->csw));
|
||||
s->mode = USB_MSDM_CBW;
|
||||
|
||||
s->needs_reset = false;
|
||||
}
|
||||
|
||||
static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
|
||||
|
@ -380,6 +405,11 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
|
|||
SCSIDevice *scsi_dev;
|
||||
uint32_t len;
|
||||
|
||||
if (s->needs_reset) {
|
||||
p->status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p->pid) {
|
||||
case USB_TOKEN_OUT:
|
||||
if (devep != 2)
|
||||
|
|
|
@ -571,6 +571,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
|
|||
|
||||
addr = ed->head & OHCI_DPTR_MASK;
|
||||
|
||||
if (addr == 0) {
|
||||
ohci_die(ohci);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ohci_read_iso_td(ohci, addr, &iso_td)) {
|
||||
trace_usb_ohci_iso_td_read_failed(addr);
|
||||
ohci_die(ohci);
|
||||
|
@ -859,6 +864,11 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
|||
int completion;
|
||||
|
||||
addr = ed->head & OHCI_DPTR_MASK;
|
||||
if (addr == 0) {
|
||||
ohci_die(ohci);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* See if this TD has already been submitted to the device. */
|
||||
completion = (addr == ohci->async_td);
|
||||
if (completion && !ohci->async_complete) {
|
||||
|
|
|
@ -463,6 +463,12 @@ static void xhci_mfwrap_timer(void *opaque)
|
|||
xhci_mfwrap_update(xhci);
|
||||
}
|
||||
|
||||
static void xhci_die(XHCIState *xhci)
|
||||
{
|
||||
xhci->usbsts |= USBSTS_HCE;
|
||||
DPRINTF("xhci: asserted controller error\n");
|
||||
}
|
||||
|
||||
static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high)
|
||||
{
|
||||
if (sizeof(dma_addr_t) == 4) {
|
||||
|
@ -488,7 +494,14 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr,
|
|||
|
||||
assert((len % sizeof(uint32_t)) == 0);
|
||||
|
||||
dma_memory_read(xhci->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_read(xhci->as, addr, buf, len,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
memset(buf, 0xff, len);
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < (len / sizeof(uint32_t)); i++) {
|
||||
buf[i] = le32_to_cpu(buf[i]);
|
||||
|
@ -496,7 +509,7 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr,
|
|||
}
|
||||
|
||||
static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
|
||||
uint32_t *buf, size_t len)
|
||||
const uint32_t *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
uint32_t tmp[5];
|
||||
|
@ -508,7 +521,13 @@ static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
|
|||
for (i = 0; i < n; i++) {
|
||||
tmp[i] = cpu_to_le32(buf[i]);
|
||||
}
|
||||
dma_memory_write(xhci->as, addr, tmp, len, MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_write(xhci->as, addr, tmp, len,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport)
|
||||
|
@ -593,12 +612,6 @@ static inline int xhci_running(XHCIState *xhci)
|
|||
return !(xhci->usbsts & USBSTS_HCH);
|
||||
}
|
||||
|
||||
static void xhci_die(XHCIState *xhci)
|
||||
{
|
||||
xhci->usbsts |= USBSTS_HCE;
|
||||
DPRINTF("xhci: asserted controller error\n");
|
||||
}
|
||||
|
||||
static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
|
||||
{
|
||||
XHCIInterrupter *intr = &xhci->intr[v];
|
||||
|
@ -619,7 +632,12 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
|
|||
ev_trb.status, ev_trb.control);
|
||||
|
||||
addr = intr->er_start + TRB_SIZE*intr->er_ep_idx;
|
||||
dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
xhci_die(xhci);
|
||||
}
|
||||
|
||||
intr->er_ep_idx++;
|
||||
if (intr->er_ep_idx >= intr->er_size) {
|
||||
|
@ -680,8 +698,12 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
|
|||
|
||||
while (1) {
|
||||
TRBType type;
|
||||
dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
trb->addr = ring->dequeue;
|
||||
trb->ccs = ring->ccs;
|
||||
le64_to_cpus(&trb->parameter);
|
||||
|
@ -798,8 +820,14 @@ static void xhci_er_reset(XHCIState *xhci, int v)
|
|||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
dma_memory_read(xhci->as, erstba, &seg, sizeof(seg),
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_read(xhci->as, erstba, &seg, sizeof(seg),
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
|
||||
le32_to_cpus(&seg.addr_low);
|
||||
le32_to_cpus(&seg.addr_high);
|
||||
le32_to_cpus(&seg.size);
|
||||
|
@ -992,7 +1020,9 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
|
|||
}
|
||||
sctx = epctx->pstreams + streamid;
|
||||
} else {
|
||||
FIXME("secondary streams not implemented yet");
|
||||
fprintf(stderr, "xhci: FIXME: secondary streams not implemented yet");
|
||||
*cc_error = CC_INVALID_STREAM_TYPE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sctx->sct == -1) {
|
||||
|
@ -2415,8 +2445,12 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
|
|||
/* TODO: actually implement real values here */
|
||||
bw_ctx[0] = 0;
|
||||
memset(&bw_ctx[1], 80, xhci->numports); /* 80% */
|
||||
dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory write failed!\n",
|
||||
__func__);
|
||||
return CC_TRB_ERROR;
|
||||
}
|
||||
|
||||
return CC_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -263,6 +263,7 @@ usb_msd_packet_complete(void) ""
|
|||
usb_msd_cmd_submit(unsigned lun, unsigned tag, unsigned flags, unsigned len, unsigned data_len) "lun %u, tag 0x%x, flags 0x%08x, len %d, data-len %d"
|
||||
usb_msd_cmd_complete(unsigned status, unsigned tag) "status %d, tag 0x%x"
|
||||
usb_msd_cmd_cancel(unsigned tag) "tag 0x%x"
|
||||
usb_msd_fatal_error(void) ""
|
||||
|
||||
# dev-uas.c
|
||||
usb_uas_reset(int addr) "dev %d"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue