mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-29 21:54:27 +00:00
qemu-usb: handle smaller isochronous packets
Fix the wrong assumption about isochronous packets being always send with maximum EP's packet size. Instead the isochronous cache now contains a sizes array to deal with arbitrary packet sizes. Fix genodelabs/genode#5257
This commit is contained in:
parent
f1f2d759af
commit
969a0583ee
@ -98,6 +98,7 @@ class Isoc_cache
|
|||||||
Allocator &_alloc;
|
Allocator &_alloc;
|
||||||
uint8_t _read { 0 };
|
uint8_t _read { 0 };
|
||||||
uint8_t _wrote { 0 };
|
uint8_t _wrote { 0 };
|
||||||
|
uint16_t _sizes[MAX_PACKETS];
|
||||||
unsigned char *_buffer;
|
unsigned char *_buffer;
|
||||||
|
|
||||||
Constructible<Urb> _urbs[URBS];
|
Constructible<Urb> _urbs[URBS];
|
||||||
@ -531,28 +532,31 @@ void Isoc_cache::_copy_to_host(USBPacket *p)
|
|||||||
if (!size || _level() >= MAX_PACKETS-1)
|
if (!size || _level() >= MAX_PACKETS-1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size_t offset = _wrote++ * _ep.max_packet_size();
|
size_t offset = _wrote * _ep.max_packet_size();
|
||||||
|
|
||||||
if (size != _ep.max_packet_size()) {
|
if (size > _ep.max_packet_size()) {
|
||||||
error("Assumption about QEmu Isochronous out packets wrong!");
|
error("Assumption about QEmu Isochronous out packets wrong!");
|
||||||
size = _ep.max_packet_size();
|
size = _ep.max_packet_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
usb_packet_copy(p, _buffer+offset, size);
|
usb_packet_copy(p, _buffer+offset, size);
|
||||||
|
_sizes[_wrote] = size;
|
||||||
|
_wrote++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Isoc_cache::_copy_to_guest(USBPacket *p)
|
void Isoc_cache::_copy_to_guest(USBPacket *p)
|
||||||
{
|
{
|
||||||
size_t count = p->iov.size / _ep.max_packet_size();
|
size_t size = p->iov.size;
|
||||||
|
|
||||||
if (!count || !_level())
|
while (size && _level()) {
|
||||||
return;
|
size_t offset = _read * _ep.max_packet_size();
|
||||||
|
if (size < _sizes[_read])
|
||||||
size_t offset = _read * _ep.max_packet_size();
|
return;
|
||||||
_read += count;
|
size -= _sizes[_read];
|
||||||
|
usb_packet_copy(p, _buffer+offset, _sizes[_read++]);
|
||||||
usb_packet_copy(p, _buffer+offset, count * _ep.max_packet_size());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -569,16 +573,16 @@ size_t Isoc_cache::read(Byte_range_ptr &dst)
|
|||||||
if (_ep.in())
|
if (_ep.in())
|
||||||
return _ep.max_packet_size();
|
return _ep.max_packet_size();
|
||||||
|
|
||||||
size_t offset = _read++ * _ep.max_packet_size();
|
size_t offset = _read * _ep.max_packet_size();
|
||||||
Genode::memcpy(dst.start, (void*)(_buffer+offset), _ep.max_packet_size());
|
Genode::memcpy(dst.start, (void*)(_buffer+offset), _sizes[_read]);
|
||||||
return _ep.max_packet_size();
|
return _sizes[_read++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Isoc_cache::write(Const_byte_range_ptr const &src)
|
void Isoc_cache::write(Const_byte_range_ptr const &src)
|
||||||
{
|
{
|
||||||
size_t offset = _wrote * _ep.max_packet_size();
|
size_t offset = _wrote * _ep.max_packet_size();
|
||||||
_wrote += src.num_bytes / _ep.max_packet_size();
|
_sizes[_wrote++] = src.num_bytes;
|
||||||
Genode::memcpy((void*)(_buffer+offset), src.start, src.num_bytes);
|
Genode::memcpy((void*)(_buffer+offset), src.start, src.num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user