// 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.

#ifndef SRC_DEVICES_USB_DRIVERS_MT_MUSB_HOST_USB_REQUEST_QUEUE_H_
#define SRC_DEVICES_USB_DRIVERS_MT_MUSB_HOST_USB_REQUEST_QUEUE_H_

#include <lib/mmio/mmio.h>
#include <lib/sync/completion.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <threads.h>
#include <zircon/hw/usb.h>
#include <zircon/types.h>

#include <atomic>
#include <memory>

#include <fbl/condition_variable.h>
#include <fbl/mutex.h>
#include <usb/request-cpp.h>

#include "usb-transaction.h"

namespace mt_usb_hci {

// The maximum single-buffered endpoint FIFO size.
constexpr uint32_t kFifoMaxSize = 4096;

// An RequestQueue cultivates a queue of outstanding usb requests and asynchronously services them
// in serial-FIFO order.
class RequestQueue {
 public:
  virtual ~RequestQueue() = default;

  // Advance processing of the current request which may optionally be the result of servicing a
  // hardware IRQ event (in which case interrupt should be set to true).
  virtual void Advance(bool interrupt) = 0;

  // Enqueue a new request for processing.
  virtual zx_status_t QueueRequest(usb::BorrowedRequest<> req) = 0;

  // Start the request processing thread.
  virtual zx_status_t StartQueueThread() = 0;

  // Clear and cancel all currently pending requests from the queue.
  virtual zx_status_t CancelAll() = 0;

  // Return this endpoint's maximum packet transfer size (i.e. wMaxPacketSize).
  virtual size_t GetMaxTransferSize() = 0;

  // Halt endpoint request processing.  All outstanding requests will result in a
  // ZX_ERR_IO_NOT_PRESENT status, and the queue thread will be shut down.
  virtual zx_status_t Halt() = 0;
};

// A TransactionQueue is an RequestQueue which dispatches requests to a Transaction for
// processing.
class TransactionQueue : public RequestQueue {
 public:
  TransactionQueue(ddk::MmioView usb, uint8_t faddr, const usb_endpoint_descriptor_t& descriptor)
      : usb_(usb),
        faddr_(faddr),
        max_pkt_sz_(usb_ep_max_packet(&descriptor)),
        descriptor_(descriptor),
        halted_(false) {}

  ~TransactionQueue() = default;

  void Advance(bool interrupt) override { transaction_->Advance(interrupt); }
  zx_status_t QueueRequest(usb::BorrowedRequest<> req) override;
  zx_status_t StartQueueThread() override;
  zx_status_t CancelAll() override;
  size_t GetMaxTransferSize() override;
  zx_status_t Halt() override;

 protected:
  // The USB register mmio.
  ddk::MmioView usb_;

  // A transaction type used by this endpoint.
  std::unique_ptr<Transaction> transaction_;

  // The id of the device this endpoint is associated with.
  uint8_t faddr_;

  // The maximum usb packet size for this transaction.
  size_t max_pkt_sz_;

  // The enumerated endpoint descriptor describing the behavior of this endpoint.
  usb_endpoint_descriptor_t descriptor_;

  // True if this endpoint has been halted.
  std::atomic_bool halted_;

 private:
  // Dispatch and process a request transaction.  This method blocks until the transaction is
  // complete.
  virtual zx_status_t DispatchRequest(usb::BorrowedRequest<> req) = 0;

  // Queue thread which services enqueued requests in serial FIFO order.
  int QueueThread();

  // The queue of pending usb::BorrowedRequests ready to be dispatched.  Requests are dispatched
  // and processed in FIFO-order.
  usb::BorrowedRequestQueue<> pending_ TA_GUARDED(pending_lock_);

  // Queue dispatch thread.
  thrd_t pending_thread_;

  // Queue dispatch condition and associated mutex.
  fbl::Mutex pending_lock_;
  fbl::ConditionVariable pending_cond_ TA_GUARDED(pending_lock_);
};

// A ControlQueue is a TransactionQueue dispatching control-type transactions.
class ControlQueue : public TransactionQueue {
 public:
  // Note that initially all enumeration control transactions are performed on the default
  // control-pipe address of 0 using the spec. default maximum packet size of 8 bytes (encoded in
  // this type's static descriptor).  During enumeration, these values will be updated to their
  // final configured values.
  explicit ControlQueue(ddk::MmioView usb) : TransactionQueue(usb, 0, descriptor_) {}

  // Read the device descriptor (used only for enumeration).  Note that a successful
  // GET_DESCRIPTOR transaction will result in max_pkt_sz_ being updated with the bMaxPacketSize0
  // as returned by the device.
  zx_status_t GetDeviceDescriptor(usb_device_descriptor_t* out);

  // Set the USB function address for the device this endpoint is associated with (used only for
  // enumeration).  Note that a successful SET_ADDRESS transaction will result in faddr_  being
  // updated with the configured address.
  zx_status_t SetAddress(uint8_t addr);

 private:
  zx_status_t DispatchRequest(usb::BorrowedRequest<> req) override;

  // An endpoint descriptor containing sufficient data to bootstrap a Control transaction.
  static constexpr usb_endpoint_descriptor_t descriptor_ = {
      0,             // .bLength
      0,             // .bDescriptorType
      0,             // .bEndpointAddress
      0,             // .bmAttributes
      htole16(0x8),  // .wMaxPacketSize (the only piece of data consumed)
      0,             // .bInterval
  };
};

// A BulkQueue is a TransactionQueue dispatching bulk-type transactions.
class BulkQueue : public TransactionQueue {
 public:
  BulkQueue(ddk::MmioView usb, uint8_t faddr, const usb_endpoint_descriptor_t& descriptor)
      : TransactionQueue(usb, faddr, descriptor) {}

 private:
  zx_status_t DispatchRequest(usb::BorrowedRequest<> req) override;
};

// An InterruptQueue is a TransactionQueue dispatching interrupt-type transactions.
class InterruptQueue : public TransactionQueue {
 public:
  InterruptQueue(ddk::MmioView usb, uint8_t faddr, const usb_endpoint_descriptor_t& descriptor)
      : TransactionQueue(usb, faddr, descriptor) {}

 private:
  zx_status_t DispatchRequest(usb::BorrowedRequest<> req) override;
};

}  // namespace mt_usb_hci

#endif  // SRC_DEVICES_USB_DRIVERS_MT_MUSB_HOST_USB_REQUEST_QUEUE_H_
