usb: USBPacket: add status, rename owner -> ep
Add enum to track the status of USBPackets, use that instead of the owner pointer to figure whenever a usb packet is currently in flight or not. Add some more packet status sanity checks. Also rename the USBEndpoint pointer from "owner" to "ep". Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
		
							parent
							
								
									1977f93dac
								
							
						
					
					
						commit
						f53c398aa6
					
				@ -715,8 +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 == NULL ||
 | 
					        if (!usb_packet_is_inflight(&q->packet) ||
 | 
				
			||||||
            q->packet.owner->dev != dev) {
 | 
					            q->packet.ep->dev != dev) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ehci_free_queue(q);
 | 
					        ehci_free_queue(q);
 | 
				
			||||||
 | 
				
			|||||||
@ -811,8 +811,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 == NULL ||
 | 
					            if (!usb_packet_is_inflight(&s->ep[ep].packey[dir].p) ||
 | 
				
			||||||
                s->ep[ep].packey[dir].p.owner->dev != dev) {
 | 
					                s->ep[ep].packey[dir].p.ep->dev != dev) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            usb_cancel_packet(&s->ep[ep].packey[dir].p);
 | 
					            usb_cancel_packet(&s->ep[ep].packey[dir].p);
 | 
				
			||||||
 | 
				
			|||||||
@ -1709,8 +1709,8 @@ 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 &&
 | 
					    if (ohci->async_td &&
 | 
				
			||||||
        ohci->usb_packet.owner != NULL &&
 | 
					        usb_packet_is_inflight(&ohci->usb_packet) &&
 | 
				
			||||||
        ohci->usb_packet.owner->dev == dev) {
 | 
					        ohci->usb_packet.ep->dev == dev) {
 | 
				
			||||||
        usb_cancel_packet(&ohci->usb_packet);
 | 
					        usb_cancel_packet(&ohci->usb_packet);
 | 
				
			||||||
        ohci->async_td = 0;
 | 
					        ohci->async_td = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -236,8 +236,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 == NULL ||
 | 
					        if (!usb_packet_is_inflight(&curr->packet) ||
 | 
				
			||||||
            curr->packet.owner->dev != dev) {
 | 
					            curr->packet.ep->dev != dev) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        uhci_async_unlink(s, curr);
 | 
					        uhci_async_unlink(s, curr);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								hw/usb.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								hw/usb.c
									
									
									
									
									
								
							@ -291,7 +291,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    assert(dev->addr == p->devaddr);
 | 
					    assert(dev->addr == p->devaddr);
 | 
				
			||||||
    assert(dev->state == USB_STATE_DEFAULT);
 | 
					    assert(dev->state == USB_STATE_DEFAULT);
 | 
				
			||||||
    assert(p->owner == NULL);
 | 
					    assert(p->state == USB_PACKET_SETUP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (p->devep == 0) {
 | 
					    if (p->devep == 0) {
 | 
				
			||||||
        /* control pipe */
 | 
					        /* control pipe */
 | 
				
			||||||
@ -315,7 +315,8 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ret == USB_RET_ASYNC) {
 | 
					    if (ret == USB_RET_ASYNC) {
 | 
				
			||||||
        p->owner = usb_ep_get(dev, p->pid, p->devep);
 | 
					        p->ep = usb_ep_get(dev, p->pid, p->devep);
 | 
				
			||||||
 | 
					        p->state = USB_PACKET_ASYNC;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -325,8 +326,8 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
 | 
				
			|||||||
   handle_packet. */
 | 
					   handle_packet. */
 | 
				
			||||||
void usb_packet_complete(USBDevice *dev, USBPacket *p)
 | 
					void usb_packet_complete(USBDevice *dev, USBPacket *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(p->owner != NULL);
 | 
					    assert(p->state == USB_PACKET_ASYNC);
 | 
				
			||||||
    p->owner = NULL;
 | 
					    p->state = USB_PACKET_COMPLETE;
 | 
				
			||||||
    dev->port->ops->complete(dev->port, p);
 | 
					    dev->port->ops->complete(dev->port, p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -335,9 +336,9 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 | 
				
			|||||||
   completed.  */
 | 
					   completed.  */
 | 
				
			||||||
void usb_cancel_packet(USBPacket * p)
 | 
					void usb_cancel_packet(USBPacket * p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(p->owner != NULL);
 | 
					    assert(p->state == USB_PACKET_ASYNC);
 | 
				
			||||||
    usb_device_cancel_packet(p->owner->dev, p);
 | 
					    p->state = USB_PACKET_CANCELED;
 | 
				
			||||||
    p->owner = NULL;
 | 
					    usb_device_cancel_packet(p->ep->dev, p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -348,6 +349,8 @@ void usb_packet_init(USBPacket *p)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep)
 | 
					void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    assert(!usb_packet_is_inflight(p));
 | 
				
			||||||
 | 
					    p->state = USB_PACKET_SETUP;
 | 
				
			||||||
    p->pid = pid;
 | 
					    p->pid = pid;
 | 
				
			||||||
    p->devaddr = addr;
 | 
					    p->devaddr = addr;
 | 
				
			||||||
    p->devep = ep;
 | 
					    p->devep = ep;
 | 
				
			||||||
@ -391,6 +394,7 @@ void usb_packet_skip(USBPacket *p, size_t bytes)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void usb_packet_cleanup(USBPacket *p)
 | 
					void usb_packet_cleanup(USBPacket *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    assert(!usb_packet_is_inflight(p));
 | 
				
			||||||
    qemu_iovec_destroy(&p->iov);
 | 
					    qemu_iovec_destroy(&p->iov);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								hw/usb.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								hw/usb.h
									
									
									
									
									
								
							@ -289,8 +289,7 @@ typedef struct USBPortOps {
 | 
				
			|||||||
    void (*wakeup)(USBPort *port);
 | 
					    void (*wakeup)(USBPort *port);
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Note that port->dev will be different then the device from which
 | 
					     * Note that port->dev will be different then the device from which
 | 
				
			||||||
     * the packet originated when a hub is involved, if you want the orginating
 | 
					     * the packet originated when a hub is involved.
 | 
				
			||||||
     * device use p->owner
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    void (*complete)(USBPort *port, USBPacket *p);
 | 
					    void (*complete)(USBPort *port, USBPacket *p);
 | 
				
			||||||
} USBPortOps;
 | 
					} USBPortOps;
 | 
				
			||||||
@ -309,15 +308,24 @@ struct USBPort {
 | 
				
			|||||||
typedef void USBCallback(USBPacket * packet, void *opaque);
 | 
					typedef void USBCallback(USBPacket * packet, void *opaque);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Structure used to hold information about an active USB packet.  */
 | 
					/* Structure used to hold information about an active USB packet.  */
 | 
				
			||||||
 | 
					typedef enum USBPacketState {
 | 
				
			||||||
 | 
					    USB_PACKET_UNDEFINED = 0,
 | 
				
			||||||
 | 
					    USB_PACKET_SETUP,
 | 
				
			||||||
 | 
					    USB_PACKET_ASYNC,
 | 
				
			||||||
 | 
					    USB_PACKET_COMPLETE,
 | 
				
			||||||
 | 
					    USB_PACKET_CANCELED,
 | 
				
			||||||
 | 
					} USBPacketState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct USBPacket {
 | 
					struct USBPacket {
 | 
				
			||||||
    /* Data fields for use by the driver.  */
 | 
					    /* Data fields for use by the driver.  */
 | 
				
			||||||
    int pid;
 | 
					    int pid;
 | 
				
			||||||
    uint8_t devaddr;
 | 
					    uint8_t devaddr;
 | 
				
			||||||
    uint8_t devep;
 | 
					    uint8_t devep;
 | 
				
			||||||
 | 
					    USBEndpoint *ep;
 | 
				
			||||||
    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.  */
 | 
				
			||||||
    USBEndpoint *owner;
 | 
					    USBPacketState state;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usb_packet_init(USBPacket *p);
 | 
					void usb_packet_init(USBPacket *p);
 | 
				
			||||||
@ -329,6 +337,11 @@ void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes);
 | 
				
			|||||||
void usb_packet_skip(USBPacket *p, size_t bytes);
 | 
					void usb_packet_skip(USBPacket *p, size_t bytes);
 | 
				
			||||||
void usb_packet_cleanup(USBPacket *p);
 | 
					void usb_packet_cleanup(USBPacket *p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline bool usb_packet_is_inflight(USBPacket *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return p->state == USB_PACKET_ASYNC;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
USBDevice *usb_find_device(USBPort *port, uint8_t addr);
 | 
					USBDevice *usb_find_device(USBPort *port, uint8_t addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int usb_handle_packet(USBDevice *dev, USBPacket *p);
 | 
					int usb_handle_packet(USBDevice *dev, USBPacket *p);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user