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