Revision 71138531

b/usb-linux.c
89 89
#define ISO_URB_COUNT 3
90 90
#define INVALID_EP_TYPE 255
91 91

  
92
/* devio.c limits single requests to 16k */
93
#define MAX_USBFS_BUFFER_SIZE 16384
94

  
92 95
typedef struct AsyncURB AsyncURB;
93 96

  
94 97
struct endp_data {
......
229 232

  
230 233
    /* For regular async urbs */
231 234
    USBPacket     *packet;
235
    int more; /* large transfer, more urbs follow */
232 236

  
233 237
    /* For buffered iso handling */
234 238
    int iso_frame_idx; /* -1 means in flight */
......
291 295
        if (p) {
292 296
            switch (aurb->urb.status) {
293 297
            case 0:
294
                p->len = aurb->urb.actual_length;
298
                p->len += aurb->urb.actual_length;
295 299
                break;
296 300

  
297 301
            case -EPIPE:
......
306 310

  
307 311
            if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
308 312
                usb_generic_async_ctrl_complete(&s->dev, p);
309
            } else {
313
            } else if (!aurb->more) {
310 314
                usb_packet_complete(&s->dev, p);
311 315
            }
312 316
        }
......
646 650
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
647 651
    struct usbdevfs_urb *urb;
648 652
    AsyncURB *aurb;
649
    int ret;
653
    int ret, rem;
654
    uint8_t *pbuf;
650 655
    uint8_t ep;
651 656

  
652 657
    if (!is_valid(s, p->devep)) {
......
673 678
        return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
674 679
    }
675 680

  
676
    aurb = async_alloc(s);
677
    aurb->packet = p;
681
    rem = p->len;
682
    pbuf = p->data;
683
    p->len = 0;
684
    while (rem) {
685
        aurb = async_alloc(s);
686
        aurb->packet = p;
678 687

  
679
    urb = &aurb->urb;
688
        urb = &aurb->urb;
689
        urb->endpoint      = ep;
690
        urb->type          = USBDEVFS_URB_TYPE_BULK;
691
        urb->usercontext   = s;
692
        urb->buffer        = pbuf;
680 693

  
681
    urb->endpoint      = ep;
682
    urb->buffer        = p->data;
683
    urb->buffer_length = p->len;
684
    urb->type          = USBDEVFS_URB_TYPE_BULK;
685
    urb->usercontext   = s;
694
        if (rem > MAX_USBFS_BUFFER_SIZE) {
695
            urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
696
            aurb->more         = 1;
697
        } else {
698
            urb->buffer_length = rem;
699
            aurb->more         = 0;
700
        }
701
        pbuf += urb->buffer_length;
702
        rem  -= urb->buffer_length;
686 703

  
687
    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
704
        ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
688 705

  
689
    DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
690
            urb->endpoint, p->len, aurb);
706
        DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
707
                urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
691 708

  
692
    if (ret < 0) {
693
        DPRINTF("husb: submit failed. errno %d\n", errno);
694
        async_free(aurb);
709
        if (ret < 0) {
710
            DPRINTF("husb: submit failed. errno %d\n", errno);
711
            async_free(aurb);
695 712

  
696
        switch(errno) {
697
        case ETIMEDOUT:
698
            return USB_RET_NAK;
699
        case EPIPE:
700
        default:
701
            return USB_RET_STALL;
713
            switch(errno) {
714
            case ETIMEDOUT:
715
                return USB_RET_NAK;
716
            case EPIPE:
717
            default:
718
                return USB_RET_STALL;
719
            }
702 720
        }
703 721
    }
704 722

  

Also available in: Unified diff