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        /// Allows for delayed in-order flushing of cached data. Ensures that no request executed
88        /// before the barrier will be re-ordered to execute after the barrier. Barriers do not
89        /// guarantee ordering of in-flight requests (i.e. if a request is made prior to a barrier
90        /// but is not completed before the barrier, the request could be reordered to execute
91        /// after the barrier). The barrier will be applied before the request it was sent with.
92        /// Note that between two barriers, the device is free to execute requests in any order.
93        const PRE_BARRIER = 8;
94        /// If set, the request is to be decompressed.
95        const DECOMPRESS_WITH_ZSTD = 16;
96    }
97}
98
99impl BlockIoFlag {}
100
101#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
102#[repr(u8)]
103pub enum BlockOpcode {
104    /// Performs a regular data read or write from the device. The operation may
105    /// be cached internally.
106    Read = 1,
107    Write = 2,
108    /// Write any controller or device cached data to nonvolatile storage.
109    Flush = 3,
110    /// Instructs the device to invalidate a number of blocks, making them  usable
111    /// for storing something else. This is basically a "delete" optimization,
112    /// where the device is in charge of discarding the old content without
113    /// clients having to write a given pattern. The operation may be cached
114    /// internally.
115    Trim = 4,
116    /// Detaches the VMO from the block device.
117    CloseVmo = 5,
118}
119
120impl BlockOpcode {
121    #[inline]
122    pub fn from_primitive(prim: u8) -> Option<Self> {
123        match prim {
124            1 => Some(Self::Read),
125            2 => Some(Self::Write),
126            3 => Some(Self::Flush),
127            4 => Some(Self::Trim),
128            5 => Some(Self::CloseVmo),
129            _ => None,
130        }
131    }
132
133    #[inline]
134    pub const fn into_primitive(self) -> u8 {
135        self as u8
136    }
137}
138
139#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
140pub struct BlockCommand {
141    pub opcode: BlockOpcode,
142    pub flags: BlockIoFlag,
143}
144
145impl fidl::Persistable for BlockCommand {}
146
147/// `TRIM`
148#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
149pub struct BlockTrim {
150    /// Opcode and flags.
151    pub command: BlockCommand,
152    /// Transfer length in blocks (0 is invalid).
153    pub length: u32,
154    /// Device offset in blocks.
155    pub offset_dev: u64,
156}
157
158impl fidl::Persistable for BlockTrim {}
159
160#[derive(Clone, Debug, PartialEq)]
161pub struct CommonQueryResponse {
162    pub info: fidl_fuchsia_hardware_block__common::BlockInfo,
163    pub block_op_size: u64,
164}
165
166impl fidl::Persistable for CommonQueryResponse {}
167
168pub mod common_ordinals {
169    pub const QUERY: u64 = 0x1551192b715c20b0;
170    pub const QUEUE: u64 = 0x4d57f58df2b01c6a;
171}
172
173mod internal {
174    use super::*;
175    unsafe impl fidl::encoding::TypeMarker for BlockIoFlag {
176        type Owned = Self;
177
178        #[inline(always)]
179        fn inline_align(_context: fidl::encoding::Context) -> usize {
180            4
181        }
182
183        #[inline(always)]
184        fn inline_size(_context: fidl::encoding::Context) -> usize {
185            4
186        }
187    }
188
189    impl fidl::encoding::ValueTypeMarker for BlockIoFlag {
190        type Borrowed<'a> = Self;
191        #[inline(always)]
192        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
193            *value
194        }
195    }
196
197    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for BlockIoFlag {
198        #[inline]
199        unsafe fn encode(
200            self,
201            encoder: &mut fidl::encoding::Encoder<'_, D>,
202            offset: usize,
203            _depth: fidl::encoding::Depth,
204        ) -> fidl::Result<()> {
205            encoder.debug_check_bounds::<Self>(offset);
206            if self.bits() & Self::all().bits() != self.bits() {
207                return Err(fidl::Error::InvalidBitsValue);
208            }
209            encoder.write_num(self.bits(), offset);
210            Ok(())
211        }
212    }
213
214    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockIoFlag {
215        #[inline(always)]
216        fn new_empty() -> Self {
217            Self::empty()
218        }
219
220        #[inline]
221        unsafe fn decode(
222            &mut self,
223            decoder: &mut fidl::encoding::Decoder<'_, D>,
224            offset: usize,
225            _depth: fidl::encoding::Depth,
226        ) -> fidl::Result<()> {
227            decoder.debug_check_bounds::<Self>(offset);
228            let prim = decoder.read_num::<u32>(offset);
229            *self = Self::from_bits(prim).ok_or(fidl::Error::InvalidBitsValue)?;
230            Ok(())
231        }
232    }
233    unsafe impl fidl::encoding::TypeMarker for BlockOpcode {
234        type Owned = Self;
235
236        #[inline(always)]
237        fn inline_align(_context: fidl::encoding::Context) -> usize {
238            std::mem::align_of::<u8>()
239        }
240
241        #[inline(always)]
242        fn inline_size(_context: fidl::encoding::Context) -> usize {
243            std::mem::size_of::<u8>()
244        }
245
246        #[inline(always)]
247        fn encode_is_copy() -> bool {
248            true
249        }
250
251        #[inline(always)]
252        fn decode_is_copy() -> bool {
253            false
254        }
255    }
256
257    impl fidl::encoding::ValueTypeMarker for BlockOpcode {
258        type Borrowed<'a> = Self;
259        #[inline(always)]
260        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
261            *value
262        }
263    }
264
265    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<Self, D> for BlockOpcode {
266        #[inline]
267        unsafe fn encode(
268            self,
269            encoder: &mut fidl::encoding::Encoder<'_, D>,
270            offset: usize,
271            _depth: fidl::encoding::Depth,
272        ) -> fidl::Result<()> {
273            encoder.debug_check_bounds::<Self>(offset);
274            encoder.write_num(self.into_primitive(), offset);
275            Ok(())
276        }
277    }
278
279    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockOpcode {
280        #[inline(always)]
281        fn new_empty() -> Self {
282            Self::Read
283        }
284
285        #[inline]
286        unsafe fn decode(
287            &mut self,
288            decoder: &mut fidl::encoding::Decoder<'_, D>,
289            offset: usize,
290            _depth: fidl::encoding::Depth,
291        ) -> fidl::Result<()> {
292            decoder.debug_check_bounds::<Self>(offset);
293            let prim = decoder.read_num::<u8>(offset);
294
295            *self = Self::from_primitive(prim).ok_or(fidl::Error::InvalidEnumValue)?;
296            Ok(())
297        }
298    }
299
300    impl fidl::encoding::ValueTypeMarker for BlockCommand {
301        type Borrowed<'a> = &'a Self;
302        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
303            value
304        }
305    }
306
307    unsafe impl fidl::encoding::TypeMarker for BlockCommand {
308        type Owned = Self;
309
310        #[inline(always)]
311        fn inline_align(_context: fidl::encoding::Context) -> usize {
312            4
313        }
314
315        #[inline(always)]
316        fn inline_size(_context: fidl::encoding::Context) -> usize {
317            8
318        }
319    }
320
321    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<BlockCommand, D>
322        for &BlockCommand
323    {
324        #[inline]
325        unsafe fn encode(
326            self,
327            encoder: &mut fidl::encoding::Encoder<'_, D>,
328            offset: usize,
329            _depth: fidl::encoding::Depth,
330        ) -> fidl::Result<()> {
331            encoder.debug_check_bounds::<BlockCommand>(offset);
332            // Delegate to tuple encoding.
333            fidl::encoding::Encode::<BlockCommand, D>::encode(
334                (
335                    <BlockOpcode as fidl::encoding::ValueTypeMarker>::borrow(&self.opcode),
336                    <BlockIoFlag as fidl::encoding::ValueTypeMarker>::borrow(&self.flags),
337                ),
338                encoder,
339                offset,
340                _depth,
341            )
342        }
343    }
344    unsafe impl<
345        D: fidl::encoding::ResourceDialect,
346        T0: fidl::encoding::Encode<BlockOpcode, D>,
347        T1: fidl::encoding::Encode<BlockIoFlag, D>,
348    > fidl::encoding::Encode<BlockCommand, D> for (T0, T1)
349    {
350        #[inline]
351        unsafe fn encode(
352            self,
353            encoder: &mut fidl::encoding::Encoder<'_, D>,
354            offset: usize,
355            depth: fidl::encoding::Depth,
356        ) -> fidl::Result<()> {
357            encoder.debug_check_bounds::<BlockCommand>(offset);
358            // Zero out padding regions. There's no need to apply masks
359            // because the unmasked parts will be overwritten by fields.
360            unsafe {
361                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(0);
362                (ptr as *mut u32).write_unaligned(0);
363            }
364            // Write the fields.
365            self.0.encode(encoder, offset + 0, depth)?;
366            self.1.encode(encoder, offset + 4, depth)?;
367            Ok(())
368        }
369    }
370
371    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockCommand {
372        #[inline(always)]
373        fn new_empty() -> Self {
374            Self {
375                opcode: fidl::new_empty!(BlockOpcode, D),
376                flags: fidl::new_empty!(BlockIoFlag, D),
377            }
378        }
379
380        #[inline]
381        unsafe fn decode(
382            &mut self,
383            decoder: &mut fidl::encoding::Decoder<'_, D>,
384            offset: usize,
385            _depth: fidl::encoding::Depth,
386        ) -> fidl::Result<()> {
387            decoder.debug_check_bounds::<Self>(offset);
388            // Verify that padding bytes are zero.
389            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(0) };
390            let padval = unsafe { (ptr as *const u32).read_unaligned() };
391            let mask = 0xffffff00u32;
392            let maskedval = padval & mask;
393            if maskedval != 0 {
394                return Err(fidl::Error::NonZeroPadding {
395                    padding_start: offset + 0 + ((mask as u64).trailing_zeros() / 8) as usize,
396                });
397            }
398            fidl::decode!(BlockOpcode, D, &mut self.opcode, decoder, offset + 0, _depth)?;
399            fidl::decode!(BlockIoFlag, D, &mut self.flags, decoder, offset + 4, _depth)?;
400            Ok(())
401        }
402    }
403
404    impl fidl::encoding::ValueTypeMarker for BlockTrim {
405        type Borrowed<'a> = &'a Self;
406        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
407            value
408        }
409    }
410
411    unsafe impl fidl::encoding::TypeMarker for BlockTrim {
412        type Owned = Self;
413
414        #[inline(always)]
415        fn inline_align(_context: fidl::encoding::Context) -> usize {
416            8
417        }
418
419        #[inline(always)]
420        fn inline_size(_context: fidl::encoding::Context) -> usize {
421            24
422        }
423    }
424
425    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<BlockTrim, D>
426        for &BlockTrim
427    {
428        #[inline]
429        unsafe fn encode(
430            self,
431            encoder: &mut fidl::encoding::Encoder<'_, D>,
432            offset: usize,
433            _depth: fidl::encoding::Depth,
434        ) -> fidl::Result<()> {
435            encoder.debug_check_bounds::<BlockTrim>(offset);
436            // Delegate to tuple encoding.
437            fidl::encoding::Encode::<BlockTrim, D>::encode(
438                (
439                    <BlockCommand as fidl::encoding::ValueTypeMarker>::borrow(&self.command),
440                    <u32 as fidl::encoding::ValueTypeMarker>::borrow(&self.length),
441                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.offset_dev),
442                ),
443                encoder,
444                offset,
445                _depth,
446            )
447        }
448    }
449    unsafe impl<
450        D: fidl::encoding::ResourceDialect,
451        T0: fidl::encoding::Encode<BlockCommand, D>,
452        T1: fidl::encoding::Encode<u32, D>,
453        T2: fidl::encoding::Encode<u64, D>,
454    > fidl::encoding::Encode<BlockTrim, D> for (T0, T1, T2)
455    {
456        #[inline]
457        unsafe fn encode(
458            self,
459            encoder: &mut fidl::encoding::Encoder<'_, D>,
460            offset: usize,
461            depth: fidl::encoding::Depth,
462        ) -> fidl::Result<()> {
463            encoder.debug_check_bounds::<BlockTrim>(offset);
464            // Zero out padding regions. There's no need to apply masks
465            // because the unmasked parts will be overwritten by fields.
466            unsafe {
467                let ptr = encoder.buf.as_mut_ptr().add(offset).offset(8);
468                (ptr as *mut u64).write_unaligned(0);
469            }
470            // Write the fields.
471            self.0.encode(encoder, offset + 0, depth)?;
472            self.1.encode(encoder, offset + 8, depth)?;
473            self.2.encode(encoder, offset + 16, depth)?;
474            Ok(())
475        }
476    }
477
478    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for BlockTrim {
479        #[inline(always)]
480        fn new_empty() -> Self {
481            Self {
482                command: fidl::new_empty!(BlockCommand, D),
483                length: fidl::new_empty!(u32, D),
484                offset_dev: fidl::new_empty!(u64, D),
485            }
486        }
487
488        #[inline]
489        unsafe fn decode(
490            &mut self,
491            decoder: &mut fidl::encoding::Decoder<'_, D>,
492            offset: usize,
493            _depth: fidl::encoding::Depth,
494        ) -> fidl::Result<()> {
495            decoder.debug_check_bounds::<Self>(offset);
496            // Verify that padding bytes are zero.
497            let ptr = unsafe { decoder.buf.as_ptr().add(offset).offset(8) };
498            let padval = unsafe { (ptr as *const u64).read_unaligned() };
499            let mask = 0xffffffff00000000u64;
500            let maskedval = padval & mask;
501            if maskedval != 0 {
502                return Err(fidl::Error::NonZeroPadding {
503                    padding_start: offset + 8 + ((mask as u64).trailing_zeros() / 8) as usize,
504                });
505            }
506            fidl::decode!(BlockCommand, D, &mut self.command, decoder, offset + 0, _depth)?;
507            fidl::decode!(u32, D, &mut self.length, decoder, offset + 8, _depth)?;
508            fidl::decode!(u64, D, &mut self.offset_dev, decoder, offset + 16, _depth)?;
509            Ok(())
510        }
511    }
512
513    impl fidl::encoding::ValueTypeMarker for CommonQueryResponse {
514        type Borrowed<'a> = &'a Self;
515        fn borrow(value: &<Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'_> {
516            value
517        }
518    }
519
520    unsafe impl fidl::encoding::TypeMarker for CommonQueryResponse {
521        type Owned = Self;
522
523        #[inline(always)]
524        fn inline_align(_context: fidl::encoding::Context) -> usize {
525            8
526        }
527
528        #[inline(always)]
529        fn inline_size(_context: fidl::encoding::Context) -> usize {
530            32
531        }
532    }
533
534    unsafe impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Encode<CommonQueryResponse, D>
535        for &CommonQueryResponse
536    {
537        #[inline]
538        unsafe fn encode(
539            self,
540            encoder: &mut fidl::encoding::Encoder<'_, D>,
541            offset: usize,
542            _depth: fidl::encoding::Depth,
543        ) -> fidl::Result<()> {
544            encoder.debug_check_bounds::<CommonQueryResponse>(offset);
545            // Delegate to tuple encoding.
546            fidl::encoding::Encode::<CommonQueryResponse, D>::encode(
547                (
548                    <fidl_fuchsia_hardware_block__common::BlockInfo as fidl::encoding::ValueTypeMarker>::borrow(&self.info),
549                    <u64 as fidl::encoding::ValueTypeMarker>::borrow(&self.block_op_size),
550                ),
551                encoder, offset, _depth
552            )
553        }
554    }
555    unsafe impl<
556        D: fidl::encoding::ResourceDialect,
557        T0: fidl::encoding::Encode<fidl_fuchsia_hardware_block__common::BlockInfo, D>,
558        T1: fidl::encoding::Encode<u64, D>,
559    > fidl::encoding::Encode<CommonQueryResponse, D> for (T0, T1)
560    {
561        #[inline]
562        unsafe fn encode(
563            self,
564            encoder: &mut fidl::encoding::Encoder<'_, D>,
565            offset: usize,
566            depth: fidl::encoding::Depth,
567        ) -> fidl::Result<()> {
568            encoder.debug_check_bounds::<CommonQueryResponse>(offset);
569            // Zero out padding regions. There's no need to apply masks
570            // because the unmasked parts will be overwritten by fields.
571            // Write the fields.
572            self.0.encode(encoder, offset + 0, depth)?;
573            self.1.encode(encoder, offset + 24, depth)?;
574            Ok(())
575        }
576    }
577
578    impl<D: fidl::encoding::ResourceDialect> fidl::encoding::Decode<Self, D> for CommonQueryResponse {
579        #[inline(always)]
580        fn new_empty() -> Self {
581            Self {
582                info: fidl::new_empty!(fidl_fuchsia_hardware_block__common::BlockInfo, D),
583                block_op_size: fidl::new_empty!(u64, D),
584            }
585        }
586
587        #[inline]
588        unsafe fn decode(
589            &mut self,
590            decoder: &mut fidl::encoding::Decoder<'_, D>,
591            offset: usize,
592            _depth: fidl::encoding::Depth,
593        ) -> fidl::Result<()> {
594            decoder.debug_check_bounds::<Self>(offset);
595            // Verify that padding bytes are zero.
596            fidl::decode!(
597                fidl_fuchsia_hardware_block__common::BlockInfo,
598                D,
599                &mut self.info,
600                decoder,
601                offset + 0,
602                _depth
603            )?;
604            fidl::decode!(u64, D, &mut self.block_op_size, decoder, offset + 24, _depth)?;
605            Ok(())
606        }
607    }
608}