fidl_fuchsia_hardware_block_driver__common/
fidl_fuchsia_hardware_block_driver__common.rs

1// WARNING: This file is machine generated by fidlgen.
2
3#![warn(clippy::all)]
4#![allow(unused_parens, unused_mut, unused_imports, nonstandard_style)]
5
6use bitflags::bitflags;
7use fidl::encoding::{MessageBufFor, ProxyChannelBox, ResourceDialect};
8use futures::future::{self, MaybeDone, TryFutureExt};
9use zx_status;
10
11pub type Vmoid = u16;
12
13pub const BLOCK_GUID_LEN: u32 = 16;
14
15pub const BLOCK_VMOID_INVALID: u16 = 0;
16
17/// Multiple block I/O operations may be sent at once before a response is
18/// actually sent back. Block I/O ops may be sent concurrently to different
19/// vmoids, and they also may be sent to different groups at any point in time.
20///
21/// `MAX_TXN_GROUP_COUNT` "groups" are pre-allocated lanes separated on the
22/// block server.  Using a group allows multiple message to be buffered at once
23/// on a single communication channel before receiving a response.
24///
25/// Usage of groups is identified by the `GROUP_ITEM` flag, and is optional.
26///
27/// These groups may be referred to with a "groupid", in the range [0,
28/// `MAX_TXN_GROUP_COUNT`).
29///
30/// The protocol to communicate with a single group is as follows:
31/// 1) SEND [N - 1] messages with an allocated groupid for any value of 1 <= N.
32///    The `GROUP_ITEM` flag is set for these messages.
33/// 2) SEND a final Nth message with the same groupid. The `GROUP_ITEM
34///    | GROUP_LAST` flags are set for this message.
35/// 3) RECEIVE a single response from the Block I/O server after all N requests
36///    have completed. This response is sent once all operations either complete
37///    or a single operation fails. At this point, step (1) may begin again for
38///    the same groupid.
39///
40/// For `READ` and `WRITE`, N may be greater than 1. Otherwise,
41/// N == 1 (skipping step (1) in the protocol above).
42///
43/// Notes:
44/// - groupids may operate on any number of vmoids at once.
45/// - If additional requests are sent on the same groupid before step (3) has
46///   completed, then the additional request will not be processed. If
47///   `GROUP_LAST` is set, an error will be returned. Otherwise, the
48///   request will be silently dropped.
49/// - Messages within a group are not guaranteed to be processed in any order
50///   relative to each other.
51/// - All requests receive responses, except for ones with `GROUP_ITEM`
52///   that do not have `GROUP_LAST` set.
53///
54/// For example, the following is a valid sequence of transactions:
55///
56///   -> (groupid = 1, vmoid = 1, OP = Write | GroupItem,             reqid = 1)
57///   -> (groupid = 1, vmoid = 2, OP = Write | GroupItem,             reqid = 2)
58///   -> (groupid = 2, vmoid = 3, OP = Write | GroupItem | GroupLast, reqid = 0)
59///   <- Response sent to groupid = 2, reqid = 0
60///   -> (groupid = 1, vmoid = 1, OP = Read | GroupItem | GroupLast,  reqid = 3)
61///   <- Response sent to groupid = 1, reqid = 3
62///   -> (groupid = 3, vmoid = 1, OP = Write | GroupItem,             reqid = 4)
63///   -> (groupid = don't care, vmoid = 1, OP = Read, reqid = 5)
64///   <- Response sent to reqid = 5
65///   -> (groupid = 3, vmoid = 1, OP = Read | GroupItem | GroupLast,  reqid = 6)
66///   <- Response sent to groupid = 3, reqid = 6
67///
68/// Each transaction reads or writes up to `length` blocks from the device,
69/// starting at `dev_offset` blocks, into the VMO associated with `vmoid`,
70/// starting at `vmo_offset` blocks.  If the transaction is out of range, for
71/// example if `length` is too large or if `dev_offset` is beyond the end of the
72/// device, `ZX_ERR_OUT_OF_RANGE` is returned.
73pub const MAX_TXN_GROUP_COUNT: u32 = 8;
74
75bitflags! {
76    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
77    pub struct BlockIoFlag: u32 {
78        /// Associate the following request with `group`.
79        const GROUP_ITEM = 1;
80        /// Only respond after this request (and all previous within group) have
81        /// completed. Only valid with `GROUP_ITEM`.
82        const GROUP_LAST = 2;
83        /// Mark this operation as "Force Unit Access" (FUA), indicating that
84        /// it should not complete until the data is written to the non-volatile
85        /// medium (write), and that reads should bypass any on-device caches.
86        const FORCE_ACCESS = 4;
87        /// Attaches a pre-barrier to a request.  This will ensure that no request which was
88        /// executed before this request will be re-ordered to execute after this request.
89        ///
90        /// NOTE: Barriers do NOT guarantee ordering of in-flight requests.  Any request which the
91        /// client has not yet received a response for is considered in-flight, and no guarantees
92        /// are made about relative ordering with this request.  This has important implications for
93        /// grouped requests:  A request in the middle of a group with PRE_BARRIER set will NOT have
94        /// ordering guarantees relative to the other requests in the same group.
95        const PRE_BARRIER = 8;
96        /// If set, the request is to be decompressed.
97        const DECOMPRESS_WITH_ZSTD = 16;
98    }
99}
100
101impl BlockIoFlag {}
102
103#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
104#[repr(u8)]
105pub enum BlockOpcode {
106    /// Performs a regular data read or write from the device. The operation may
107    /// be cached internally.
108    Read = 1,
109    Write = 2,
110    /// Write any controller or device cached data to nonvolatile storage.
111    Flush = 3,
112    /// Instructs the device to invalidate a number of blocks, making them  usable
113    /// for storing something else. This is basically a "delete" optimization,
114    /// where the device is in charge of discarding the old content without
115    /// clients having to write a given pattern. The operation may be cached
116    /// internally.
117    Trim = 4,
118    /// Detaches the VMO from the block device.
119    CloseVmo = 5,
120}
121
122impl BlockOpcode {
123    #[inline]
124    pub fn from_primitive(prim: u8) -> Option<Self> {
125        match prim {
126            1 => Some(Self::Read),
127            2 => Some(Self::Write),
128            3 => Some(Self::Flush),
129            4 => Some(Self::Trim),
130            5 => Some(Self::CloseVmo),
131            _ => None,
132        }
133    }
134
135    #[inline]
136    pub const fn into_primitive(self) -> u8 {
137        self as u8
138    }
139}
140
141#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
142pub struct BlockCommand {
143    pub opcode: BlockOpcode,
144    pub flags: BlockIoFlag,
145}
146
147impl fidl::Persistable for BlockCommand {}
148
149/// `TRIM`
150#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
151pub struct BlockTrim {
152    /// Opcode and flags.
153    pub command: BlockCommand,
154    /// Transfer length in blocks (0 is invalid).
155    pub length: u32,
156    /// Device offset in blocks.
157    pub offset_dev: u64,
158}
159
160impl fidl::Persistable for BlockTrim {}
161
162#[derive(Clone, Debug, PartialEq)]
163pub struct CommonQueryResponse {
164    pub info: fidl_fuchsia_hardware_block__common::BlockInfo,
165    pub block_op_size: u64,
166}
167
168impl fidl::Persistable for CommonQueryResponse {}
169
170pub mod common_ordinals {
171    pub const QUERY: u64 = 0x1551192b715c20b0;
172    pub const QUEUE: u64 = 0x4d57f58df2b01c6a;
173}
174
175mod internal {
176    use super::*;
177    unsafe impl fidl::encoding::TypeMarker for BlockIoFlag {
178        type Owned = Self;
179
180        #[inline(always)]
181        fn inline_align(_context: fidl::encoding::Context) -> usize {
182            4
183        }
184
185        #[inline(always)]
186        fn inline_size(_context: fidl::encoding::Context) -> usize {
187            4
188        }
189    }
190
191    impl fidl::encoding::ValueTypeMarker for BlockIoFlag {
192        type Borrowed<'a> = Self;
193        #[inline(always)]
194        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
195            *value
196        }
197    }
198
199    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for BlockIoFlag {
200        #[inline]
201        unsafe fn encode(
202            self,
203            encoder: &mut fidl::encoding::Encoder<'_, D>,
204            offset: usize,
205            _depth: fidl::encoding::Depth,
206        ) -> fidl::Result<()> {
207            encoder.debug_check_bounds::<Self>(offset);
208            if self.bits() & Self::all().bits() != self.bits() {
209                return Err(fidl::Error::InvalidBitsValue);
210            }
211            encoder.write_num(self.bits(), offset);
212            Ok(())
213        }
214    }
215
216    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockIoFlag {
217        #[inline(always)]
218        fn new_empty() -> Self {
219            Self::empty()
220        }
221
222        #[inline]
223        unsafe fn decode(
224            &mut self,
225            decoder: &mut fidl::encoding::Decoder<'_, D>,
226            offset: usize,
227            _depth: fidl::encoding::Depth,
228        ) -> fidl::Result<()> {
229            decoder.debug_check_bounds::<Self>(offset);
230            let prim = decoder.read_num::<u32>(offset);
231            *self = Self::from_bits(prim).ok_or(fidl::Error::InvalidBitsValue)?;
232            Ok(())
233        }
234    }
235    unsafe impl fidl::encoding::TypeMarker for BlockOpcode {
236        type Owned = Self;
237
238        #[inline(always)]
239        fn inline_align(_context: fidl::encoding::Context) -> usize {
240            std::mem::align_of::<u8>()
241        }
242
243        #[inline(always)]
244        fn inline_size(_context: fidl::encoding::Context) -> usize {
245            std::mem::size_of::<u8>()
246        }
247
248        #[inline(always)]
249        fn encode_is_copy() -> bool {
250            true
251        }
252
253        #[inline(always)]
254        fn decode_is_copy() -> bool {
255            false
256        }
257    }
258
259    impl fidl::encoding::ValueTypeMarker for BlockOpcode {
260        type Borrowed<'a> = Self;
261        #[inline(always)]
262        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
263            *value
264        }
265    }
266
267    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for BlockOpcode {
268        #[inline]
269        unsafe fn encode(
270            self,
271            encoder: &mut fidl::encoding::Encoder<'_, D>,
272            offset: usize,
273            _depth: fidl::encoding::Depth,
274        ) -> fidl::Result<()> {
275            encoder.debug_check_bounds::<Self>(offset);
276            encoder.write_num(self.into_primitive(), offset);
277            Ok(())
278        }
279    }
280
281    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockOpcode {
282        #[inline(always)]
283        fn new_empty() -> Self {
284            Self::Read
285        }
286
287        #[inline]
288        unsafe fn decode(
289            &mut self,
290            decoder: &mut fidl::encoding::Decoder<'_, D>,
291            offset: usize,
292            _depth: fidl::encoding::Depth,
293        ) -> fidl::Result<()> {
294            decoder.debug_check_bounds::<Self>(offset);
295            let prim = decoder.read_num::<u8>(offset);
296
297            *self = Self::from_primitive(prim).ok_or(fidl::Error::InvalidEnumValue)?;
298            Ok(())
299        }
300    }
301
302    impl fidl::encoding::ValueTypeMarker for BlockCommand {
303        type Borrowed<'a> = &'a Self;
304        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
305            value
306        }
307    }
308
309    unsafe impl fidl::encoding::TypeMarker for BlockCommand {
310        type Owned = Self;
311
312        #[inline(always)]
313        fn inline_align(_context: fidl::encoding::Context) -> usize {
314            4
315        }
316
317        #[inline(always)]
318        fn inline_size(_context: fidl::encoding::Context) -> usize {
319            8
320        }
321    }
322
323    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<BlockCommand, D>
324        for &BlockCommand
325    {
326        #[inline]
327        unsafe fn encode(
328            self,
329            encoder: &mut fidl::encoding::Encoder<'_, D>,
330            offset: usize,
331            _depth: fidl::encoding::Depth,
332        ) -> fidl::Result<()> {
333            encoder.debug_check_bounds::<BlockCommand>(offset);
334            // Delegate to tuple encoding.
335            fidl::encoding::Encode::<BlockCommand, D>::encode(
336                (
337                    <BlockOpcode as fidl::encoding::ValueTypeMarker>::borrow(&self.opcode),
338                    <BlockIoFlag as fidl::encoding::ValueTypeMarker>::borrow(&self.flags),
339                ),
340                encoder,
341                offset,
342                _depth,
343            )
344        }
345    }
346    unsafe impl<
347        D: fidl::encoding::ResourceDialect,
348        T0: fidl::encoding::Encode<BlockOpcode, D>,
349        T1: fidl::encoding::Encode<BlockIoFlag, D>,
350    > fidl::encoding::Encode<BlockCommand, D> for (T0, T1)
351    {
352        #[inline]
353        unsafe fn encode(
354            self,
355            encoder: &mut fidl::encoding::Encoder<'_, D>,
356            offset: usize,
357            depth: fidl::encoding::Depth,
358        ) -> fidl::Result<()> {
359            encoder.debug_check_bounds::<BlockCommand>(offset);
360            // Zero out padding regions. There's no need to apply masks
361            // because the unmasked parts will be overwritten by fields.
362            unsafe {
363                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
364                (ptr as *mut u32).write_unaligned(0);
365            }
366            // Write the fields.
367            self.0.encode(encoder, offset + 0, depth)?;
368            self.1.encode(encoder, offset + 4, depth)?;
369            Ok(())
370        }
371    }
372
373    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockCommand {
374        #[inline(always)]
375        fn new_empty() -> Self {
376            Self {
377                opcode: fidl::new_empty!(BlockOpcode, D),
378                flags: fidl::new_empty!(BlockIoFlag, D),
379            }
380        }
381
382        #[inline]
383        unsafe fn decode(
384            &mut self,
385            decoder: &mut fidl::encoding::Decoder<'_, D>,
386            offset: usize,
387            _depth: fidl::encoding::Depth,
388        ) -> fidl::Result<()> {
389            decoder.debug_check_bounds::<Self>(offset);
390            // Verify that padding bytes are zero.
391            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
392            let padval = unsafe { (ptr as *const u32).read_unaligned() };
393            let mask = 0xffffff00u32;
394            let maskedval = padval & mask;
395            if maskedval != 0 {
396                return Err(fidl::Error::NonZeroPadding {
397                    padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
398                });
399            }
400            fidl::decode!(BlockOpcode, D, &mut self.opcode, decoder, offset + 0, _depth)?;
401            fidl::decode!(BlockIoFlag, D, &mut self.flags, decoder, offset + 4, _depth)?;
402            Ok(())
403        }
404    }
405
406    impl fidl::encoding::ValueTypeMarker for BlockTrim {
407        type Borrowed<'a> = &'a Self;
408        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
409            value
410        }
411    }
412
413    unsafe impl fidl::encoding::TypeMarker for BlockTrim {
414        type Owned = Self;
415
416        #[inline(always)]
417        fn inline_align(_context: fidl::encoding::Context) -> usize {
418            8
419        }
420
421        #[inline(always)]
422        fn inline_size(_context: fidl::encoding::Context) -> usize {
423            24
424        }
425    }
426
427    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<BlockTrim, D>
428        for &BlockTrim
429    {
430        #[inline]
431        unsafe fn encode(
432            self,
433            encoder: &mut fidl::encoding::Encoder<'_, D>,
434            offset: usize,
435            _depth: fidl::encoding::Depth,
436        ) -> fidl::Result<()> {
437            encoder.debug_check_bounds::<BlockTrim>(offset);
438            // Delegate to tuple encoding.
439            fidl::encoding::Encode::<BlockTrim, D>::encode(
440                (
441                    <BlockCommand as fidl::encoding::ValueTypeMarker>::borrow(&self.command),
442                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.length),
443                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.offset_dev),
444                ),
445                encoder,
446                offset,
447                _depth,
448            )
449        }
450    }
451    unsafe impl<
452        D: fidl::encoding::ResourceDialect,
453        T0: fidl::encoding::Encode<BlockCommand, D>,
454        T1: fidl::encoding::Encode<u32, D>,
455        T2: fidl::encoding::Encode<u64, D>,
456    > fidl::encoding::Encode<BlockTrim, D> for (T0, T1, T2)
457    {
458        #[inline]
459        unsafe fn encode(
460            self,
461            encoder: &mut fidl::encoding::Encoder<'_, D>,
462            offset: usize,
463            depth: fidl::encoding::Depth,
464        ) -> fidl::Result<()> {
465            encoder.debug_check_bounds::<BlockTrim>(offset);
466            // Zero out padding regions. There's no need to apply masks
467            // because the unmasked parts will be overwritten by fields.
468            unsafe {
469                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(8);
470                (ptr as *mut u64).write_unaligned(0);
471            }
472            // Write the fields.
473            self.0.encode(encoder, offset + 0, depth)?;
474            self.1.encode(encoder, offset + 8, depth)?;
475            self.2.encode(encoder, offset + 16, depth)?;
476            Ok(())
477        }
478    }
479
480    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockTrim {
481        #[inline(always)]
482        fn new_empty() -> Self {
483            Self {
484                command: fidl::new_empty!(BlockCommand, D),
485                length: fidl::new_empty!(u32, D),
486                offset_dev: fidl::new_empty!(u64, D),
487            }
488        }
489
490        #[inline]
491        unsafe fn decode(
492            &mut self,
493            decoder: &mut fidl::encoding::Decoder<'_, D>,
494            offset: usize,
495            _depth: fidl::encoding::Depth,
496        ) -> fidl::Result<()> {
497            decoder.debug_check_bounds::<Self>(offset);
498            // Verify that padding bytes are zero.
499            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(8) };
500            let padval = unsafe { (ptr as *const u64).read_unaligned() };
501            let mask = 0xffffffff00000000u64;
502            let maskedval = padval & mask;
503            if maskedval != 0 {
504                return Err(fidl::Error::NonZeroPadding {
505                    padding_start: offset + 8 + ((mask as u64).trailing_zeros() / 8) as usize,
506                });
507            }
508            fidl::decode!(BlockCommand, D, &mut self.command, decoder, offset + 0, _depth)?;
509            fidl::decode!(u32, D, &mut self.length, decoder, offset + 8, _depth)?;
510            fidl::decode!(u64, D, &mut self.offset_dev, decoder, offset + 16, _depth)?;
511            Ok(())
512        }
513    }
514
515    impl fidl::encoding::ValueTypeMarker for CommonQueryResponse {
516        type Borrowed<'a> = &'a Self;
517        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
518            value
519        }
520    }
521
522    unsafe impl fidl::encoding::TypeMarker for CommonQueryResponse {
523        type Owned = Self;
524
525        #[inline(always)]
526        fn inline_align(_context: fidl::encoding::Context) -> usize {
527            8
528        }
529
530        #[inline(always)]
531        fn inline_size(_context: fidl::encoding::Context) -> usize {
532            32
533        }
534    }
535
536    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<CommonQueryResponse, D>
537        for &CommonQueryResponse
538    {
539        #[inline]
540        unsafe fn encode(
541            self,
542            encoder: &mut fidl::encoding::Encoder<'_, D>,
543            offset: usize,
544            _depth: fidl::encoding::Depth,
545        ) -> fidl::Result<()> {
546            encoder.debug_check_bounds::<CommonQueryResponse>(offset);
547            // Delegate to tuple encoding.
548            fidl::encoding::Encode::<CommonQueryResponse, D>::encode(
549                (
550                    <fidl_fuchsia_hardware_block__common::BlockInfo as fidl::encoding::ValueTypeMarker>::borrow(&self.info),
551                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.block_op_size),
552                ),
553                encoder, offset, _depth
554            )
555        }
556    }
557    unsafe impl<
558        D: fidl::encoding::ResourceDialect,
559        T0: fidl::encoding::Encode<fidl_fuchsia_hardware_block__common::BlockInfo, D>,
560        T1: fidl::encoding::Encode<u64, D>,
561    > fidl::encoding::Encode<CommonQueryResponse, D> for (T0, T1)
562    {
563        #[inline]
564        unsafe fn encode(
565            self,
566            encoder: &mut fidl::encoding::Encoder<'_, D>,
567            offset: usize,
568            depth: fidl::encoding::Depth,
569        ) -> fidl::Result<()> {
570            encoder.debug_check_bounds::<CommonQueryResponse>(offset);
571            // Zero out padding regions. There's no need to apply masks
572            // because the unmasked parts will be overwritten by fields.
573            // Write the fields.
574            self.0.encode(encoder, offset + 0, depth)?;
575            self.1.encode(encoder, offset + 24, depth)?;
576            Ok(())
577        }
578    }
579
580    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for CommonQueryResponse {
581        #[inline(always)]
582        fn new_empty() -> Self {
583            Self {
584                info: fidl::new_empty!(fidl_fuchsia_hardware_block__common::BlockInfo, D),
585                block_op_size: fidl::new_empty!(u64, D),
586            }
587        }
588
589        #[inline]
590        unsafe fn decode(
591            &mut self,
592            decoder: &mut fidl::encoding::Decoder<'_, D>,
593            offset: usize,
594            _depth: fidl::encoding::Depth,
595        ) -> fidl::Result<()> {
596            decoder.debug_check_bounds::<Self>(offset);
597            // Verify that padding bytes are zero.
598            fidl::decode!(
599                fidl_fuchsia_hardware_block__common::BlockInfo,
600                D,
601                &mut self.info,
602                decoder,
603                offset + 0,
604                _depth
605            )?;
606            fidl::decode!(u64, D, &mut self.block_op_size, decoder, offset + 24, _depth)?;
607            Ok(())
608        }
609    }
610}