uhci: remove buffer

Map guest memory and pass on a direct pointer instead of copying
the bits to a indirect buffer.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2011-07-13 15:37:29 +02:00
parent 29c74f762b
commit df5e66eefb
1 changed files with 7 additions and 8 deletions

View File

@ -31,6 +31,7 @@
#include "qemu-timer.h" #include "qemu-timer.h"
#include "usb-uhci.h" #include "usb-uhci.h"
#include "iov.h" #include "iov.h"
#include "dma.h"
//#define DEBUG //#define DEBUG
//#define DEBUG_DUMP_DATA //#define DEBUG_DUMP_DATA
@ -111,6 +112,7 @@ typedef struct UHCIState UHCIState;
*/ */
typedef struct UHCIAsync { typedef struct UHCIAsync {
USBPacket packet; USBPacket packet;
QEMUSGList sgl;
UHCIState *uhci; UHCIState *uhci;
QTAILQ_ENTRY(UHCIAsync) next; QTAILQ_ENTRY(UHCIAsync) next;
uint32_t td; uint32_t td;
@ -118,7 +120,6 @@ typedef struct UHCIAsync {
int8_t valid; int8_t valid;
uint8_t isoc; uint8_t isoc;
uint8_t done; uint8_t done;
uint8_t buffer[2048];
} UHCIAsync; } UHCIAsync;
typedef struct UHCIPort { typedef struct UHCIPort {
@ -176,6 +177,7 @@ static UHCIAsync *uhci_async_alloc(UHCIState *s)
async->done = 0; async->done = 0;
async->isoc = 0; async->isoc = 0;
usb_packet_init(&async->packet); usb_packet_init(&async->packet);
qemu_sglist_init(&async->sgl, 1);
return async; return async;
} }
@ -183,6 +185,7 @@ static UHCIAsync *uhci_async_alloc(UHCIState *s)
static void uhci_async_free(UHCIState *s, UHCIAsync *async) static void uhci_async_free(UHCIState *s, UHCIAsync *async)
{ {
usb_packet_cleanup(&async->packet); usb_packet_cleanup(&async->packet);
qemu_sglist_destroy(&async->sgl);
qemu_free(async); qemu_free(async);
} }
@ -706,11 +709,6 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
goto out; goto out;
} }
if (len > 0) {
/* write the data back */
cpu_physical_memory_write(td->buffer, async->buffer, len);
}
if ((td->ctrl & TD_CTRL_SPD) && len < max_len) { if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
*int_mask |= 0x02; *int_mask |= 0x02;
/* short packet: do not update QH */ /* short packet: do not update QH */
@ -827,12 +825,12 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
usb_packet_setup(&async->packet, pid, (td->token >> 8) & 0x7f, usb_packet_setup(&async->packet, pid, (td->token >> 8) & 0x7f,
(td->token >> 15) & 0xf); (td->token >> 15) & 0xf);
usb_packet_addbuf(&async->packet, async->buffer, max_len); qemu_sglist_add(&async->sgl, td->buffer, max_len);
usb_packet_map(&async->packet, &async->sgl);
switch(pid) { switch(pid) {
case USB_TOKEN_OUT: case USB_TOKEN_OUT:
case USB_TOKEN_SETUP: case USB_TOKEN_SETUP:
cpu_physical_memory_read(td->buffer, async->buffer, max_len);
len = uhci_broadcast_packet(s, &async->packet); len = uhci_broadcast_packet(s, &async->packet);
if (len >= 0) if (len >= 0)
len = max_len; len = max_len;
@ -859,6 +857,7 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
done: done:
len = uhci_complete_td(s, td, async, int_mask); len = uhci_complete_td(s, td, async, int_mask);
usb_packet_unmap(&async->packet);
uhci_async_free(s, async); uhci_async_free(s, async);
return len; return len;
} }