usb: link packets to endpoints not devices
Add USBEndpoint for the control endpoint to USBDevices. Link async packets to the USBEndpoint instead of the USBDevice. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
f003397ce9
commit
25d5de7d81
@ -715,7 +715,8 @@ static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev)
|
|||||||
EHCIQueue *q, *tmp;
|
EHCIQueue *q, *tmp;
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
|
QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
|
||||||
if (q->packet.owner != dev) {
|
if (q->packet.owner == NULL ||
|
||||||
|
q->packet.owner->dev != dev) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ehci_free_queue(q);
|
ehci_free_queue(q);
|
||||||
|
@ -812,7 +812,8 @@ static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
|
|||||||
|
|
||||||
for (ep = 0; ep < 16; ep++) {
|
for (ep = 0; ep < 16; ep++) {
|
||||||
for (dir = 0; dir < 2; dir++) {
|
for (dir = 0; dir < 2; dir++) {
|
||||||
if (s->ep[ep].packey[dir].p.owner != dev) {
|
if (s->ep[ep].packey[dir].p.owner == NULL ||
|
||||||
|
s->ep[ep].packey[dir].p.owner->dev != dev) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
usb_cancel_packet(&s->ep[ep].packey[dir].p);
|
usb_cancel_packet(&s->ep[ep].packey[dir].p);
|
||||||
|
@ -1707,7 +1707,9 @@ static void ohci_mem_write(void *opaque,
|
|||||||
|
|
||||||
static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
|
static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
|
||||||
{
|
{
|
||||||
if (ohci->async_td && ohci->usb_packet.owner == dev) {
|
if (ohci->async_td &&
|
||||||
|
ohci->usb_packet.owner != NULL &&
|
||||||
|
ohci->usb_packet.owner->dev == dev) {
|
||||||
usb_cancel_packet(&ohci->usb_packet);
|
usb_cancel_packet(&ohci->usb_packet);
|
||||||
ohci->async_td = 0;
|
ohci->async_td = 0;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,8 @@ static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev)
|
|||||||
UHCIAsync *curr, *n;
|
UHCIAsync *curr, *n;
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
|
QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
|
||||||
if (curr->packet.owner != dev) {
|
if (curr->packet.owner == NULL ||
|
||||||
|
curr->packet.owner->dev != dev) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uhci_async_unlink(s, curr);
|
uhci_async_unlink(s, curr);
|
||||||
|
12
hw/usb.c
12
hw/usb.c
@ -329,7 +329,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
|
|||||||
ret = dev->info->handle_packet(dev, p);
|
ret = dev->info->handle_packet(dev, p);
|
||||||
if (ret == USB_RET_ASYNC) {
|
if (ret == USB_RET_ASYNC) {
|
||||||
if (p->owner == NULL) {
|
if (p->owner == NULL) {
|
||||||
p->owner = dev;
|
p->owner = usb_ep_get(dev, p->pid, p->devep);
|
||||||
} else {
|
} else {
|
||||||
/* We'll end up here when usb_handle_packet is called
|
/* We'll end up here when usb_handle_packet is called
|
||||||
* recursively due to a hub being in the chain. Nothing
|
* recursively due to a hub being in the chain. Nothing
|
||||||
@ -357,7 +357,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
|
|||||||
void usb_cancel_packet(USBPacket * p)
|
void usb_cancel_packet(USBPacket * p)
|
||||||
{
|
{
|
||||||
assert(p->owner != NULL);
|
assert(p->owner != NULL);
|
||||||
p->owner->info->cancel_packet(p->owner, p);
|
p->owner->dev->info->cancel_packet(p->owner->dev, p);
|
||||||
p->owner = NULL;
|
p->owner = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,11 +419,16 @@ void usb_ep_init(USBDevice *dev)
|
|||||||
{
|
{
|
||||||
int ep;
|
int ep;
|
||||||
|
|
||||||
|
dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
|
||||||
|
dev->ep_ctl.ifnum = 0;
|
||||||
|
dev->ep_ctl.dev = dev;
|
||||||
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
|
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
|
||||||
dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
|
dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
|
||||||
dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
|
dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
|
||||||
dev->ep_in[ep].ifnum = 0;
|
dev->ep_in[ep].ifnum = 0;
|
||||||
dev->ep_out[ep].ifnum = 0;
|
dev->ep_out[ep].ifnum = 0;
|
||||||
|
dev->ep_in[ep].dev = dev;
|
||||||
|
dev->ep_out[ep].dev = dev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +477,9 @@ void usb_ep_dump(USBDevice *dev)
|
|||||||
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
|
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 = pid == USB_TOKEN_IN ? dev->ep_in : dev->ep_out;
|
||||||
|
if (ep == 0) {
|
||||||
|
return &dev->ep_ctl;
|
||||||
|
}
|
||||||
assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
|
assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
|
||||||
assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
|
assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
|
||||||
return eps + ep - 1;
|
return eps + ep - 1;
|
||||||
|
4
hw/usb.h
4
hw/usb.h
@ -177,6 +177,7 @@ struct USBEndpoint {
|
|||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t ifnum;
|
uint8_t ifnum;
|
||||||
int max_packet_size;
|
int max_packet_size;
|
||||||
|
USBDevice *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* definition of a USB device */
|
/* definition of a USB device */
|
||||||
@ -204,6 +205,7 @@ struct USBDevice {
|
|||||||
int32_t setup_len;
|
int32_t setup_len;
|
||||||
int32_t setup_index;
|
int32_t setup_index;
|
||||||
|
|
||||||
|
USBEndpoint ep_ctl;
|
||||||
USBEndpoint ep_in[USB_MAX_ENDPOINTS];
|
USBEndpoint ep_in[USB_MAX_ENDPOINTS];
|
||||||
USBEndpoint ep_out[USB_MAX_ENDPOINTS];
|
USBEndpoint ep_out[USB_MAX_ENDPOINTS];
|
||||||
|
|
||||||
@ -317,7 +319,7 @@ struct USBPacket {
|
|||||||
QEMUIOVector iov;
|
QEMUIOVector iov;
|
||||||
int result; /* transfer length or USB_RET_* status code */
|
int result; /* transfer length or USB_RET_* status code */
|
||||||
/* Internal use by the USB layer. */
|
/* Internal use by the USB layer. */
|
||||||
USBDevice *owner;
|
USBEndpoint *owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
void usb_packet_init(USBPacket *p);
|
void usb_packet_init(USBPacket *p);
|
||||||
|
Loading…
Reference in New Issue
Block a user