usb_cdc: Fix handling of zero-length-packets
A zero length packet should only be sent at the end of a transmission if the host is expecting more data. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
be1effebc3
commit
92aea93500
|
@ -290,7 +290,7 @@ static const struct descriptor_s {
|
||||||
|
|
||||||
// State tracking
|
// State tracking
|
||||||
enum {
|
enum {
|
||||||
UX_READ = 1<<0, UX_SEND = 1<<1
|
UX_READ = 1<<0, UX_SEND = 1<<1, UX_SEND_ZLP = 1<<2
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *usb_xfer_data;
|
static void *usb_xfer_data;
|
||||||
|
@ -321,13 +321,16 @@ usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
|
||||||
// Success
|
// Success
|
||||||
data += xs;
|
data += xs;
|
||||||
size -= xs;
|
size -= xs;
|
||||||
if (!size && xs < USB_CDC_EP0_SIZE) {
|
if (!size) {
|
||||||
// Transfer completed successfully
|
// Entire transfer completed successfully
|
||||||
if (flags & UX_READ) {
|
if (flags & UX_READ) {
|
||||||
// Send status packet at end of read
|
// Send status packet at end of read
|
||||||
flags = UX_SEND;
|
flags = UX_SEND;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (xs == USB_CDC_EP0_SIZE && flags & UX_SEND_ZLP)
|
||||||
|
// Must send zero-length-packet
|
||||||
|
continue;
|
||||||
usb_xfer_flags = 0;
|
usb_xfer_flags = 0;
|
||||||
usb_notify_ep0();
|
usb_notify_ep0();
|
||||||
return;
|
return;
|
||||||
|
@ -356,10 +359,12 @@ usb_req_get_descriptor(struct usb_ctrlrequest *req)
|
||||||
const struct descriptor_s *d = &cdc_descriptors[i];
|
const struct descriptor_s *d = &cdc_descriptors[i];
|
||||||
if (READP(d->wValue) == req->wValue
|
if (READP(d->wValue) == req->wValue
|
||||||
&& READP(d->wIndex) == req->wIndex) {
|
&& READP(d->wIndex) == req->wIndex) {
|
||||||
uint_fast8_t size = READP(d->size);
|
uint_fast8_t size = READP(d->size), flags = UX_SEND;
|
||||||
if (size > req->wLength)
|
if (size > req->wLength)
|
||||||
size = req->wLength;
|
size = req->wLength;
|
||||||
usb_do_xfer((void*)READP(d->desc), size, UX_SEND);
|
else if (size < req->wLength)
|
||||||
|
flags |= UX_SEND_ZLP;
|
||||||
|
usb_do_xfer((void*)READP(d->desc), size, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue