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