aboutsummaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2012-01-12 13:23:01 +0100
committerGerd Hoffmann <kraxel@redhat.com>2012-02-10 11:31:57 +0100
commit079d0b7f1eedcc634c371fe05b617fdc55c8b762 (patch)
tree60ee42f36b295edb49fcb62af5912f769efa9991 /hw
parent63095ab54c1ce554b1fc825fc678394ccb129e5b (diff)
usb: Set USBEndpoint in usb_packet_setup().
With the separation of the device lookup (via usb_find_device) and packet processing we can lookup device and endpoint before setting up the usb packet. So we can initialize USBPacket->ep early and keep it valid for the whole lifecycle of the USBPacket. Also the devaddr and devep fields are not needed any more. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/usb-audio.c4
-rw-r--r--hw/usb-bt.c4
-rw-r--r--hw/usb-ccid.c2
-rw-r--r--hw/usb-ehci.c15
-rw-r--r--hw/usb-hid.c2
-rw-r--r--hw/usb-hub.c2
-rw-r--r--hw/usb-msd.c2
-rw-r--r--hw/usb-musb.c7
-rw-r--r--hw/usb-net.c6
-rw-r--r--hw/usb-ohci.c16
-rw-r--r--hw/usb-serial.c2
-rw-r--r--hw/usb-uhci.c13
-rw-r--r--hw/usb-wacom.c2
-rw-r--r--hw/usb-xhci.c27
-rw-r--r--hw/usb.c21
-rw-r--r--hw/usb.h4
16 files changed, 67 insertions, 62 deletions
diff --git a/hw/usb-audio.c b/hw/usb-audio.c
index a4ea0b0fe..c60aaff26 100644
--- a/hw/usb-audio.c
+++ b/hw/usb-audio.c
@@ -607,7 +607,7 @@ static int usb_audio_handle_data(USBDevice *dev, USBPacket *p)
switch (p->pid) {
case USB_TOKEN_OUT:
- switch (p->devep) {
+ switch (p->ep->nr) {
case 1:
ret = usb_audio_handle_dataout(s, p);
break;
@@ -624,7 +624,7 @@ fail:
if (ret == USB_RET_STALL && s->debug) {
fprintf(stderr, "usb-audio: failed data transaction: "
"pid 0x%x ep 0x%x len 0x%zx\n",
- p->pid, p->devep, p->iov.size);
+ p->pid, p->ep->nr, p->iov.size);
}
return ret;
}
diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index 58b247ef4..ea6a5a0c0 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -423,7 +423,7 @@ static int usb_bt_handle_data(USBDevice *dev, USBPacket *p)
switch (p->pid) {
case USB_TOKEN_IN:
- switch (p->devep & 0xf) {
+ switch (p->ep->nr) {
case USB_EVT_EP:
ret = usb_bt_fifo_dequeue(&s->evt, p);
break;
@@ -442,7 +442,7 @@ static int usb_bt_handle_data(USBDevice *dev, USBPacket *p)
break;
case USB_TOKEN_OUT:
- switch (p->devep & 0xf) {
+ switch (p->ep->nr) {
case USB_ACL_EP:
usb_bt_fifo_out_enqueue(s, &s->outacl, s->hci->acl_send,
usb_bt_hci_acl_complete, p);
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index b3bcfeb4a..8c0c7178b 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -995,7 +995,7 @@ static int ccid_handle_data(USBDevice *dev, USBPacket *p)
break;
case USB_TOKEN_IN:
- switch (p->devep & 0xf) {
+ switch (p->ep->nr) {
case CCID_BULK_IN_EP:
if (!p->iov.size) {
ret = USB_RET_NAK;
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index f0213adec..6c01ca93a 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -1357,6 +1357,7 @@ err:
static int ehci_execute(EHCIQueue *q)
{
USBDevice *dev;
+ USBEndpoint *ep;
int ret;
int endp;
int devadr;
@@ -1387,13 +1388,13 @@ static int ehci_execute(EHCIQueue *q)
endp = get_field(q->qh.epchar, QH_EPCHAR_EP);
devadr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR);
- ret = USB_RET_NODEV;
+ /* TODO: associating device with ehci port */
+ dev = ehci_find_device(q->ehci, devadr);
+ ep = usb_ep_get(dev, q->pid, endp);
- usb_packet_setup(&q->packet, q->pid, devadr, endp);
+ usb_packet_setup(&q->packet, q->pid, ep);
usb_packet_map(&q->packet, &q->sgl);
- // TO-DO: associating device with ehci port
- dev = ehci_find_device(q->ehci, q->packet.devaddr);
ret = usb_handle_packet(dev, &q->packet);
DPRINTF("submit: qh %x next %x qtd %x pid %x len %zd "
"(total %d) endp %x ret %d\n",
@@ -1415,6 +1416,7 @@ static int ehci_process_itd(EHCIState *ehci,
EHCIitd *itd)
{
USBDevice *dev;
+ USBEndpoint *ep;
int ret;
uint32_t i, len, pid, dir, devaddr, endp;
uint32_t pg, off, ptr1, ptr2, max, mult;
@@ -1454,10 +1456,11 @@ static int ehci_process_itd(EHCIState *ehci,
pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT;
- usb_packet_setup(&ehci->ipacket, pid, devaddr, endp);
+ dev = ehci_find_device(ehci, devaddr);
+ ep = usb_ep_get(dev, pid, endp);
+ usb_packet_setup(&ehci->ipacket, pid, ep);
usb_packet_map(&ehci->ipacket, &ehci->isgl);
- dev = ehci_find_device(ehci, ehci->ipacket.devaddr);
ret = usb_handle_packet(dev, &ehci->ipacket);
usb_packet_unmap(&ehci->ipacket);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index c6489800f..4d00c2813 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -463,7 +463,7 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
switch (p->pid) {
case USB_TOKEN_IN:
- if (p->devep == 1) {
+ if (p->ep->nr == 1) {
int64_t curtime = qemu_get_clock_ns(vm_clock);
if (!hid_has_events(hs) &&
(!hs->idle || hs->next_idle_clock - curtime > 0)) {
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 22562565c..940e211d1 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -416,7 +416,7 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
switch(p->pid) {
case USB_TOKEN_IN:
- if (p->devep == 1) {
+ if (p->ep->nr == 1) {
USBHubPort *port;
unsigned int status;
uint8_t buf[4];
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index c34cad55f..aac1181fe 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -341,7 +341,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
uint32_t tag;
int ret = 0;
struct usb_msd_cbw cbw;
- uint8_t devep = p->devep;
+ uint8_t devep = p->ep->nr;
switch (p->pid) {
case USB_TOKEN_OUT:
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index f4e52f16c..820907a9a 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -606,6 +606,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
int epnum, int pid, int len, USBCallback cb, int dir)
{
USBDevice *dev;
+ USBEndpoint *uep;
int ret;
int idx = epnum && dir;
int ttype;
@@ -623,13 +624,13 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
ep->delayed_cb[dir] = cb;
/* A wild guess on the FADDR semantics... */
- usb_packet_setup(&ep->packey[dir].p, pid, ep->faddr[idx],
- ep->type[idx] & 0xf);
+ dev = usb_find_device(&s->port, ep->faddr[idx]);
+ uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
+ usb_packet_setup(&ep->packey[dir].p, pid, uep);
usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
ep->packey[dir].ep = ep;
ep->packey[dir].dir = dir;
- dev = usb_find_device(&s->port, ep->packey[dir].p.devaddr);
ret = usb_handle_packet(dev, &ep->packey[dir].p);
if (ret == USB_RET_ASYNC) {
diff --git a/hw/usb-net.c b/hw/usb-net.c
index f00e85475..72c9185ba 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1210,7 +1210,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
switch(p->pid) {
case USB_TOKEN_IN:
- switch (p->devep) {
+ switch (p->ep->nr) {
case 1:
ret = usb_net_handle_statusin(s, p);
break;
@@ -1225,7 +1225,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
break;
case USB_TOKEN_OUT:
- switch (p->devep) {
+ switch (p->ep->nr) {
case 2:
ret = usb_net_handle_dataout(s, p);
break;
@@ -1243,7 +1243,7 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
if (ret == USB_RET_STALL)
fprintf(stderr, "usbnet: failed data transaction: "
"pid 0x%x ep 0x%x len 0x%zx\n",
- p->pid, p->devep, p->iov.size);
+ p->pid, p->ep->nr, p->iov.size);
return ret;
}
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 8a8f3bc85..ba7231f2d 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -657,6 +657,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
int ret;
int i;
USBDevice *dev;
+ USBEndpoint *ep;
struct ohci_iso_td iso_td;
uint32_t addr;
uint16_t starting_frame;
@@ -796,11 +797,10 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
if (completion) {
ret = ohci->usb_packet.result;
} else {
- usb_packet_setup(&ohci->usb_packet, pid,
- OHCI_BM(ed->flags, ED_FA),
- OHCI_BM(ed->flags, ED_EN));
+ dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
+ ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
+ usb_packet_setup(&ohci->usb_packet, pid, ep);
usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len);
- dev = ohci_find_device(ohci, ohci->usb_packet.devaddr);
ret = usb_handle_packet(dev, &ohci->usb_packet);
if (ret == USB_RET_ASYNC) {
return 1;
@@ -889,6 +889,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
int ret;
int i;
USBDevice *dev;
+ USBEndpoint *ep;
struct ohci_td td;
uint32_t addr;
int flag_r;
@@ -992,11 +993,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
#endif
return 1;
}
- usb_packet_setup(&ohci->usb_packet, pid,
- OHCI_BM(ed->flags, ED_FA),
- OHCI_BM(ed->flags, ED_EN));
+ dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
+ ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
+ usb_packet_setup(&ohci->usb_packet, pid, ep);
usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen);
- dev = ohci_find_device(ohci, ohci->usb_packet.devaddr);
ret = usb_handle_packet(dev, &ohci->usb_packet);
#ifdef DEBUG_PACKET
DPRINTF("ret=%d\n", ret);
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index cf83cf21d..1cfb551a0 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -353,7 +353,7 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
{
USBSerialState *s = (USBSerialState *)dev;
int i, ret = 0;
- uint8_t devep = p->devep;
+ uint8_t devep = p->ep->nr;
struct iovec *iov;
uint8_t header[2];
int first_len, len;
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index ef0814570..ab64be604 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -761,6 +761,8 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
int len = 0, max_len;
uint8_t pid, isoc;
uint32_t token;
+ USBDevice *dev;
+ USBEndpoint *ep;
/* Is active ? */
if (!(td->ctrl & TD_CTRL_ACTIVE))
@@ -805,23 +807,22 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
max_len = ((td->token >> 21) + 1) & 0x7ff;
pid = td->token & 0xff;
- usb_packet_setup(&async->packet, pid, (td->token >> 8) & 0x7f,
- (td->token >> 15) & 0xf);
+ dev = uhci_find_device(s, (td->token >> 8) & 0x7f);
+ ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
+ usb_packet_setup(&async->packet, pid, ep);
qemu_sglist_add(&async->sgl, td->buffer, max_len);
usb_packet_map(&async->packet, &async->sgl);
switch(pid) {
case USB_TOKEN_OUT:
case USB_TOKEN_SETUP:
- len = usb_handle_packet(uhci_find_device(s, async->packet.devaddr),
- &async->packet);
+ len = usb_handle_packet(dev, &async->packet);
if (len >= 0)
len = max_len;
break;
case USB_TOKEN_IN:
- len = usb_handle_packet(uhci_find_device(s, async->packet.devaddr),
- &async->packet);
+ len = usb_handle_packet(dev, &async->packet);
break;
default:
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index 46b8010f6..73ff241d4 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -306,7 +306,7 @@ static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p)
switch (p->pid) {
case USB_TOKEN_IN:
- if (p->devep == 1) {
+ if (p->ep->nr == 1) {
if (!(s->changed || s->idle))
return USB_RET_NAK;
s->changed = 0;
diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c
index aa236c9a3..b274b806d 100644
--- a/hw/usb-xhci.c
+++ b/hw/usb-xhci.c
@@ -1336,15 +1336,17 @@ static int xhci_hle_control(XHCIState *xhci, XHCITransfer *xfer,
}
#endif
-static int xhci_setup_packet(XHCITransfer *xfer, XHCIPort *port, int ep)
+static int xhci_setup_packet(XHCITransfer *xfer, XHCIPort *port, USBDevice *dev)
{
- usb_packet_setup(&xfer->packet,
- xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT,
- xfer->xhci->slots[xfer->slotid-1].devaddr,
- ep & 0x7f);
+ USBEndpoint *ep;
+ int dir;
+
+ dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT;
+ ep = usb_ep_get(dev, dir, xfer->epid >> 1);
+ usb_packet_setup(&xfer->packet, dir, ep);
usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length);
DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n",
- xfer->packet.pid, xfer->packet.devaddr, xfer->packet.devep);
+ xfer->packet.pid, dev->addr, ep->nr);
return 0;
}
@@ -1462,7 +1464,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
xfer->in_xfer = bmRequestType & USB_DIR_IN;
xfer->iso_xfer = false;
- xhci_setup_packet(xfer, port, 0);
+ xhci_setup_packet(xfer, port, dev);
if (!xfer->in_xfer) {
xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0);
}
@@ -1484,12 +1486,8 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
int ret;
DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid);
- uint8_t ep = xfer->epid>>1;
xfer->in_xfer = epctx->type>>2;
- if (xfer->in_xfer) {
- ep |= 0x80;
- }
if (xfer->data && xfer->data_alloced < xfer->data_length) {
xfer->data_alloced = 0;
@@ -1517,7 +1515,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
return -1;
}
- xhci_setup_packet(xfer, port, ep);
+ xhci_setup_packet(xfer, port, dev);
switch(epctx->type) {
case ET_INTR_OUT:
@@ -1530,8 +1528,9 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
FIXME();
break;
default:
- fprintf(stderr, "xhci: unknown or unhandled EP type %d (ep %02x)\n",
- epctx->type, ep);
+ fprintf(stderr, "xhci: unknown or unhandled EP "
+ "(type %d, in %d, ep %02x)\n",
+ epctx->type, xfer->in_xfer, xfer->epid);
return -1;
}
diff --git a/hw/usb.c b/hw/usb.c
index 8bd1222cc..240f24b25 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -140,7 +140,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
int request, value, index;
int ret = 0;
- assert(p->devep == 0);
+ assert(p->ep->nr == 0);
request = (s->setup_buf[0] << 8) | s->setup_buf[1];
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
@@ -186,7 +186,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
static int do_token_out(USBDevice *s, USBPacket *p)
{
- assert(p->devep == 0);
+ assert(p->ep->nr == 0);
switch(s->setup_state) {
case SETUP_STATE_ACK:
@@ -289,11 +289,11 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
if (dev == NULL) {
return USB_RET_NODEV;
}
- assert(dev->addr == p->devaddr);
+ assert(dev == p->ep->dev);
assert(dev->state == USB_STATE_DEFAULT);
assert(p->state == USB_PACKET_SETUP);
- if (p->devep == 0) {
+ if (p->ep->nr == 0) {
/* control pipe */
switch (p->pid) {
case USB_TOKEN_SETUP:
@@ -315,7 +315,6 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
}
if (ret == USB_RET_ASYNC) {
- p->ep = usb_ep_get(dev, p->pid, p->devep);
p->state = USB_PACKET_ASYNC;
}
return ret;
@@ -347,13 +346,12 @@ void usb_packet_init(USBPacket *p)
qemu_iovec_init(&p->iov, 1);
}
-void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep)
+void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep)
{
assert(!usb_packet_is_inflight(p));
p->state = USB_PACKET_SETUP;
p->pid = pid;
- p->devaddr = addr;
- p->devep = ep;
+ p->ep = ep;
p->result = 0;
qemu_iovec_reset(&p->iov);
}
@@ -464,7 +462,12 @@ void usb_ep_dump(USBDevice *dev)
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
{
- struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev->ep_in : dev->ep_out;
+ struct USBEndpoint *eps;
+
+ if (dev == NULL) {
+ return NULL;
+ }
+ eps = (pid == USB_TOKEN_IN) ? dev->ep_in : dev->ep_out;
if (ep == 0) {
return &dev->ep_ctl;
}
diff --git a/hw/usb.h b/hw/usb.h
index 1e629af68..a80fe8f7f 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -321,8 +321,6 @@ typedef enum USBPacketState {
struct USBPacket {
/* Data fields for use by the driver. */
int pid;
- uint8_t devaddr;
- uint8_t devep;
USBEndpoint *ep;
QEMUIOVector iov;
int result; /* transfer length or USB_RET_* status code */
@@ -331,7 +329,7 @@ struct USBPacket {
};
void usb_packet_init(USBPacket *p);
-void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep);
+void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep);
void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
void usb_packet_unmap(USBPacket *p);