1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#pragma once 6 7#include <ddk/driver.h> 8#include <ddk/protocol/block.h> 9#include <ddktl/protocol/block-internal.h> 10#include <fbl/type_support.h> 11#include <fbl/unique_ptr.h> 12#include <zircon/assert.h> 13 14// DDK block protocol support 15// 16// :: Mixins :: 17// 18// ddk::BlockIfc and ddk::BlockProtocol are mixin classes that simplify writing DDK drivers that 19// interact with the block protocol. They take care of implementing the function pointer tables 20// and calling into the object that wraps them. 21// 22// :: Examples :: 23// 24// // A driver that implements a ZX_PROTOCOL_BLOCK_IMPL device 25// class BlockDevice; 26// using BlockDeviceType = ddk::Device<BlockDevice, /* ddk mixins */>; 27// 28// class BlockDevice : public BlockDeviceType, 29// public ddk::BlockProtocol<BlockDevice> { 30// public: 31// BlockDevice(zx_device_t* parent) 32// : BlockDeviceType("my-block-device", parent) {} 33// 34// zx_status_t Bind() { 35// DdkAdd(); 36// } 37// 38// void DdkRelease() { 39// // Clean up 40// } 41// 42// ... 43// private: 44// ... 45// }; 46 47namespace ddk { 48 49template <typename D> 50class BlockProtocol : public internal::base_protocol { 51public: 52 BlockProtocol() { 53 internal::CheckBlockProtocolSubclass<D>(); 54 ops_.query = Query; 55 ops_.queue = Queue; 56 57 // Can only inherit from one base_protocol implemenation 58 ZX_ASSERT(ddk_proto_id_ == 0); 59 ddk_proto_id_ = ZX_PROTOCOL_BLOCK_IMPL; 60 ddk_proto_ops_ = &ops_; 61 } 62 63private: 64 static void Query(void* ctx, block_info_t* info_out, size_t* block_op_size_out) { 65 static_cast<D*>(ctx)->BlockQuery(info_out, block_op_size_out); 66 } 67 68 static void Queue(void* ctx, block_op_t* txn) { 69 static_cast<D*>(ctx)->BlockQueue(txn); 70 } 71 72 block_protocol_ops_t ops_ = {}; 73}; 74 75} // namespace ddk 76