usb: keep track of packet owner.
Keep track of the device which owns the usb packet for async processing. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
53aa8c0e2a
commit
4ff658fb6c
32
hw/usb.c
32
hw/usb.c
@ -313,6 +313,38 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(p->owner == NULL);
|
||||
ret = dev->info->handle_packet(dev, p);
|
||||
if (ret == USB_RET_ASYNC) {
|
||||
if (p->owner == NULL) {
|
||||
p->owner = dev;
|
||||
} else {
|
||||
/* We'll end up here when usb_handle_packet is called
|
||||
* recursively due to a hub being in the chain. Nothing
|
||||
* to do. Leave p->owner pointing to the device, not the
|
||||
* hub. */;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Notify the controller that an async packet is complete. This should only
|
||||
be called for packets previously deferred by returning USB_RET_ASYNC from
|
||||
handle_packet. */
|
||||
void usb_packet_complete(USBDevice *dev, USBPacket *p)
|
||||
{
|
||||
/* Note: p->owner != dev is possible in case dev is a hub */
|
||||
assert(p->owner != NULL);
|
||||
dev->port->ops->complete(dev, p);
|
||||
p->owner = NULL;
|
||||
}
|
||||
|
||||
/* Cancel an active packet. The packed must have been deferred by
|
||||
returning USB_RET_ASYNC from handle_packet, and not yet
|
||||
completed. */
|
||||
void usb_cancel_packet(USBPacket * p)
|
||||
{
|
||||
assert(p->owner != NULL);
|
||||
p->cancel_cb(p, p->cancel_opaque);
|
||||
p->owner = NULL;
|
||||
}
|
||||
|
18
hw/usb.h
18
hw/usb.h
@ -262,11 +262,14 @@ struct USBPacket {
|
||||
uint8_t *data;
|
||||
int len;
|
||||
/* Internal use by the USB layer. */
|
||||
USBDevice *owner;
|
||||
USBCallback *cancel_cb;
|
||||
void *cancel_opaque;
|
||||
};
|
||||
|
||||
int usb_handle_packet(USBDevice *dev, USBPacket *p);
|
||||
void usb_packet_complete(USBDevice *dev, USBPacket *p);
|
||||
void usb_cancel_packet(USBPacket * p);
|
||||
|
||||
/* Defer completion of a USB packet. The hadle_packet routine should then
|
||||
return USB_RET_ASYNC. Packets that complete immediately (before
|
||||
@ -278,21 +281,6 @@ static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel,
|
||||
p->cancel_opaque = opaque;
|
||||
}
|
||||
|
||||
/* Notify the controller that an async packet is complete. This should only
|
||||
be called for packets previously deferred with usb_defer_packet, and
|
||||
should never be called from within handle_packet. */
|
||||
static inline void usb_packet_complete(USBDevice *dev, USBPacket *p)
|
||||
{
|
||||
dev->port->ops->complete(dev, p);
|
||||
}
|
||||
|
||||
/* Cancel an active packet. The packed must have been deferred with
|
||||
usb_defer_packet, and not yet completed. */
|
||||
static inline void usb_cancel_packet(USBPacket * p)
|
||||
{
|
||||
p->cancel_cb(p, p->cancel_opaque);
|
||||
}
|
||||
|
||||
void usb_attach(USBPort *port, USBDevice *dev);
|
||||
void usb_wakeup(USBDevice *dev);
|
||||
int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
|
||||
|
Loading…
Reference in New Issue
Block a user