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