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;
|
int ret;
|
||||||
|
|
||||||
|
assert(p->owner == NULL);
|
||||||
ret = dev->info->handle_packet(dev, p);
|
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;
|
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;
|
uint8_t *data;
|
||||||
int len;
|
int len;
|
||||||
/* Internal use by the USB layer. */
|
/* Internal use by the USB layer. */
|
||||||
|
USBDevice *owner;
|
||||||
USBCallback *cancel_cb;
|
USBCallback *cancel_cb;
|
||||||
void *cancel_opaque;
|
void *cancel_opaque;
|
||||||
};
|
};
|
||||||
|
|
||||||
int usb_handle_packet(USBDevice *dev, USBPacket *p);
|
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
|
/* Defer completion of a USB packet. The hadle_packet routine should then
|
||||||
return USB_RET_ASYNC. Packets that complete immediately (before
|
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;
|
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_attach(USBPort *port, USBDevice *dev);
|
||||||
void usb_wakeup(USBDevice *dev);
|
void usb_wakeup(USBDevice *dev);
|
||||||
int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
|
int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
|
||||||
|
Loading…
Reference in New Issue
Block a user