blob: 0497c476a20fbb7ba1d5d9e03b7982070ae1fde3 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <inttypes.h>
#include <ddk/device.h>
#include <ddk/protocol/block.h>
#include <ddk/protocol/usb-old.h>
#include <lib/sync/completion.h>
#include <zircon/device/block.h>
#include <zircon/listnode.h>
#include <threads.h>
// struct representing a block device for a logical unit
typedef struct {
zx_device_t* zxdev; // block device we publish
uint64_t total_blocks;
uint32_t block_size;
uint8_t lun; // our logical unit number
uint32_t flags; // flags for block_info_t
bool device_added;
} ums_block_t;
// main struct for the UMS driver
typedef struct {
zx_device_t* zxdev; // root device we publish
zx_device_t* usb_zxdev; // USB device we are bound to
usb_protocol_t usb;
uint32_t tag_send; // next tag to send in CBW
uint32_t tag_receive; // next tag we expect to receive in CSW
uint8_t max_lun; // index of last logical unit
size_t max_transfer; // maximum transfer size reported by usb_get_max_transfer_size()
uint8_t interface_number;
uint8_t bulk_in_addr;
uint8_t bulk_out_addr;
size_t bulk_in_max_packet;
size_t bulk_out_max_packet;
usb_request_t* cbw_req;
usb_request_t* data_req;
usb_request_t* csw_req;
usb_request_t* data_transfer_req; // for use in ums_data_transfer
size_t parent_req_size;
thrd_t worker_thread;
bool dead;
// list of queued transactions
list_node_t queued_txns;
sync_completion_t txn_completion; // signals ums_worker_thread when new txns are available
// and when device is dead
mtx_t txn_lock; // protects queued_txns, txn_completion and dead
ums_block_t block_devs[];
} ums_t;
#define block_to_ums(block) containerof(block - block->lun, ums_t, block_devs)
typedef struct ums_txn {
block_op_t op;
block_impl_queue_callback completion_cb;
void* cookie;
list_node_t node;
ums_block_t* dev;
} ums_txn_t;
#define block_op_to_txn(op) containerof(op, ums_txn_t, op)
zx_status_t ums_block_add_device(ums_t* ums, ums_block_t* dev);