ZXFoundation™ 26h2
Loading...
Searching...
No Matches
subchannel.cxxm
1/// SPDX-License-Identifier: Apache-2.0
2/// @file arch/s390x/io/css.cxxm
3/// @brief Channel Subsystem core — privileged I/O instruction wrappers and
4/// subchannel table management (PoP Chapter 14).
5
6export module arch.s390x.io.css.subchannel;
7import arch.s390x.io.types;
8import zxfoundation.base.types;
9import zxfoundation.sync.waitqueue.types;
10import lib.error;
11import std;
12
13export {
14
15namespace arch::s390x::io::css {
16
17 /// @brief Lifecycle state of a subchannel entry.
18 enum class subchannel_state : u8 {
19 free = 0, ///< Slot is unused.
20 probing = 1, ///< Currently being probed during init.
21 idle = 2, ///< Probed and enabled, ready for I/O.
22 active = 3, ///< I/O operation is in progress.
23 halting = 4, ///< Halt or clear has been issued.
24 };
25
26 /// @brief Kernel I/O completion sink.
27 using io_completion_sink_fn = void (*)(
28 u32 sch_index, u32 binding_id, u32 binding_generation,
29 const irb& status
30 ) noexcept;
31
32 /// @brief Per-subchannel bookkeeping entry.
33 struct subchannel_entry {
34 subchannel_id schid{};
35 senseid_data sense{};
36 subchannel_state state{subchannel_state::free};
37 zxfoundation::sync::waitqueue::wait_head io_wait{};
38 irb last_irb{};
39 std::atomic<u32> io_done{0};
40 u16 devno{0xFFFF};
41 u8 available_lpm{0};
42 u8 _pad0[1]{};
43 u32 binding_id{~0U};
44 u32 binding_generation{0};
45 u32 active_binding_id{~0U};
46
47 // Non-copyable, non-movable — identity is table slot address.
48 subchannel_entry() noexcept = default;
49 subchannel_entry(const subchannel_entry&) = delete;
50 subchannel_entry(subchannel_entry&&) = delete;
51 auto operator=(const subchannel_entry&) = delete;
52 auto operator=(subchannel_entry&&) = delete;
53 };
54
55 /// @brief Probe all subchannels, enable valid ones, and populate the table.
56 auto init() noexcept -> void;
57
58 /// @brief Start I/O on a subchannel.
59 /// @param sch_index Index into the subchannel table.
60 /// @param orb_ref Prepared Operation Request Block.
61 /// @return Ok on CC=0; driver_error on failure.
62 [[nodiscard]] auto start_io(u32 sch_index, orb& orb_ref) noexcept
63 -> ::std::expected<void, ::lib::kernel_error>;
64
65 /// @brief Install the nucleus I/O completion sink.
66 [[nodiscard]] auto install_completion_sink(
67 io_completion_sink_fn sink
68 ) noexcept -> ::std::expected<void, ::lib::kernel_error>;
69
70 /// @brief Exclusively associate an active I/O binding with a subchannel.
71 [[nodiscard]] auto claim_binding(
72 u32 sch_index, u32 binding_id, u32 binding_generation
73 ) noexcept -> ::std::expected<void, ::lib::kernel_error>;
74
75 /// @brief Remove an exact subchannel-binding association after I/O fencing.
76 [[nodiscard]] auto release_binding(
77 u32 sch_index, u32 binding_id, u32 binding_generation
78 ) noexcept -> ::std::expected<void, ::lib::kernel_error>;
79
80 /// @brief Return the hardware-available logical path mask for a binding.
81 [[nodiscard]] auto available_lpm(u32 sch_index) noexcept -> u8;
82
83 /// @brief Test I/O on a subchannel (issue TSCH).
84 /// @param sch_index Index into the subchannel table.
85 /// @param irb_ref Output Interruption Response Block.
86 /// @return Condition code on success; driver_error on failure.
87 [[nodiscard]] auto test_io(u32 sch_index, irb& irb_ref) noexcept
88 -> ::std::expected<condition_code, ::lib::kernel_error>;
89
90 /// @brief Halt I/O on a subchannel (issue HSCH).
91 /// @param sch_index Index into the subchannel table.
92 /// @return Ok on CC=0; driver_error on failure.
93 [[nodiscard]] auto halt_io(u32 sch_index) noexcept
94 -> ::std::expected<void, ::lib::kernel_error>;
95
96 /// @brief Clear I/O on a subchannel (issue CSCH).
97 /// @param sch_index Index into the subchannel table.
98 /// @return Ok on CC=0; driver_error on failure.
99 [[nodiscard]] auto clear_io(u32 sch_index) noexcept
100 -> ::std::expected<void, ::lib::kernel_error>;
101
102 /// @brief Called from the I/O interrupt handler to drain status.
103 /// @param sch_no Raw subchannel number from the I/O old PSW area.
104 auto io_interrupt(u32 sch_no) noexcept -> void;
105
106 /// @brief Find a subchannel by SENSE-ID device type and model.
107 /// @param dev_type Device type from senseid_data.
108 /// @param dev_model Device model from senseid_data.
109 /// @return Table index on success; not_found error otherwise.
110 [[nodiscard]] auto find_device(u16 dev_type, u16 dev_model) noexcept
111 -> ::std::expected<u32, ::lib::kernel_error>;
112
113 /// @brief Return the number of probed subchannels.
114 [[nodiscard]] auto subchannel_count() noexcept -> u32;
115
116 /// @brief Return a pointer to a subchannel entry by index.
117 /// @param index Index into the subchannel table.
118 /// @return Pointer to the entry, or nullptr if index is out of range.
119 [[nodiscard]] auto get_entry(u32 index) noexcept -> subchannel_entry*;
120
121} // namespace arch::s390x::io::css
122
123} // end export