blob: cae38b2341e765a17e7f51e253d9280878337a00 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/devices/usb/drivers/usb-virtual-bus/usb-virtual-device.h"
#include "src/devices/usb/drivers/usb-virtual-bus/usb-virtual-bus.h"
namespace usb_virtual_bus {
void UsbVirtualDevice::on_fidl_error(fidl::UnbindInfo error) {
bus_->FinishRemove<UsbVirtualDevice>();
}
void UsbVirtualDevice::UsbDciRequestQueue(usb_request_t* usb_request,
const usb_request_complete_callback_t* complete_cb) {
Request request(usb_request, *complete_cb, sizeof(usb_request_t));
uint8_t index = EpAddressToIndex(request.request()->header.ep_address);
if (index >= USB_MAX_EPS) {
FDF_LOG(ERROR, "usb_virtual_bus_device_queue bad endpoint %u\n",
request.request()->header.ep_address);
request.Complete(ZX_ERR_INVALID_ARGS, 0);
return;
}
bus_->ep(index).device_.QueueRequest(std::move(request));
}
zx_status_t UsbVirtualDevice::UsbDciSetInterface(const usb_dci_interface_protocol_t* interface) {
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t UsbVirtualDevice::UsbDciConfigEp(const usb_endpoint_descriptor_t* ep_desc,
const usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
uint8_t index = EpAddressToIndex(usb_ep_num(ep_desc));
if (index >= USB_MAX_EPS) {
return ZX_ERR_INVALID_ARGS;
}
bus_->ep(index).max_packet_size_ = usb_ep_max_packet(ep_desc);
return ZX_OK;
}
zx_status_t UsbVirtualDevice::UsbDciDisableEp(uint8_t ep_address) { return ZX_OK; }
zx_status_t UsbVirtualDevice::UsbDciEpSetStall(uint8_t ep_address) {
uint8_t index = EpAddressToIndex(ep_address);
if (index >= USB_MAX_EPS) {
return ZX_ERR_INVALID_ARGS;
}
return bus_->ep(index).SetStall(true).status_value();
}
zx_status_t UsbVirtualDevice::UsbDciEpClearStall(uint8_t ep_address) {
uint8_t index = EpAddressToIndex(ep_address);
if (index >= USB_MAX_EPS) {
return ZX_ERR_INVALID_ARGS;
}
return bus_->ep(index).SetStall(false).status_value();
}
zx_status_t UsbVirtualDevice::UsbDciCancelAll(uint8_t endpoint) {
uint8_t index = EpAddressToIndex(endpoint);
if (index >= USB_MAX_EPS) {
return ZX_ERR_INVALID_ARGS;
}
bus_->ep(index).device_.CommonCancelAll();
return ZX_OK;
}
size_t UsbVirtualDevice::UsbDciGetRequestSize() {
return Request::RequestSize(Request::RequestSize(sizeof(usb_request_t)));
}
void UsbVirtualDevice::ConnectToEndpoint(ConnectToEndpointRequest& request,
ConnectToEndpointCompleter::Sync& completer) {
uint8_t index = EpAddressToIndex(request.ep_addr());
if (index >= USB_MAX_EPS) {
completer.Reply(zx::error(ZX_ERR_INVALID_ARGS));
return;
}
bus_->ep(index).device_.Connect(std::move(request.ep()));
completer.Reply(zx::ok());
}
void UsbVirtualDevice::SetInterface(SetInterfaceRequest& request,
SetInterfaceCompleter::Sync& completer) {
completer.Reply(bus_->SetDciInterface(std::move(request.interface())));
}
void UsbVirtualDevice::StartController(StartControllerCompleter::Sync& completer) {
bus_->FinishConnect();
completer.Reply(zx::ok());
}
void UsbVirtualDevice::StopController(StopControllerCompleter::Sync& completer) {
bus_->SetConnected(false);
completer.Reply(zx::ok());
}
void UsbVirtualDevice::ConfigureEndpoint(ConfigureEndpointRequest& request,
ConfigureEndpointCompleter::Sync& completer) {
uint8_t index = EpAddressToIndex(request.ep_descriptor().b_endpoint_address());
if (index >= USB_MAX_EPS) {
completer.Reply(zx::error(ZX_ERR_INVALID_ARGS));
return;
}
bus_->ep(index).max_packet_size_ = usb_ep_max_packet2(request.ep_descriptor());
completer.Reply(zx::ok());
}
void UsbVirtualDevice::DisableEndpoint(DisableEndpointRequest& request,
DisableEndpointCompleter::Sync& completer) {
zx_status_t status = UsbDciDisableEp(request.ep_address());
if (status != ZX_OK) {
completer.Reply(zx::error(status));
return;
}
completer.Reply(zx::ok());
}
void UsbVirtualDevice::EndpointSetStall(EndpointSetStallRequest& request,
EndpointSetStallCompleter::Sync& completer) {
zx_status_t status = UsbDciEpSetStall(request.ep_address());
if (status != ZX_OK) {
completer.Reply(zx::error(status));
return;
}
completer.Reply(zx::ok());
}
void UsbVirtualDevice::EndpointClearStall(EndpointClearStallRequest& request,
EndpointClearStallCompleter::Sync& completer) {
zx_status_t status = UsbDciEpClearStall(request.ep_address());
if (status != ZX_OK) {
completer.Reply(zx::error(status));
return;
}
completer.Reply(zx::ok());
}
void UsbVirtualDevice::CancelAll(CancelAllRequest& request, CancelAllCompleter::Sync& completer) {
zx_status_t status = UsbDciCancelAll(request.ep_address());
if (status != ZX_OK) {
completer.Reply(zx::error(status));
return;
}
completer.Reply(zx::ok());
}
} // namespace usb_virtual_bus