mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
usb_host: add support to flush EP transfers
This causes all pending transfers of a EP to be canceled and in turn to be acked by the raw session. issue #4196
This commit is contained in:
parent
4aa99fd1a9
commit
eabda8907f
@ -21,6 +21,7 @@
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
#include "raw.h"
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
#include <signal.h>
|
||||
@ -103,6 +104,11 @@ class Device : public List<Device>::Element
|
||||
});
|
||||
}
|
||||
|
||||
usb_host_endpoint *_host_ep(uint8_t ep)
|
||||
{
|
||||
return ep & USB_DIR_IN ? _udev.ep_in[ep & 0xf] : _udev.ep_out[ep & 0xf];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve string descriptor at index given in packet
|
||||
*/
|
||||
@ -359,8 +365,7 @@ class Device : public List<Device>::Element
|
||||
|
||||
if (p.transfer.polling_interval == Usb::Packet_descriptor::DEFAULT_POLLING_INTERVAL) {
|
||||
|
||||
usb_host_endpoint *ep = read ? _udev.ep_in[p.transfer.ep & 0x0f]
|
||||
: _udev.ep_out[p.transfer.ep & 0x0f];
|
||||
usb_host_endpoint *ep = _host_ep(p.transfer.ep);
|
||||
|
||||
if (!ep) {
|
||||
error("could not get ep: ", p.transfer.ep);
|
||||
@ -415,16 +420,14 @@ class Device : public List<Device>::Element
|
||||
bool _isoc(Packet_descriptor &p, bool read)
|
||||
{
|
||||
unsigned pipe;
|
||||
usb_host_endpoint *ep;
|
||||
usb_host_endpoint *ep = _host_ep(p.transfer.ep);
|
||||
void *buf = dma_malloc(p.size());
|
||||
|
||||
if (read) {
|
||||
pipe = usb_rcvisocpipe(&_udev, p.transfer.ep);
|
||||
ep = _udev.ep_in[p.transfer.ep & 0x0f];
|
||||
}
|
||||
else {
|
||||
pipe = usb_sndisocpipe(&_udev, p.transfer.ep);
|
||||
ep = _udev.ep_out[p.transfer.ep & 0x0f];
|
||||
Genode::memcpy(buf, _sink->packet_content(p), p.size());
|
||||
}
|
||||
|
||||
@ -535,6 +538,23 @@ class Device : public List<Device>::Element
|
||||
p.succeded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush all pending URBs for endpoint
|
||||
*/
|
||||
void _flush_endpoint(Packet_descriptor &p)
|
||||
{
|
||||
usb_host_endpoint *ep = _host_ep(p.number);
|
||||
|
||||
if (!ep) {
|
||||
error("could net get ep: ", p.number);
|
||||
p.error = Usb::Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
usb_hcd_flush_endpoint(&_udev, ep);
|
||||
p.succeded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch incoming packet types
|
||||
*/
|
||||
@ -597,6 +617,10 @@ class Device : public List<Device>::Element
|
||||
case Packet_descriptor::RELEASE_IF:
|
||||
_release_interface(p);
|
||||
break;
|
||||
|
||||
case Packet_descriptor::FLUSH_TRANSFERS:
|
||||
_flush_endpoint(p);
|
||||
break;
|
||||
}
|
||||
|
||||
_ack_packet(p);
|
||||
|
@ -33,7 +33,7 @@ namespace Usb {
|
||||
*/
|
||||
struct Usb::Packet_descriptor : Genode::Packet_descriptor
|
||||
{
|
||||
enum Type { STRING, CTRL, BULK, IRQ, ISOC, ALT_SETTING, CONFIG, RELEASE_IF };
|
||||
enum Type { STRING, CTRL, BULK, IRQ, ISOC, ALT_SETTING, CONFIG, RELEASE_IF, FLUSH_TRANSFERS };
|
||||
enum Iso { MAX_PACKETS = 32 };
|
||||
|
||||
/* use the polling interval stated in the endpoint descriptor */
|
||||
|
Loading…
Reference in New Issue
Block a user