// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef DARWINN_DRIVER_USB_USB_IO_REQUEST_H_ #define DARWINN_DRIVER_USB_USB_IO_REQUEST_H_ #include #include "driver/device_buffer.h" #include "driver/dma_chunker.h" #include "driver/dma_info.h" #include "driver/usb/usb_ml_commands.h" namespace platforms { namespace darwinn { namespace driver { // Entry for either a hint, generated by code generator at compile time, or a // request, submitted by device at run time. class UsbIoRequest { public: // Basic type of the hint/request. enum class Type { // This is a bulk out request. Data is sent from host to device. kBulkOut = 0, // This is a bulk in request. Data is sent from device to host. kBulkIn, // This is an interrupt event. Signal is sent from device to host. kScHostInterrupt, }; enum class SourceAndMatchStatus { // This is a hint, and we haven't seen a matching request from device. kHintNotYetMatched = 0, // This is a hint, and we have received a matching request from device. kHintAlreadyMatched, // This is a request submitted by device. kSubmittedByDevice, }; // Constructor for device descriptors. UsbIoRequest(int id, UsbMlCommands::DescriptorTag tag); UsbIoRequest(int id, Type type, UsbMlCommands::DescriptorTag tag, const DeviceBuffer& buffer); // Constructor for DMA hints. UsbIoRequest(DmaInfo* dma_info); // Accessors. Type GetType() const { return type_; } UsbMlCommands::DescriptorTag GetTag() const { return tag_; } SourceAndMatchStatus GetSourceAndMatchStatus() const { return source_and_match_status_; } const DeviceBuffer& GetBuffer() const { return chunker_.buffer(); } // Returns true if in given state. bool IsHeaderSent() const { return !header_.empty(); } bool IsActive() const { return chunker_.IsActive(); } bool IsCompleted() const { if (!chunker_.IsCompleted()) { return false; } // Interrupt will be always come through descriptor path. // It is completed when it was matched with hint, or submitted by device. if (type_ == Type::kScHostInterrupt) { return source_and_match_status_ != SourceAndMatchStatus::kHintNotYetMatched; } return true; } // Returns true if there is chunk to transfer. bool HasNextChunk() const { return chunker_.HasNextChunk(); } // Returns not yet transferred chunk. DeviceBuffer GetNextChunk() { return chunker_.GetNextChunk(); } // Returns a next chunk upto "num_bytes". DeviceBuffer GetNextChunk(int num_bytes) { return chunker_.GetNextChunk(num_bytes); } // Notifies that "num_bytes" of transfer is completed. void NotifyTransferComplete(int num_bytes) { chunker_.NotifyTransfer(num_bytes); } // Returns number of active chunks assuming each chunk is "bytes". int GetActiveCounts(int bytes) const { return chunker_.GetActiveCounts(bytes); } // Marks this hint as it has been matched with a request/event sent from // device. void SetMatched(); // Returns header. const std::vector& header() const { return header_; } // Sets header. void SetHeader(const std::vector& header) { header_ = header; } void SetHeader(std::vector&& header) { header_ = std::move(header); } // Returns true if created from DMA hint. bool FromDmaHint() const { return dma_info_ != nullptr; } DmaInfo* dma_info() const { return dma_info_; } // Returns id. int id() const { return id_; } private: // ID for debugging purpose. const int id_; // Is this a hint or a request. If it's a hint, has it been matched with // soemthing sent from device? SourceAndMatchStatus source_and_match_status_; // Basic type of the hint/request. const Type type_; // Tag is more detailed information under Type. For example, a bulk out type // could be instruction, parameters, or input activations. const UsbMlCommands::DescriptorTag tag_; // DMA chunker. DmaChunker chunker_; // Contains valid pointer to DMA info if this is for hint. DmaInfo* dma_info_{nullptr}; // Stores header used in single endpoint mode. std::vector header_; }; } // namespace driver } // namespace darwinn } // namespace platforms #endif // DARWINN_DRIVER_USB_USB_IO_REQUEST_H_