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>
This commit is contained in:
parent
63095ab54c
commit
079d0b7f1e
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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];
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
21
hw/usb.c
21
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;
|
||||
}
|
||||
|
4
hw/usb.h
4
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);
|
||||
|
@ -214,7 +214,7 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
||||
int ret, fd, mode;
|
||||
int one = 1, shortpacket = 0, timeout = 50;
|
||||
sigset_t new_mask, old_mask;
|
||||
uint8_t devep = p->devep;
|
||||
uint8_t devep = p->ep->nr;
|
||||
|
||||
/* protect data transfers from SIGALRM signal */
|
||||
sigemptyset(&new_mask);
|
||||
|
44
usb-linux.c
44
usb-linux.c
@ -137,7 +137,7 @@ static int usb_host_usbfs_type(USBHostDevice *s, USBPacket *p)
|
||||
[USB_ENDPOINT_XFER_BULK] = USBDEVFS_URB_TYPE_BULK,
|
||||
[USB_ENDPOINT_XFER_INT] = USBDEVFS_URB_TYPE_INTERRUPT,
|
||||
};
|
||||
uint8_t type = usb_ep_get_type(&s->dev, p->pid, p->devep);
|
||||
uint8_t type = p->ep->type;
|
||||
assert(type < ARRAY_SIZE(usbfs));
|
||||
return usbfs[type];
|
||||
}
|
||||
@ -360,7 +360,7 @@ static void async_complete(void *opaque)
|
||||
break;
|
||||
|
||||
case -EPIPE:
|
||||
set_halt(s, p->pid, p->devep);
|
||||
set_halt(s, p->pid, p->ep->nr);
|
||||
p->result = USB_RET_STALL;
|
||||
break;
|
||||
|
||||
@ -733,16 +733,16 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
|
||||
int i, j, ret, max_packet_size, offset, len = 0;
|
||||
uint8_t *buf;
|
||||
|
||||
max_packet_size = usb_ep_get_max_packet_size(&s->dev, p->pid, p->devep);
|
||||
max_packet_size = p->ep->max_packet_size;
|
||||
if (max_packet_size == 0)
|
||||
return USB_RET_NAK;
|
||||
|
||||
aurb = get_iso_urb(s, p->pid, p->devep);
|
||||
aurb = get_iso_urb(s, p->pid, p->ep->nr);
|
||||
if (!aurb) {
|
||||
aurb = usb_host_alloc_iso(s, p->pid, p->devep);
|
||||
aurb = usb_host_alloc_iso(s, p->pid, p->ep->nr);
|
||||
}
|
||||
|
||||
i = get_iso_urb_idx(s, p->pid, p->devep);
|
||||
i = get_iso_urb_idx(s, p->pid, p->ep->nr);
|
||||
j = aurb[i].iso_frame_idx;
|
||||
if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
|
||||
if (in) {
|
||||
@ -769,7 +769,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
|
||||
}
|
||||
} else {
|
||||
len = p->iov.size;
|
||||
offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->devep);
|
||||
offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->ep->nr);
|
||||
|
||||
/* Check the frame fits */
|
||||
if (len > max_packet_size) {
|
||||
@ -781,27 +781,27 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
|
||||
usb_packet_copy(p, aurb[i].urb.buffer + offset, len);
|
||||
aurb[i].urb.iso_frame_desc[j].length = len;
|
||||
offset += len;
|
||||
set_iso_buffer_used(s, p->pid, p->devep, offset);
|
||||
set_iso_buffer_used(s, p->pid, p->ep->nr, offset);
|
||||
|
||||
/* Start the stream once we have buffered enough data */
|
||||
if (!is_iso_started(s, p->pid, p->devep) && i == 1 && j == 8) {
|
||||
set_iso_started(s, p->pid, p->devep);
|
||||
if (!is_iso_started(s, p->pid, p->ep->nr) && i == 1 && j == 8) {
|
||||
set_iso_started(s, p->pid, p->ep->nr);
|
||||
}
|
||||
}
|
||||
aurb[i].iso_frame_idx++;
|
||||
if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
|
||||
i = (i + 1) % s->iso_urb_count;
|
||||
set_iso_urb_idx(s, p->pid, p->devep, i);
|
||||
set_iso_urb_idx(s, p->pid, p->ep->nr, i);
|
||||
}
|
||||
} else {
|
||||
if (in) {
|
||||
set_iso_started(s, p->pid, p->devep);
|
||||
set_iso_started(s, p->pid, p->ep->nr);
|
||||
} else {
|
||||
DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (is_iso_started(s, p->pid, p->devep)) {
|
||||
if (is_iso_started(s, p->pid, p->ep->nr)) {
|
||||
/* (Re)-submit all fully consumed / filled urbs */
|
||||
for (i = 0; i < s->iso_urb_count; i++) {
|
||||
if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
|
||||
@ -821,7 +821,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
|
||||
break;
|
||||
}
|
||||
aurb[i].iso_frame_idx = -1;
|
||||
change_iso_inflight(s, p->pid, p->devep, 1);
|
||||
change_iso_inflight(s, p->pid, p->ep->nr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -840,20 +840,20 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
||||
|
||||
trace_usb_host_req_data(s->bus_num, s->addr,
|
||||
p->pid == USB_TOKEN_IN,
|
||||
p->devep, p->iov.size);
|
||||
p->ep->nr, p->iov.size);
|
||||
|
||||
if (!is_valid(s, p->pid, p->devep)) {
|
||||
if (!is_valid(s, p->pid, p->ep->nr)) {
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
|
||||
return USB_RET_NAK;
|
||||
}
|
||||
|
||||
if (p->pid == USB_TOKEN_IN) {
|
||||
ep = p->devep | 0x80;
|
||||
ep = p->ep->nr | 0x80;
|
||||
} else {
|
||||
ep = p->devep;
|
||||
ep = p->ep->nr;
|
||||
}
|
||||
|
||||
if (is_halted(s, p->pid, p->devep)) {
|
||||
if (is_halted(s, p->pid, p->ep->nr)) {
|
||||
unsigned int arg = ep;
|
||||
ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);
|
||||
if (ret < 0) {
|
||||
@ -861,10 +861,10 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
|
||||
trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
|
||||
return USB_RET_NAK;
|
||||
}
|
||||
clear_halt(s, p->pid, p->devep);
|
||||
clear_halt(s, p->pid, p->ep->nr);
|
||||
}
|
||||
|
||||
if (is_isoc(s, p->pid, p->devep)) {
|
||||
if (is_isoc(s, p->pid, p->ep->nr)) {
|
||||
return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
|
||||
}
|
||||
|
||||
@ -1057,7 +1057,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
|
||||
urb = &aurb->urb;
|
||||
|
||||
urb->type = USBDEVFS_URB_TYPE_CONTROL;
|
||||
urb->endpoint = p->devep;
|
||||
urb->endpoint = p->ep->nr;
|
||||
|
||||
urb->buffer = &dev->setup_buf;
|
||||
urb->buffer_length = length + 8;
|
||||
|
@ -610,7 +610,7 @@ static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
|
||||
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
|
||||
uint8_t ep;
|
||||
|
||||
ep = p->devep;
|
||||
ep = p->ep->nr;
|
||||
if (p->pid == USB_TOKEN_IN) {
|
||||
ep |= USB_DIR_IN;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user