mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-11 13:22:33 +00:00
parent
91a7fb1da7
commit
2670ae399b
repos
dde_linux/src
os/include/usb_session
@ -28,6 +28,9 @@
|
||||
#include <lx_kit/malloc.h>
|
||||
#include <lx_kit/scheduler.h>
|
||||
|
||||
/* definition from scsi.h conflicts with USB session timeout error */
|
||||
#undef TIMEOUT_ERROR
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern "C" int usb_set_configuration(struct usb_device *dev, int configuration);
|
||||
@ -175,9 +178,27 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
kfree(buf);
|
||||
|
||||
p.control.actual_size = err;
|
||||
if (err >= 0) {
|
||||
p.succeded = true;
|
||||
p.control.actual_size = err;
|
||||
} else {
|
||||
p.control.actual_size = 0;
|
||||
|
||||
p.succeded = (err < 0 && err != -EPIPE) ? false : true;
|
||||
if (err == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((err == -ENODEV) || (err == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else if ((err == -EPROTO) || (err == -EILSEQ))
|
||||
p.error = Packet_descriptor::PROTOCOL_ERROR;
|
||||
else if (err == -EPIPE)
|
||||
p.error = Packet_descriptor::STALL_ERROR;
|
||||
else if (err == -ETIMEDOUT)
|
||||
p.error = Packet_descriptor::TIMEOUT_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -194,16 +215,34 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
p.control.request, p.control.request_type,
|
||||
p.control.value, p.control.index, buf, p.size(),
|
||||
p.control.timeout);
|
||||
if (err >= 0 || err== -EPIPE) {
|
||||
p.control.actual_size = err;
|
||||
|
||||
if (err >= 0) {
|
||||
p.succeded = true;
|
||||
p.control.actual_size = err;
|
||||
|
||||
if (p.control.request == USB_REQ_CLEAR_FEATURE &&
|
||||
p.control.value == USB_ENDPOINT_HALT) {
|
||||
usb_reset_endpoint(_device->udev, p.control.index);
|
||||
}
|
||||
} else {
|
||||
p.control.actual_size = 0;
|
||||
|
||||
if (err == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((err == -ENODEV) || (err == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else if ((err == -EPROTO) || (err == -EILSEQ))
|
||||
p.error = Packet_descriptor::PROTOCOL_ERROR;
|
||||
else if (err == -EPIPE)
|
||||
p.error = Packet_descriptor::STALL_ERROR;
|
||||
else if (err == -ETIMEDOUT)
|
||||
p.error = Packet_descriptor::TIMEOUT_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (err >= 0
|
||||
&& p.control.request == USB_REQ_CLEAR_FEATURE
|
||||
&& p.control.value == USB_ENDPOINT_HALT) {
|
||||
usb_reset_endpoint(_device->udev, p.control.index);
|
||||
}
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
@ -242,10 +281,15 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (read)
|
||||
Genode::memcpy(_sink->packet_content(p), urb->transfer_buffer,
|
||||
urb->actual_length);
|
||||
}
|
||||
|
||||
if (urb->status == -EPIPE) {
|
||||
} else if (urb->status == -ESHUTDOWN) {
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
} else if ((urb->status == -EPROTO) || (urb->status == -EILSEQ)) {
|
||||
p.error = Packet_descriptor::PROTOCOL_ERROR;
|
||||
} else if (urb->status == -EPIPE) {
|
||||
p.error = Packet_descriptor::STALL_ERROR;
|
||||
} else {
|
||||
Genode::error(__func__, ": unhandled error: ", urb->status);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
_ack_packet(p);
|
||||
@ -287,7 +331,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!bulk_urb) {
|
||||
error("Failed to allocate bulk URB");
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::MEMORY_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -298,8 +342,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
int ret = usb_submit_urb(bulk_urb, GFP_KERNEL);
|
||||
if (ret != 0) {
|
||||
error("Failed to submit URB, error: ", ret);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
if (ret == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((ret == -ENODEV) || (ret == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", ret);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
free_complete_data(data);
|
||||
usb_free_urb(bulk_urb);
|
||||
@ -329,7 +379,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!irq_urb) {
|
||||
error("Failed to allocate interrupt URB");
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::MEMORY_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -345,7 +395,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!ep) {
|
||||
error("could not get ep: ", p.transfer.ep);
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -359,8 +409,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
int ret = usb_submit_urb(irq_urb, GFP_KERNEL);
|
||||
if (ret != 0) {
|
||||
error("Failed to submit URB, error: ", ret);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
if (ret == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((ret == -ENODEV) || (ret == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", ret);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
free_complete_data(data);
|
||||
usb_free_urb(irq_urb);
|
||||
@ -393,7 +449,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!ep) {
|
||||
error("could not get ep: ", p.transfer.ep);
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -401,7 +457,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!urb) {
|
||||
error("Failed to allocate isochronous URB");
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::MEMORY_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -429,8 +485,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (ret == 0)
|
||||
return true;
|
||||
|
||||
error("Failed to submit URB, error: ", ret);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
if (ret == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((ret == -ENODEV) || (ret == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", ret);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
free_complete_data(data);
|
||||
usb_free_urb(urb);
|
||||
@ -447,6 +509,8 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
p.interface.alt_setting);
|
||||
if (!err)
|
||||
p.succeded = true;
|
||||
else
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -469,6 +533,8 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
if (!err)
|
||||
p.succeded = true;
|
||||
else
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -503,7 +569,15 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
_p_in_flight++;
|
||||
|
||||
if (!_device || !_device->udev || !_sink->packet_valid(p)) {
|
||||
if (!_device || !_device->udev ||
|
||||
_device->udev->state == USB_STATE_NOTATTACHED) {
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
_ack_packet(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_sink->packet_valid(p)) {
|
||||
p.error = Packet_descriptor::PACKET_INVALID_ERROR;
|
||||
_ack_packet(p);
|
||||
continue;
|
||||
}
|
||||
|
@ -186,9 +186,27 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
kfree(buf);
|
||||
|
||||
p.control.actual_size = err;
|
||||
if (err >= 0) {
|
||||
p.succeded = true;
|
||||
p.control.actual_size = err;
|
||||
} else {
|
||||
p.control.actual_size = 0;
|
||||
|
||||
p.succeded = (err < 0 && err != -EPIPE) ? false : true;
|
||||
if (err == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((err == -ENODEV) || (err == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else if ((err == -EPROTO) || (err == -EILSEQ))
|
||||
p.error = Packet_descriptor::PROTOCOL_ERROR;
|
||||
else if (err == -EPIPE)
|
||||
p.error = Packet_descriptor::STALL_ERROR;
|
||||
else if (err == -ETIMEDOUT)
|
||||
p.error = Packet_descriptor::TIMEOUT_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,16 +223,34 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
p.control.request, p.control.request_type,
|
||||
p.control.value, p.control.index, buf, p.size(),
|
||||
p.control.timeout);
|
||||
if (err >= 0 || err== -EPIPE) {
|
||||
p.control.actual_size = err;
|
||||
|
||||
if (err >= 0) {
|
||||
p.succeded = true;
|
||||
p.control.actual_size = err;
|
||||
|
||||
if (p.control.request == USB_REQ_CLEAR_FEATURE &&
|
||||
p.control.value == USB_ENDPOINT_HALT) {
|
||||
usb_reset_endpoint(_device->udev, p.control.index);
|
||||
}
|
||||
} else {
|
||||
p.control.actual_size = 0;
|
||||
|
||||
if (err == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((err == -ENODEV) || (err == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else if ((err == -EPROTO) || (err == -EILSEQ))
|
||||
p.error = Packet_descriptor::PROTOCOL_ERROR;
|
||||
else if (err == -EPIPE)
|
||||
p.error = Packet_descriptor::STALL_ERROR;
|
||||
else if (err == -ETIMEDOUT)
|
||||
p.error = Packet_descriptor::TIMEOUT_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (err >= 0
|
||||
&& p.control.request == USB_REQ_CLEAR_FEATURE
|
||||
&& p.control.value == USB_ENDPOINT_HALT) {
|
||||
usb_reset_endpoint(_device->udev, p.control.index);
|
||||
}
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
@ -251,12 +287,17 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
p.succeded = true;
|
||||
|
||||
if (read)
|
||||
Genode::memcpy(_sink->packet_content(p), urb->transfer_buffer,
|
||||
Genode::memcpy(_sink->packet_content(p), urb->transfer_buffer,
|
||||
urb->actual_length);
|
||||
}
|
||||
|
||||
if (urb->status == -EPIPE) {
|
||||
} else if (urb->status == -ESHUTDOWN) {
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
} else if ((urb->status == -EPROTO) || (urb->status == -EILSEQ)) {
|
||||
p.error = Packet_descriptor::PROTOCOL_ERROR;
|
||||
} else if (urb->status == -EPIPE) {
|
||||
p.error = Packet_descriptor::STALL_ERROR;
|
||||
} else {
|
||||
Genode::error(__func__, ": unhandled error: ", urb->status);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
_ack_packet(p);
|
||||
@ -298,7 +339,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!bulk_urb) {
|
||||
error("Failed to allocate bulk URB");
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::MEMORY_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -309,8 +350,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
int ret = usb_submit_urb(bulk_urb, GFP_KERNEL);
|
||||
if (ret != 0) {
|
||||
error("Failed to submit URB, error: ", ret);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
if (ret == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((ret == -ENODEV) || (ret == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", ret);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
free_complete_data(data);
|
||||
usb_free_urb(bulk_urb);
|
||||
@ -340,7 +387,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!irq_urb) {
|
||||
error("Failed to allocate interrupt URB");
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::MEMORY_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -356,7 +403,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!ep) {
|
||||
error("could not get ep: ", p.transfer.ep);
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -370,8 +417,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
int ret = usb_submit_urb(irq_urb, GFP_KERNEL);
|
||||
if (ret != 0) {
|
||||
error("Failed to submit URB, error: ", ret);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
if (ret == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((ret == -ENODEV) || (ret == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", ret);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
free_complete_data(data);
|
||||
usb_free_urb(irq_urb);
|
||||
@ -404,7 +457,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!ep) {
|
||||
error("could not get ep: ", p.transfer.ep);
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -412,7 +465,7 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (!urb) {
|
||||
error("Failed to allocate isochronous URB");
|
||||
dma_free(buf);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
p.error = Usb::Packet_descriptor::MEMORY_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -440,8 +493,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
if (ret == 0)
|
||||
return true;
|
||||
|
||||
error("Failed to submit URB, error: ", ret);
|
||||
p.error = Usb::Packet_descriptor::SUBMIT_ERROR;
|
||||
if (ret == -ENOENT)
|
||||
p.error = Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR;
|
||||
else if ((ret == -ENODEV) || (ret == -ESHUTDOWN))
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
else {
|
||||
Genode::error(__func__, ": unhandled error: ", ret);
|
||||
p.error = Packet_descriptor::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
free_complete_data(data);
|
||||
usb_free_urb(urb);
|
||||
@ -458,6 +517,8 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
p.interface.alt_setting);
|
||||
if (!err)
|
||||
p.succeded = true;
|
||||
else
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -480,6 +541,8 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
|
||||
if (!err)
|
||||
p.succeded = true;
|
||||
else
|
||||
Genode::error(__func__, ": unhandled error: ", err);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -515,8 +578,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
_p_in_flight++;
|
||||
|
||||
if (!_device || !_device->udev ||
|
||||
_device->udev->state == USB_STATE_NOTATTACHED ||
|
||||
!_sink->packet_valid(p)) {
|
||||
_device->udev->state == USB_STATE_NOTATTACHED) {
|
||||
p.error = Packet_descriptor::NO_DEVICE_ERROR;
|
||||
_ack_packet(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_sink->packet_valid(p)) {
|
||||
p.error = Packet_descriptor::PACKET_INVALID_ERROR;
|
||||
_ack_packet(p);
|
||||
continue;
|
||||
}
|
||||
|
@ -47,8 +47,16 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
|
||||
Genode::construct_at<Sync_ctrl_urb>(scu, *(Usb::Connection*)(dev->bus->controller), *u);
|
||||
|
||||
scu->send(timeout);
|
||||
int ret = u->actual_length;
|
||||
kfree(scu);
|
||||
|
||||
int ret;
|
||||
if (u->status >= 0)
|
||||
ret = u->actual_length;
|
||||
else
|
||||
ret = u->status;
|
||||
|
||||
usb_free_urb(u);
|
||||
kfree(dr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -74,6 +82,22 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
||||
|
||||
Genode::construct_at<Urb>(u, *(Usb::Connection*)(urb->dev->bus->controller), *urb);
|
||||
|
||||
/*
|
||||
* Self-destruction of the 'Urb' object in its completion function
|
||||
* would not work if the 'Usb' session gets closed before the
|
||||
* completion function was called. So we store the pointer in the
|
||||
* otherwise unused 'hcpriv' member and free it in a following
|
||||
* 'usb_submit_urb()' or 'usb_free_urb()' call.
|
||||
*/
|
||||
|
||||
if (urb->hcpriv) {
|
||||
Urb *prev_urb = (Urb*)urb->hcpriv;
|
||||
prev_urb->~Urb();
|
||||
kfree(urb->hcpriv);
|
||||
}
|
||||
|
||||
urb->hcpriv = u;
|
||||
|
||||
u->send();
|
||||
return 0;
|
||||
}
|
||||
@ -81,5 +105,15 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
||||
|
||||
void usb_free_urb(struct urb *urb)
|
||||
{
|
||||
if (!urb)
|
||||
return;
|
||||
|
||||
/* free 'Urb' object */
|
||||
if (urb->hcpriv) {
|
||||
Urb *u = (Urb*)urb->hcpriv;
|
||||
u->~Urb();
|
||||
kfree(urb->hcpriv);
|
||||
}
|
||||
|
||||
kfree(urb);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class Urb : public Usb::Completion
|
||||
urb & _urb;
|
||||
Usb::Packet_descriptor _packet {
|
||||
_usb.source()->alloc_packet(_urb.transfer_buffer_length) };
|
||||
bool _completed { false };
|
||||
|
||||
public:
|
||||
|
||||
@ -79,6 +80,12 @@ class Urb : public Usb::Completion
|
||||
};
|
||||
}
|
||||
|
||||
~Urb()
|
||||
{
|
||||
if (!_completed)
|
||||
_usb.source()->release_packet(_packet);
|
||||
}
|
||||
|
||||
void send()
|
||||
{
|
||||
_usb.source()->submit_packet(_packet);
|
||||
@ -88,6 +95,7 @@ class Urb : public Usb::Completion
|
||||
{
|
||||
if (packet.succeded) {
|
||||
bool ctrl = (usb_pipetype(_urb.pipe) == PIPE_CONTROL);
|
||||
_urb.status = 0;
|
||||
_urb.actual_length = ctrl ? packet.control.actual_size
|
||||
: packet.transfer.actual_size;
|
||||
|
||||
@ -96,10 +104,44 @@ class Urb : public Usb::Completion
|
||||
Genode::memcpy(_urb.transfer_buffer,
|
||||
_usb.source()->packet_content(packet),
|
||||
_urb.actual_length);
|
||||
} else {
|
||||
_urb.actual_length = 0;
|
||||
switch (packet.error) {
|
||||
case Usb::Packet_descriptor::NO_ERROR:
|
||||
Genode::error(__func__, ": got NO_ERROR code in error path");
|
||||
_urb.status = -EIO;
|
||||
break;
|
||||
case Usb::Packet_descriptor::INTERFACE_OR_ENDPOINT_ERROR:
|
||||
_urb.status = -ENOENT;
|
||||
break;
|
||||
case Usb::Packet_descriptor::MEMORY_ERROR:
|
||||
_urb.status = -ENOMEM;
|
||||
break;
|
||||
case Usb::Packet_descriptor::NO_DEVICE_ERROR:
|
||||
_urb.status = -ESHUTDOWN;
|
||||
break;
|
||||
case Usb::Packet_descriptor::PACKET_INVALID_ERROR:
|
||||
_urb.status = -EINVAL;
|
||||
break;
|
||||
case Usb::Packet_descriptor::PROTOCOL_ERROR:
|
||||
_urb.status = -EPROTO;
|
||||
break;
|
||||
case Usb::Packet_descriptor::STALL_ERROR:
|
||||
_urb.status = -EPIPE;
|
||||
break;
|
||||
case Usb::Packet_descriptor::TIMEOUT_ERROR:
|
||||
_urb.status = -ETIMEDOUT;
|
||||
break;
|
||||
case Usb::Packet_descriptor::UNKNOWN_ERROR:
|
||||
Genode::error(__func__, ": got UNKNOWN_ERROR code");
|
||||
_urb.status = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_urb.complete) _urb.complete(&_urb);
|
||||
kfree(_packet.completion);
|
||||
|
||||
_completed = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -82,7 +82,17 @@ struct Usb::Packet_descriptor : Genode::Packet_descriptor
|
||||
};
|
||||
};
|
||||
|
||||
enum Error { NO_ERROR, STALL_ERROR, SUBMIT_ERROR };
|
||||
enum Error {
|
||||
NO_ERROR,
|
||||
INTERFACE_OR_ENDPOINT_ERROR,
|
||||
MEMORY_ERROR,
|
||||
NO_DEVICE_ERROR,
|
||||
PACKET_INVALID_ERROR,
|
||||
PROTOCOL_ERROR,
|
||||
STALL_ERROR,
|
||||
TIMEOUT_ERROR,
|
||||
UNKNOWN_ERROR
|
||||
};
|
||||
|
||||
Error error = NO_ERROR;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user