static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)

{

    AsyncURB *aurb;

    int i, j, ret, max_packet_size, offset, len = 0;

    uint8_t *buf;



    max_packet_size = usb_ep_get_max_packet_size(&s->dev, p->pid, p->devep);

    if (max_packet_size == 0)

        return USB_RET_NAK;



    aurb = get_iso_urb(s, p->pid, p->devep);

    if (!aurb) {

        aurb = usb_host_alloc_iso(s, p->pid, p->devep);

    }



    i = get_iso_urb_idx(s, p->pid, p->devep);

    j = aurb[i].iso_frame_idx;

    if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {

        if (in) {

            /* Check urb status  */

            if (aurb[i].urb.status) {

                len = urb_status_to_usb_ret(aurb[i].urb.status);

                /* Move to the next urb */

                aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;

            /* Check frame status */

            } else if (aurb[i].urb.iso_frame_desc[j].status) {

                len = urb_status_to_usb_ret(

                                        aurb[i].urb.iso_frame_desc[j].status);

            /* Check the frame fits */

            } else if (aurb[i].urb.iso_frame_desc[j].actual_length

                       > p->iov.size) {

                printf("husb: received iso data is larger then packet\n");

                len = USB_RET_NAK;

            /* All good copy data over */

            } else {

                len = aurb[i].urb.iso_frame_desc[j].actual_length;

                buf  = aurb[i].urb.buffer +

                    j * aurb[i].urb.iso_frame_desc[0].length;

                usb_packet_copy(p, buf, len);

            }

        } else {

            len = p->iov.size;

            offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->devep);



            /* Check the frame fits */

            if (len > max_packet_size) {

                printf("husb: send iso data is larger then max packet size\n");

                return USB_RET_NAK;

            }



            /* All good copy data over */

            usb_packet_copy(p, aurb[i].urb.buffer + offset, len);

            aurb[i].urb.iso_frame_desc[j].length = len;

            offset += len;

            set_iso_buffer_used(s, p->pid, p->devep, offset);



            /* Start the stream once we have buffered enough data */

            if (!is_iso_started(s, p->pid, p->devep) && i == 1 && j == 8) {

                set_iso_started(s, p->pid, p->devep);

            }

        }

        aurb[i].iso_frame_idx++;

        if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

            i = (i + 1) % s->iso_urb_count;

            set_iso_urb_idx(s, p->pid, p->devep, i);

        }

    } else {

        if (in) {

            set_iso_started(s, p->pid, p->devep);

        } else {

            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");

        }

    }



    if (is_iso_started(s, p->pid, p->devep)) {

        /* (Re)-submit all fully consumed / filled urbs */

        for (i = 0; i < s->iso_urb_count; i++) {

            if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

                ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);

                if (ret < 0) {

                    perror("USBDEVFS_SUBMITURB");

                    if (!in || len == 0) {

                        switch(errno) {

                        case ETIMEDOUT:

                            len = USB_RET_NAK;

                            break;

                        case EPIPE:

                        default:

                            len = USB_RET_STALL;

                        }

                    }

                    break;

                }

                aurb[i].iso_frame_idx = -1;

                change_iso_inflight(s, p->pid, p->devep, 1);

            }

        }

    }



    return len;

}

static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)

{

    AsyncURB *aurb;

    int i, j, ret, max_packet_size, offset, len = 0;

    uint8_t *buf;



    max_packet_size = usb_ep_get_max_packet_size(&s->dev, p->pid, p->devep);

    if (max_packet_size == 0)

        return USB_RET_NAK;



    aurb = get_iso_urb(s, p->pid, p->devep);

    if (!aurb) {

        aurb = usb_host_alloc_iso(s, p->pid, p->devep);

    }



    i = get_iso_urb_idx(s, p->pid, p->devep);

    j = aurb[i].iso_frame_idx;

    if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {

        if (in) {

            

            if (aurb[i].urb.status) {

                len = urb_status_to_usb_ret(aurb[i].urb.status);

                

                aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;

            

            } else if (aurb[i].urb.iso_frame_desc[j].status) {

                len = urb_status_to_usb_ret(

                                        aurb[i].urb.iso_frame_desc[j].status);

            

            } else if (aurb[i].urb.iso_frame_desc[j].actual_length

                       > p->iov.size) {

                printf("husb: received iso data is larger then packet\n");

                len = USB_RET_NAK;

            

            } else {

                len = aurb[i].urb.iso_frame_desc[j].actual_length;

                buf  = aurb[i].urb.buffer +

                    j * aurb[i].urb.iso_frame_desc[0].length;

                usb_packet_copy(p, buf, len);

            }

        } else {

            len = p->iov.size;

            offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->devep);



            

            if (len > max_packet_size) {

                printf("husb: send iso data is larger then max packet size\n");

                return USB_RET_NAK;

            }



            

            usb_packet_copy(p, aurb[i].urb.buffer + offset, len);

            aurb[i].urb.iso_frame_desc[j].length = len;

            offset += len;

            set_iso_buffer_used(s, p->pid, p->devep, offset);



            

            if (!is_iso_started(s, p->pid, p->devep) && i == 1 && j == 8) {

                set_iso_started(s, p->pid, p->devep);

            }

        }

        aurb[i].iso_frame_idx++;

        if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

            i = (i + 1) % s->iso_urb_count;

            set_iso_urb_idx(s, p->pid, p->devep, i);

        }

    } else {

        if (in) {

            set_iso_started(s, p->pid, p->devep);

        } else {

            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");

        }

    }



    if (is_iso_started(s, p->pid, p->devep)) {

        

        for (i = 0; i < s->iso_urb_count; i++) {

            if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

                ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);

                if (ret < 0) {

                    perror("USBDEVFS_SUBMITURB");

                    if (!in || len == 0) {

                        switch(errno) {

                        case ETIMEDOUT:

                            len = USB_RET_NAK;

                            break;

                        case EPIPE:

                        default:

                            len = USB_RET_STALL;

                        }

                    }

                    break;

                }

                aurb[i].iso_frame_idx = -1;

                change_iso_inflight(s, p->pid, p->devep, 1);

            }

        }

    }



    return len;

}

static int FUNC_0(USBHostDevice *VAR_0, USBPacket *VAR_1, int VAR_2)

{

    AsyncURB *aurb;

    int VAR_3, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8 = 0;

    uint8_t *buf;



    VAR_6 = usb_ep_get_max_packet_size(&VAR_0->dev, VAR_1->pid, VAR_1->devep);

    if (VAR_6 == 0)

        return USB_RET_NAK;



    aurb = get_iso_urb(VAR_0, VAR_1->pid, VAR_1->devep);

    if (!aurb) {

        aurb = usb_host_alloc_iso(VAR_0, VAR_1->pid, VAR_1->devep);

    }



    VAR_3 = get_iso_urb_idx(VAR_0, VAR_1->pid, VAR_1->devep);

    VAR_4 = aurb[VAR_3].iso_frame_idx;

    if (VAR_4 >= 0 && VAR_4 < ISO_FRAME_DESC_PER_URB) {

        if (VAR_2) {

            

            if (aurb[VAR_3].urb.status) {

                VAR_8 = urb_status_to_usb_ret(aurb[VAR_3].urb.status);

                

                aurb[VAR_3].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;

            

            } else if (aurb[VAR_3].urb.iso_frame_desc[VAR_4].status) {

                VAR_8 = urb_status_to_usb_ret(

                                        aurb[VAR_3].urb.iso_frame_desc[VAR_4].status);

            

            } else if (aurb[VAR_3].urb.iso_frame_desc[VAR_4].actual_length

                       > VAR_1->iov.size) {

                printf("husb: received iso data is larger then packet\n");

                VAR_8 = USB_RET_NAK;

            

            } else {

                VAR_8 = aurb[VAR_3].urb.iso_frame_desc[VAR_4].actual_length;

                buf  = aurb[VAR_3].urb.buffer +

                    VAR_4 * aurb[VAR_3].urb.iso_frame_desc[0].length;

                usb_packet_copy(VAR_1, buf, VAR_8);

            }

        } else {

            VAR_8 = VAR_1->iov.size;

            VAR_7 = (VAR_4 == 0) ? 0 : get_iso_buffer_used(VAR_0, VAR_1->pid, VAR_1->devep);



            

            if (VAR_8 > VAR_6) {

                printf("husb: send iso data is larger then max packet size\n");

                return USB_RET_NAK;

            }



            

            usb_packet_copy(VAR_1, aurb[VAR_3].urb.buffer + VAR_7, VAR_8);

            aurb[VAR_3].urb.iso_frame_desc[VAR_4].length = VAR_8;

            VAR_7 += VAR_8;

            set_iso_buffer_used(VAR_0, VAR_1->pid, VAR_1->devep, VAR_7);



            

            if (!is_iso_started(VAR_0, VAR_1->pid, VAR_1->devep) && VAR_3 == 1 && VAR_4 == 8) {

                set_iso_started(VAR_0, VAR_1->pid, VAR_1->devep);

            }

        }

        aurb[VAR_3].iso_frame_idx++;

        if (aurb[VAR_3].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

            VAR_3 = (VAR_3 + 1) % VAR_0->iso_urb_count;

            set_iso_urb_idx(VAR_0, VAR_1->pid, VAR_1->devep, VAR_3);

        }

    } else {

        if (VAR_2) {

            set_iso_started(VAR_0, VAR_1->pid, VAR_1->devep);

        } else {

            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");

        }

    }



    if (is_iso_started(VAR_0, VAR_1->pid, VAR_1->devep)) {

        

        for (VAR_3 = 0; VAR_3 < VAR_0->iso_urb_count; VAR_3++) {

            if (aurb[VAR_3].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {

                VAR_5 = ioctl(VAR_0->fd, USBDEVFS_SUBMITURB, &aurb[VAR_3]);

                if (VAR_5 < 0) {

                    perror("USBDEVFS_SUBMITURB");

                    if (!VAR_2 || VAR_8 == 0) {

                        switch(errno) {

                        case ETIMEDOUT:

                            VAR_8 = USB_RET_NAK;

                            break;

                        case EPIPE:

                        default:

                            VAR_8 = USB_RET_STALL;

                        }

                    }

                    break;

                }

                aurb[VAR_3].iso_frame_idx = -1;

                change_iso_inflight(VAR_0, VAR_1->pid, VAR_1->devep, 1);

            }

        }

    }



    return VAR_8;

}

static int FUNC_0(USBHostDevice *VAR_0, USBPacket *VAR_1, int VAR_2)
{ AsyncURB *aurb; int VAR_3, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8 = 0; uint8_t *buf; VAR_6 = usb_ep_get_max_packet_size(&VAR_0->dev, VAR_1->pid, VAR_1->devep); if (VAR_6 == 0)
return USB_RET_NAK; aurb = get_iso_urb(VAR_0, VAR_1->pid, VAR_1->devep); if (!aurb) { aurb = usb_host_alloc_iso(VAR_0, VAR_1->pid, VAR_1->devep); } VAR_3 = get_iso_urb_idx(VAR_0, VAR_1->pid, VAR_1->devep); VAR_4 = aurb[VAR_3].iso_frame_idx; if (VAR_4 >= 0 && VAR_4 < ISO_FRAME_DESC_PER_URB) { if (VAR_2) { if (aurb[VAR_3].urb.status) { VAR_8 = urb_status_to_usb_ret(aurb[VAR_3].urb.status); aurb[VAR_3].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1; } else if (aurb[VAR_3].urb.iso_frame_desc[VAR_4].status) { VAR_8 = urb_status_to_usb_ret(
aurb[VAR_3].urb.iso_frame_desc[VAR_4].status); } else if (aurb[VAR_3].urb.iso_frame_desc[VAR_4].actual_length > VAR_1->iov.size) { printf("husb: received iso data is larger then packet\n"); VAR_8 = USB_RET_NAK; } else { VAR_8 = aurb[VAR_3].urb.iso_frame_desc[VAR_4].actual_length; buf  = aurb[VAR_3].urb.buffer +
VAR_4 * aurb[VAR_3].urb.iso_frame_desc[0].length; usb_packet_copy(VAR_1, buf, VAR_8); } } else { VAR_8 = VAR_1->iov.size; VAR_7 = (VAR_4 == 0) ? 0 : get_iso_buffer_used(VAR_0, VAR_1->pid, VAR_1->devep); if (VAR_8 > VAR_6) { printf("husb: send iso data is larger then max packet size\n"); return USB_RET_NAK; } usb_packet_copy(VAR_1, aurb[VAR_3].urb.buffer + VAR_7, VAR_8); aurb[VAR_3].urb.iso_frame_desc[VAR_4].length = VAR_8; VAR_7 += VAR_8; set_iso_buffer_used(VAR_0, VAR_1->pid, VAR_1->devep, VAR_7); if (!is_iso_started(VAR_0, VAR_1->pid, VAR_1->devep) && VAR_3 == 1 && VAR_4 == 8) { set_iso_started(VAR_0, VAR_1->pid, VAR_1->devep); } } aurb[VAR_3].iso_frame_idx++; if (aurb[VAR_3].iso_frame_idx == ISO_FRAME_DESC_PER_URB) { VAR_3 = (VAR_3 + 1) % VAR_0->iso_urb_count; set_iso_urb_idx(VAR_0, VAR_1->pid, VAR_1->devep, VAR_3); } } else { if (VAR_2) { set_iso_started(VAR_0, VAR_1->pid, VAR_1->devep); } else { DPRINTF("hubs: iso out error no free buffer, dropping packet\n"); } } if (is_iso_started(VAR_0, VAR_1->pid, VAR_1->devep)) { for (VAR_3 = 0; VAR_3 < VAR_0->iso_urb_count; VAR_3++) { if (aurb[VAR_3].iso_frame_idx == ISO_FRAME_DESC_PER_URB) { VAR_5 = ioctl(VAR_0->fd, USBDEVFS_SUBMITURB, &aurb[VAR_3]); if (VAR_5 < 0) { perror("USBDEVFS_SUBMITURB"); if (!VAR_2 || VAR_8 == 0) { switch(errno) { case ETIMEDOUT:
VAR_8 = USB_RET_NAK; break; case EPIPE:
default:
VAR_8 = USB_RET_STALL; } } break; } aurb[VAR_3].iso_frame_idx = -1; change_iso_inflight(VAR_0, VAR_1->pid, VAR_1->devep, 1); } } } return VAR_8; }