From 079d0b7f1eedcc634c371fe05b617fdc55c8b762 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 12 Jan 2012 13:23:01 +0100 Subject: 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 --- hw/usb-audio.c | 4 ++-- hw/usb-bt.c | 4 ++-- hw/usb-ccid.c | 2 +- hw/usb-ehci.c | 15 +++++++++------ hw/usb-hid.c | 2 +- hw/usb-hub.c | 2 +- hw/usb-msd.c | 2 +- hw/usb-musb.c | 7 ++++--- hw/usb-net.c | 6 +++--- hw/usb-ohci.c | 16 ++++++++-------- hw/usb-serial.c | 2 +- hw/usb-uhci.c | 13 +++++++------ hw/usb-wacom.c | 2 +- hw/usb-xhci.c | 27 +++++++++++++-------------- hw/usb.c | 21 ++++++++++++--------- hw/usb.h | 4 +--- 16 files changed, 67 insertions(+), 62 deletions(-) (limited to 'hw') 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); -- cgit v1.2.3