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:
Gerd Hoffmann 2011-05-12 13:48:13 +02:00
parent 53aa8c0e2a
commit 4ff658fb6c
2 changed files with 35 additions and 15 deletions

View File

@ -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;
}

View File

@ -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);