diff options
-rw-r--r-- | hw/usb-bus.c | 9 | ||||
-rw-r--r-- | hw/usb.c | 13 | ||||
-rw-r--r-- | hw/usb.h | 10 |
3 files changed, 32 insertions, 0 deletions
diff --git a/hw/usb-bus.c b/hw/usb-bus.c index b753834584..5c05ed5806 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -74,6 +74,15 @@ static int usb_device_init(USBDevice *dev) return 0; } +USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr) +{ + USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev); + if (klass->find_device) { + return klass->find_device(dev, addr); + } + return NULL; +} + static void usb_device_handle_destroy(USBDevice *dev) { USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev); @@ -295,6 +295,19 @@ int set_usb_string(uint8_t *buf, const char *str) return q - buf; } +USBDevice *usb_find_device(USBPort *port, uint8_t addr) +{ + USBDevice *dev = port->dev; + + if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT) { + return NULL; + } + if (dev->addr == addr) { + return dev; + } + return usb_device_find_device(dev, addr); +} + /* Hand over a packet to a device for processing. Return value USB_RET_ASYNC indicates the processing isn't finished yet, the driver will call usb_packet_complete() when done processing it. */ @@ -229,6 +229,12 @@ typedef struct USBDeviceClass { int (*init)(USBDevice *dev); /* + * Walk (enabled) downstream ports, check for a matching device. + * Only hubs implement this. + */ + USBDevice *(*find_device)(USBDevice *dev, uint8_t addr); + + /* * Process USB packet. * Called by the HC (Host Controller). * @@ -332,6 +338,8 @@ void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes); void usb_packet_skip(USBPacket *p, size_t bytes); void usb_packet_cleanup(USBPacket *p); +USBDevice *usb_find_device(USBPort *port, uint8_t addr); + int usb_handle_packet(USBDevice *dev, USBPacket *p); void usb_packet_complete(USBDevice *dev, USBPacket *p); void usb_cancel_packet(USBPacket * p); @@ -446,6 +454,8 @@ extern const VMStateDescription vmstate_usb_device; .offset = vmstate_offset_value(_state, _field, USBDevice), \ } +USBDevice *usb_device_find_device(USBDevice *dev, uint8_t addr); + int usb_device_handle_packet(USBDevice *dev, USBPacket *p); void usb_device_cancel_packet(USBDevice *dev, USBPacket *p); |