From 277ca3398833cd3cea281b875463bd8d9d603231 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Wed, 4 Dec 2013 12:15:05 +0100 Subject: [PATCH] usb block: use generic block driver API (Fix #966) --- .../src/lib/usb/include/storage/component.h | 123 ------------------ dde_linux/src/lib/usb/main.cc | 1 - dde_linux/src/lib/usb/storage/storage.cc | 108 ++++++++++----- 3 files changed, 73 insertions(+), 159 deletions(-) delete mode 100644 dde_linux/src/lib/usb/include/storage/component.h diff --git a/dde_linux/src/lib/usb/include/storage/component.h b/dde_linux/src/lib/usb/include/storage/component.h deleted file mode 100644 index e25e7e704..000000000 --- a/dde_linux/src/lib/usb/include/storage/component.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * \brief Block-session implementation for USB storage - * \author Sebastian Sumpf - * \date 2012-05-23 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _STORAGE__COMPONENT_H_ -#define _STORAGE__COMPONENT_H_ - -#include -#include - -#include - -namespace Block { - - using namespace Genode; - - class Session_component; - - struct Device : ::Device - { - /** - * Request block size for driver and medium - */ - virtual Genode::size_t block_size() = 0; - - /** - * Request capacity of medium in blocks - */ - virtual Genode::size_t block_count() = 0; - - virtual void io(Session_component *session, Packet_descriptor &packet, - addr_t virt, addr_t phys) = 0; - }; - - - class Session_component : public Packet_session_component - { - private: - - addr_t _rq_phys ; /* physical addr. of rq_ds */ - Device *_device; /* device this session is using */ - - protected: - - void _process_packets(unsigned) - { - while (tx_sink()->packet_avail()) - { - Packet_descriptor packet = tx_sink()->get_packet(); - addr_t virt = (addr_t)tx_sink()->packet_content(packet); - addr_t phys = _rq_phys + packet.offset(); - - try { - _device->io(this, packet, virt, phys); - } catch (...) { PERR("Failed to queue packet"); } - } - } - - public: - - /** - * Constructor - */ - Session_component(Dataspace_capability tx_ds, - Ram_dataspace_capability rx_ds, - Rpc_entrypoint &ep, - Signal_receiver *sig_rec, - ::Device *device) - : - Packet_session_component(tx_ds, ep, sig_rec), - _rq_phys(Dataspace_client(tx_ds).phys_addr()), - _device(static_cast(device)) - { - env()->ram_session()->free(rx_ds); - } - - void info(size_t *blk_count, size_t *blk_size, - Operations *ops) - { - *blk_count = _device->block_count(); - *blk_size = _device->block_size(); - ops->set_operation(Packet_descriptor::READ); - ops->set_operation(Packet_descriptor::WRITE); - } - - void sync() {} - - void complete(Packet_descriptor &packet, bool success) - { - packet.succeeded(success); - tx_sink()->acknowledge_packet(packet); - } - }; - - /* - * Shortcut for single-client root component - */ - typedef Root_component Root_component; - - /** - * Root component, handling new session requests - */ - class Root : public Packet_root - { - public: - - Root(Rpc_entrypoint *session_ep, Allocator *md_alloc, - Signal_receiver *sig_rec, Device *device) - : - Packet_root(session_ep, md_alloc, sig_rec, device) { } - }; - -} -#endif /* _STORAGE__COMPONENT_H_ */ diff --git a/dde_linux/src/lib/usb/main.cc b/dde_linux/src/lib/usb/main.cc index 8d0f934fa..7412ca0cb 100644 --- a/dde_linux/src/lib/usb/main.cc +++ b/dde_linux/src/lib/usb/main.cc @@ -22,7 +22,6 @@ #include /* Local */ -#include #include #include #include diff --git a/dde_linux/src/lib/usb/storage/storage.cc b/dde_linux/src/lib/usb/storage/storage.cc index 4737a182d..0239a9098 100644 --- a/dde_linux/src/lib/usb/storage/storage.cc +++ b/dde_linux/src/lib/usb/storage/storage.cc @@ -12,21 +12,21 @@ */ #include -#include +#include #include #include #include #include -#include +#include #include #include "signal.h" static Signal_helper *_signal = 0; class Storage_device : public Genode::List::Element, - public Block::Device + public Block::Driver { private: @@ -45,7 +45,7 @@ class Storage_device : public Genode::List::Element, if (verbose) PDBG("ACK packet for block: %zu status: %d", packet->block_number(), cmnd->result); - session->complete(*packet, true); + session->complete_packet(*packet); Genode::destroy(Genode::env()->heap(), packet); _scsi_free_command(cmnd); } @@ -74,45 +74,27 @@ class Storage_device : public Genode::List::Element, Genode::uint32_t *data = (Genode::uint32_t *)scsi_buffer_data(cmnd); _block_count = bswap(data[0]); _block_size = bswap(data[1]); - + /* if device returns the highest block number */ if (!_sdev->fix_capacity) _block_count++; - + if (verbose) PDBG("block size: %zu block count: %llu", _block_size, _block_count); - + scsi_free_buffer(cmnd); _scsi_free_command(cmnd); } - - Storage_device(struct scsi_device *sdev) : _sdev(sdev) + void _io(Genode::size_t block_nr, Genode::size_t block_count, + Block::Packet_descriptor packet, + Genode::addr_t virt, Genode::addr_t phys, bool read) { - /* read device capacity */ - _capacity(); - } - - public: - - static Storage_device *add(struct scsi_device *sdev) { - return new (Genode::env()->heap()) Storage_device(sdev); } - - Genode::size_t block_size() { return _block_size; } - Genode::size_t block_count() { return _block_count; } - - void io(Block::Session_component *session, Block::Packet_descriptor &packet, - Genode::addr_t virt, Genode::addr_t phys) - { - Block::sector_t block_nr = packet.block_number(); - Genode::uint16_t block_count = packet.block_count() & 0xffff; - bool read = packet.operation() == Block::Packet_descriptor::WRITE ? false : true; - if (block_nr > _block_count) - throw -1; - + throw Io_error(); + if (verbose) - PDBG("PACKET: phys: %lx block: %llu count: %u %s", + PDBG("PACKET: phys: %lx block: %zu count: %u %s", phys, block_nr, block_count, read ? "read" : "write"); struct scsi_cmnd *cmnd = _scsi_alloc_command(); @@ -132,7 +114,7 @@ class Storage_device : public Genode::List::Element, memcpy(&cmnd->cmnd[2], &be_block_nr, 4); /* transfer one block */ - Genode::uint16_t be_block_count = bswap(block_count); + Genode::uint16_t be_block_count = bswap(block_count); memcpy(&cmnd->cmnd[7], &be_block_count, 2); /* setup command */ @@ -147,9 +129,54 @@ class Storage_device : public Genode::List::Element, /* send command to host driver */ if (_sdev->host->hostt->queuecommand(_sdev->host, cmnd)) { - throw -2; + throw Io_error(); } } + + public: + + Storage_device(struct scsi_device *sdev) + : Block::Driver(), _sdev(sdev) + { + /* read device capacity */ + _capacity(); + } + + Genode::size_t block_size() { return _block_size; } + Genode::size_t block_count() { return _block_count; } + + Block::Session::Operations ops() + { + Block::Session::Operations o; + o.set_operation(Block::Packet_descriptor::READ); + o.set_operation(Block::Packet_descriptor::WRITE); + return o; + } + + void read_dma(Genode::size_t block_number, + Genode::size_t block_count, + Genode::addr_t phys, + Block::Packet_descriptor &packet) + { + _io(block_number, block_count, packet, + (Genode::addr_t)session->tx_sink()->packet_content(packet), + phys, true); + } + + void write_dma(Genode::size_t block_number, + Genode::size_t block_count, + Genode::addr_t phys, + Block::Packet_descriptor &packet) + { + _io(block_number, block_count, packet, + (Genode::addr_t)session->tx_sink()->packet_content(packet), + phys, false); + } + + bool dma_enabled() { return true; } + + Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) { + return Backend_memory::alloc(size, false); } }; @@ -157,12 +184,23 @@ void Storage::init(Genode::Signal_receiver *recv) { _signal = new (Genode::env()->heap()) Signal_helper(recv); } +struct Factory : Block::Driver_factory +{ + Storage_device device; + + Factory(struct scsi_device *sdev) : device(sdev) {} + + Block::Driver *create() { return &device; } + void destroy(Block::Driver *driver) { } +}; + + void scsi_add_device(struct scsi_device *sdev) { using namespace Genode; static bool announce = false; - Storage_device *device = Storage_device::add(sdev); + static struct Factory factory(sdev); /* * XXX move to 'main' @@ -171,7 +209,7 @@ void scsi_add_device(struct scsi_device *sdev) enum { STACK_SIZE = 1024 * sizeof(addr_t) }; static Cap_connection cap_stor; static Rpc_entrypoint ep_stor(&cap_stor, STACK_SIZE, "usb_stor_ep"); - static Block::Root root(&ep_stor, env()->heap(), _signal->receiver(), device); + static Block::Root root(&ep_stor, env()->heap(), factory, *_signal->receiver()); env()->parent()->announce(ep_stor.manage(&root)); announce = true; }