1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#include <fbl/intrusive_double_list.h>
8#include <fbl/ref_ptr.h>
9#include <fbl/slab_allocator.h>
10#include <fbl/unique_ptr.h>
11
12#include <dispatcher-pool/dispatcher-channel.h>
13#include <intel-hda/utils/codec-commands.h>
14#include <intel-hda/utils/intel-hda-proto.h>
15
16namespace audio {
17namespace intel_hda {
18
19class IntelHDACodec;
20
21class CodecCmdJob;
22using CodecCmdJobAllocTraits = fbl::StaticSlabAllocatorTraits<fbl::unique_ptr<CodecCmdJob>>;
23using CodecCmdJobAllocator = fbl::SlabAllocator<CodecCmdJobAllocTraits>;
24
25class CodecCmdJob : public fbl::DoublyLinkedListable<fbl::unique_ptr<CodecCmdJob>>,
26                    public fbl::SlabAllocated<CodecCmdJobAllocTraits> {
27public:
28    CodecCommand command()   const { return cmd_; }
29    uint8_t      codec_id()  const { return cmd_.codec_id(); }
30    uint16_t     nid()       const { return cmd_.nid(); }
31    CodecVerb    verb()      const { return cmd_.verb(); }
32
33    const fbl::RefPtr<dispatcher::Channel>& response_channel() const { return response_channel_; }
34    zx_txid_t transaction_id() const { return transaction_id_; }
35
36private:
37    // Only our slab allocators is allowed to construct us, and only the
38    // unique_ptrs it hands out are allowed to destroy us.
39    friend CodecCmdJobAllocator;
40    friend fbl::unique_ptr<CodecCmdJob>;
41
42    CodecCmdJob(CodecCommand cmd) : cmd_(cmd) { }
43    CodecCmdJob(fbl::RefPtr<dispatcher::Channel>&& response_channel,
44                uint32_t transaction_id,
45                CodecCommand cmd)
46        : cmd_(cmd),
47          transaction_id_(transaction_id),
48          response_channel_(fbl::move(response_channel)) { }
49
50    ~CodecCmdJob() = default;
51
52    const CodecCommand cmd_;
53    const zx_txid_t    transaction_id_ = IHDA_INVALID_TRANSACTION_ID;
54    fbl::RefPtr<dispatcher::Channel> response_channel_ = nullptr;
55};
56
57}  // namespace intel_hda
58}  // namespace audio
59
60// Let users of the slab allocator know that the storage for the allocator is
61// instantiated in a separate translation unit.
62FWD_DECL_STATIC_SLAB_ALLOCATOR(::audio::intel_hda::CodecCmdJobAllocTraits);
63