110391SAndreas.Sandberg@ARM.com/*
212187Sanouk.vanlaer@arm.com * Copyright (c) 2014-2017 ARM Limited
310391SAndreas.Sandberg@ARM.com * All rights reserved
410391SAndreas.Sandberg@ARM.com *
510391SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall
610391SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual
710391SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating
810391SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software
910391SAndreas.Sandberg@ARM.com * licensed hereunder.  You may use the software subject to the license
1010391SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated
1110391SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software,
1210391SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form.
1310391SAndreas.Sandberg@ARM.com *
1410391SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
1510391SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
1610391SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
1710391SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
1810391SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
1910391SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
2010391SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
2110391SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
2210391SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from
2310391SAndreas.Sandberg@ARM.com * this software without specific prior written permission.
2410391SAndreas.Sandberg@ARM.com *
2510391SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610391SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710391SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810391SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910391SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010391SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110391SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210391SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310391SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410391SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510391SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610391SAndreas.Sandberg@ARM.com *
3710391SAndreas.Sandberg@ARM.com * Authors: Andreas Sandberg
3810391SAndreas.Sandberg@ARM.com */
3910391SAndreas.Sandberg@ARM.com
4010391SAndreas.Sandberg@ARM.com#ifndef __DEV_VIRTIO_FS9P_HH__
4110391SAndreas.Sandberg@ARM.com#define __DEV_VIRTIO_FS9P_HH__
4210391SAndreas.Sandberg@ARM.com
4310391SAndreas.Sandberg@ARM.com#include <map>
4410391SAndreas.Sandberg@ARM.com#include <memory>
4510391SAndreas.Sandberg@ARM.com#include <string>
4610391SAndreas.Sandberg@ARM.com
4710391SAndreas.Sandberg@ARM.com#include "base/pollevent.hh"
4810391SAndreas.Sandberg@ARM.com#include "dev/virtio/base.hh"
4910391SAndreas.Sandberg@ARM.com
5010391SAndreas.Sandberg@ARM.comstruct VirtIO9PBaseParams;
5110391SAndreas.Sandberg@ARM.com
5210391SAndreas.Sandberg@ARM.comtypedef uint8_t P9MsgType;
5310391SAndreas.Sandberg@ARM.comtypedef uint16_t P9Tag;
5410391SAndreas.Sandberg@ARM.com
5510391SAndreas.Sandberg@ARM.comstruct P9MsgHeader {
5610391SAndreas.Sandberg@ARM.com    /** Length including header */
5710391SAndreas.Sandberg@ARM.com    uint32_t len;
5810391SAndreas.Sandberg@ARM.com    /** Message type */
5910391SAndreas.Sandberg@ARM.com    P9MsgType type;
6010391SAndreas.Sandberg@ARM.com    /** Message tag */
6110391SAndreas.Sandberg@ARM.com    P9Tag tag;
6210391SAndreas.Sandberg@ARM.com} M5_ATTR_PACKED;
6310391SAndreas.Sandberg@ARM.com
6410391SAndreas.Sandberg@ARM.com/** Convert p9 byte order (LE) to host byte order */
6510391SAndreas.Sandberg@ARM.comtemplate <typename T> inline T
6610391SAndreas.Sandberg@ARM.comp9toh(T v) { return letoh(v); }
6710391SAndreas.Sandberg@ARM.com
6810391SAndreas.Sandberg@ARM.com/** Convert host byte order to p9 byte order (LE) */
6910391SAndreas.Sandberg@ARM.comtemplate <typename T> inline T
7010391SAndreas.Sandberg@ARM.comhtop9(T v) { return htole(v); }
7110391SAndreas.Sandberg@ARM.com
7210391SAndreas.Sandberg@ARM.comtemplate <> inline P9MsgHeader
7310391SAndreas.Sandberg@ARM.comp9toh(P9MsgHeader v)
7410391SAndreas.Sandberg@ARM.com{
7510391SAndreas.Sandberg@ARM.com    v.len = p9toh(v.len);
7610391SAndreas.Sandberg@ARM.com    v.type = p9toh(v.type);
7710391SAndreas.Sandberg@ARM.com    v.tag = p9toh(v.tag);
7810391SAndreas.Sandberg@ARM.com    return v;
7910391SAndreas.Sandberg@ARM.com}
8010391SAndreas.Sandberg@ARM.com
8110391SAndreas.Sandberg@ARM.comtemplate <> inline P9MsgHeader
8210391SAndreas.Sandberg@ARM.comhtop9(P9MsgHeader v)
8310391SAndreas.Sandberg@ARM.com{
8410391SAndreas.Sandberg@ARM.com    v.len = htop9(v.len);
8510391SAndreas.Sandberg@ARM.com    v.type = htop9(v.type);
8610391SAndreas.Sandberg@ARM.com    v.tag = htop9(v.tag);
8710391SAndreas.Sandberg@ARM.com    return v;
8810391SAndreas.Sandberg@ARM.com}
8910391SAndreas.Sandberg@ARM.com
9010391SAndreas.Sandberg@ARM.com/**
9110391SAndreas.Sandberg@ARM.com * This class implements a VirtIO transport layer for the 9p network
9210391SAndreas.Sandberg@ARM.com * file system.
9310391SAndreas.Sandberg@ARM.com *
9410391SAndreas.Sandberg@ARM.com * The 9p VirtIO transport uses the following queues:
9510391SAndreas.Sandberg@ARM.com *  -# 9p requests and replies
9610391SAndreas.Sandberg@ARM.com *
9710391SAndreas.Sandberg@ARM.com * Each 9p request and response is sent in its own descriptor
9810391SAndreas.Sandberg@ARM.com * chain. The guest initiates a transaction by packing a T message
9910391SAndreas.Sandberg@ARM.com * (see the 9p spec) into the first part of a descriptor chain. After
10010391SAndreas.Sandberg@ARM.com * the T message, the guest reserves space for the reply (R message)
10110391SAndreas.Sandberg@ARM.com * by including one or more writable descriptors. The server replies
10210391SAndreas.Sandberg@ARM.com * by writing an R message into the writable descriptors and putting
10310391SAndreas.Sandberg@ARM.com * the chain in the used ring (VirtQueue::produceDescriptor()).
10410391SAndreas.Sandberg@ARM.com *
10510391SAndreas.Sandberg@ARM.com * @see https://github.com/rustyrussell/virtio-spec
10610391SAndreas.Sandberg@ARM.com * @see https://github.com/ericvh/9p-rfc
10710391SAndreas.Sandberg@ARM.com * @see https://code.google.com/p/diod/wiki/protocol
10810391SAndreas.Sandberg@ARM.com */
10910391SAndreas.Sandberg@ARM.comclass VirtIO9PBase : public VirtIODeviceBase
11010391SAndreas.Sandberg@ARM.com{
11110391SAndreas.Sandberg@ARM.com  public:
11210391SAndreas.Sandberg@ARM.com    typedef VirtIO9PBaseParams Params;
11310391SAndreas.Sandberg@ARM.com    VirtIO9PBase(Params *params);
11410391SAndreas.Sandberg@ARM.com    virtual ~VirtIO9PBase();
11510391SAndreas.Sandberg@ARM.com
11610391SAndreas.Sandberg@ARM.com    void readConfig(PacketPtr pkt, Addr cfgOffset);
11710391SAndreas.Sandberg@ARM.com
11810391SAndreas.Sandberg@ARM.com  protected:
11910391SAndreas.Sandberg@ARM.com    /**
12010391SAndreas.Sandberg@ARM.com     * VirtIO 9p configuration structure
12110391SAndreas.Sandberg@ARM.com     *
12210391SAndreas.Sandberg@ARM.com     * @note The fields in this structure depend on the features
12310391SAndreas.Sandberg@ARM.com     * exposed to the guest.
12410391SAndreas.Sandberg@ARM.com     */
12510391SAndreas.Sandberg@ARM.com    struct Config {
12610391SAndreas.Sandberg@ARM.com        uint16_t len;
12710391SAndreas.Sandberg@ARM.com        char tag[];
12810391SAndreas.Sandberg@ARM.com    } M5_ATTR_PACKED;
12910391SAndreas.Sandberg@ARM.com
13010391SAndreas.Sandberg@ARM.com    /** Currently active configuration (host byte order) */
13110391SAndreas.Sandberg@ARM.com    std::unique_ptr<Config> config;
13210391SAndreas.Sandberg@ARM.com
13310391SAndreas.Sandberg@ARM.com    /** VirtIO device ID */
13410391SAndreas.Sandberg@ARM.com    static const DeviceId ID_9P = 0x09;
13510391SAndreas.Sandberg@ARM.com
13610391SAndreas.Sandberg@ARM.com    /** @{
13710391SAndreas.Sandberg@ARM.com     * @name Feature bits
13810391SAndreas.Sandberg@ARM.com     */
13910391SAndreas.Sandberg@ARM.com    /** Device provides a name of the resource in its configuration */
14010391SAndreas.Sandberg@ARM.com    static const FeatureBits F_MOUNT_TAG = 0x01;
14110391SAndreas.Sandberg@ARM.com    /** @} */
14210391SAndreas.Sandberg@ARM.com
14310391SAndreas.Sandberg@ARM.com  protected:
14410391SAndreas.Sandberg@ARM.com    /**
14510391SAndreas.Sandberg@ARM.com     * Virtqueue for 9p requests
14610391SAndreas.Sandberg@ARM.com     */
14710391SAndreas.Sandberg@ARM.com    class FSQueue : public VirtQueue
14810391SAndreas.Sandberg@ARM.com    {
14910391SAndreas.Sandberg@ARM.com      public:
15010391SAndreas.Sandberg@ARM.com        FSQueue(PortProxy &proxy, uint16_t size, VirtIO9PBase &_parent)
15110391SAndreas.Sandberg@ARM.com            : VirtQueue(proxy, size), parent(_parent) {}
15210391SAndreas.Sandberg@ARM.com        virtual ~FSQueue() {}
15310391SAndreas.Sandberg@ARM.com
15410391SAndreas.Sandberg@ARM.com        void onNotifyDescriptor(VirtDescriptor *desc);
15510391SAndreas.Sandberg@ARM.com
15610391SAndreas.Sandberg@ARM.com        std::string name() const { return parent.name() + ".queue"; }
15710391SAndreas.Sandberg@ARM.com
15810391SAndreas.Sandberg@ARM.com      protected:
15910391SAndreas.Sandberg@ARM.com        VirtIO9PBase &parent;
16010391SAndreas.Sandberg@ARM.com    };
16110391SAndreas.Sandberg@ARM.com
16210391SAndreas.Sandberg@ARM.com    FSQueue queue;
16310391SAndreas.Sandberg@ARM.com
16410391SAndreas.Sandberg@ARM.com  protected:
16510391SAndreas.Sandberg@ARM.com    /**
16610391SAndreas.Sandberg@ARM.com     * Handle incoming 9p RPC message.
16710391SAndreas.Sandberg@ARM.com     *
16810391SAndreas.Sandberg@ARM.com     * @param header 9p message header.
16910391SAndreas.Sandberg@ARM.com     * @param data Pointer to data in message.
17010391SAndreas.Sandberg@ARM.com     * @param size Size of data (excluding header)
17110391SAndreas.Sandberg@ARM.com     */
17210391SAndreas.Sandberg@ARM.com    virtual void recvTMsg(const P9MsgHeader &header, const uint8_t *data, size_t size) = 0;
17310391SAndreas.Sandberg@ARM.com    /**
17410391SAndreas.Sandberg@ARM.com     * Send a 9p RPC message reply.
17510391SAndreas.Sandberg@ARM.com     *
17610391SAndreas.Sandberg@ARM.com     * @param header 9p message header.
17710391SAndreas.Sandberg@ARM.com     * @param data Pointer to data in message.
17810391SAndreas.Sandberg@ARM.com     * @param size Size of data (excluding header)
17910391SAndreas.Sandberg@ARM.com     */
18010391SAndreas.Sandberg@ARM.com    void sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size);
18110391SAndreas.Sandberg@ARM.com
18210391SAndreas.Sandberg@ARM.com    /**
18310391SAndreas.Sandberg@ARM.com     * Dump a 9p RPC message on the debug output
18410391SAndreas.Sandberg@ARM.com     *
18510391SAndreas.Sandberg@ARM.com     * @param header 9p message header.
18610391SAndreas.Sandberg@ARM.com     * @param data Pointer to data in message.
18710391SAndreas.Sandberg@ARM.com     * @param size Size of data (excluding header)
18810391SAndreas.Sandberg@ARM.com     */
18910391SAndreas.Sandberg@ARM.com    void dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size);
19010391SAndreas.Sandberg@ARM.com
19110391SAndreas.Sandberg@ARM.com  private:
19210391SAndreas.Sandberg@ARM.com    /**
19310391SAndreas.Sandberg@ARM.com     * Map between 9p transaction tags and descriptors where they
19410391SAndreas.Sandberg@ARM.com     * appeared.
19510391SAndreas.Sandberg@ARM.com     *
19610391SAndreas.Sandberg@ARM.com     * When handling asynchronous requests, we need to ensure that
19710391SAndreas.Sandberg@ARM.com     * replies are posted in the same descriptor as queries. The 9p
19810391SAndreas.Sandberg@ARM.com     * RPC protocol uses the tag field in the header to match requests
19910391SAndreas.Sandberg@ARM.com     * and replies, which we use here to find the relevant descriptor.
20010391SAndreas.Sandberg@ARM.com     */
20110391SAndreas.Sandberg@ARM.com    std::map<P9Tag, VirtDescriptor *> pendingTransactions;
20210391SAndreas.Sandberg@ARM.com};
20310391SAndreas.Sandberg@ARM.com
20410391SAndreas.Sandberg@ARM.comstruct VirtIO9PProxyParams;
20510391SAndreas.Sandberg@ARM.com
20610391SAndreas.Sandberg@ARM.com/**
20710391SAndreas.Sandberg@ARM.com * VirtIO 9p proxy base class.
20810391SAndreas.Sandberg@ARM.com *
20910391SAndreas.Sandberg@ARM.com * This base class provides basic functionality shared by different 9p
21010391SAndreas.Sandberg@ARM.com * proxy implementations.
21110391SAndreas.Sandberg@ARM.com */
21210391SAndreas.Sandberg@ARM.comclass VirtIO9PProxy : public VirtIO9PBase
21310391SAndreas.Sandberg@ARM.com{
21410391SAndreas.Sandberg@ARM.com  public:
21510391SAndreas.Sandberg@ARM.com    typedef VirtIO9PProxyParams Params;
21610391SAndreas.Sandberg@ARM.com    VirtIO9PProxy(Params *params);
21710391SAndreas.Sandberg@ARM.com    virtual ~VirtIO9PProxy();
21810391SAndreas.Sandberg@ARM.com
21911168Sandreas.hansson@arm.com    void serialize(CheckpointOut &cp) const override;
22011168Sandreas.hansson@arm.com    void unserialize(CheckpointIn &cp) override;
22110391SAndreas.Sandberg@ARM.com
22210391SAndreas.Sandberg@ARM.com  protected:
22311169Sandreas.hansson@arm.com    void recvTMsg(const P9MsgHeader &header, const uint8_t *data,
22411169Sandreas.hansson@arm.com                  size_t size) override;
22510391SAndreas.Sandberg@ARM.com
22610391SAndreas.Sandberg@ARM.com    /** Notification of pending data from server */
22710391SAndreas.Sandberg@ARM.com    void serverDataReady();
22810391SAndreas.Sandberg@ARM.com
22910391SAndreas.Sandberg@ARM.com    /**
23010391SAndreas.Sandberg@ARM.com     * Read data from the server behind the proxy.
23110391SAndreas.Sandberg@ARM.com     *
23210391SAndreas.Sandberg@ARM.com     * @note This method may return read fewer than len bytes.
23310391SAndreas.Sandberg@ARM.com     *
23410391SAndreas.Sandberg@ARM.com     * @param data Memory location to store results in.
23510391SAndreas.Sandberg@ARM.com     * @param len Maximum length to read.
23610391SAndreas.Sandberg@ARM.com     * @return Number of bytes read, -errno on failure.
23710391SAndreas.Sandberg@ARM.com     */
23810391SAndreas.Sandberg@ARM.com    virtual ssize_t read(uint8_t *data, size_t len) = 0;
23910391SAndreas.Sandberg@ARM.com    /**
24010391SAndreas.Sandberg@ARM.com     * Write data to the server behind the proxy.
24110391SAndreas.Sandberg@ARM.com     *
24210391SAndreas.Sandberg@ARM.com     * @note This method may return write fewer than len bytes.
24310391SAndreas.Sandberg@ARM.com     *
24410391SAndreas.Sandberg@ARM.com     * @param data Pointer to data to write.
24510391SAndreas.Sandberg@ARM.com     * @param len Maximum length to write.
24610391SAndreas.Sandberg@ARM.com     * @return Number of bytes written, -errno on failure.
24710391SAndreas.Sandberg@ARM.com     */
24810391SAndreas.Sandberg@ARM.com    virtual ssize_t write(const uint8_t *data, size_t len) = 0;
24910391SAndreas.Sandberg@ARM.com
25010391SAndreas.Sandberg@ARM.com    /**
25110391SAndreas.Sandberg@ARM.com     * Convenience function that reads exactly len bytes.
25210391SAndreas.Sandberg@ARM.com     *
25310391SAndreas.Sandberg@ARM.com     * This method calls read until exactly len number of bytes has
25410391SAndreas.Sandberg@ARM.com     * been read. A read() call is retried if the underlying syscall
25510391SAndreas.Sandberg@ARM.com     * was interrupted.
25610391SAndreas.Sandberg@ARM.com     *
25710391SAndreas.Sandberg@ARM.com     * @param data Memory location to store results in.
25810391SAndreas.Sandberg@ARM.com     * @param len Number of bytes to read.
25910391SAndreas.Sandberg@ARM.com     */
26010391SAndreas.Sandberg@ARM.com    void readAll(uint8_t *data, size_t len);
26110391SAndreas.Sandberg@ARM.com    /**
26210391SAndreas.Sandberg@ARM.com     * Convenience function that writes exactly len bytes.
26310391SAndreas.Sandberg@ARM.com     *
26410391SAndreas.Sandberg@ARM.com     * This method calls write until exactly len number of bytes has
26510391SAndreas.Sandberg@ARM.com     * been written. A write() call is retried if the underlying
26610391SAndreas.Sandberg@ARM.com     * syscall was interrupted.
26710391SAndreas.Sandberg@ARM.com     *
26810391SAndreas.Sandberg@ARM.com     * @param data Data to write.
26910391SAndreas.Sandberg@ARM.com     * @param len Number of bytes to write.
27010391SAndreas.Sandberg@ARM.com     */
27110391SAndreas.Sandberg@ARM.com    void writeAll(const uint8_t *data, size_t len);
27211204Ssascha.bischoff@ARM.com
27311204Ssascha.bischoff@ARM.com    /**
27411204Ssascha.bischoff@ARM.com     * Bool to track if the device has been used or not.
27511204Ssascha.bischoff@ARM.com     *
27611204Ssascha.bischoff@ARM.com     * We need to keep track of if the device has been used as we are
27711204Ssascha.bischoff@ARM.com     * unable to checkpoint the device in the event that the device
27811204Ssascha.bischoff@ARM.com     * has been mounted in the guest system. This is due to the fact
27911204Ssascha.bischoff@ARM.com     * that we do not, and cannot, track the complete state across
28011204Ssascha.bischoff@ARM.com     * host and guest.
28111204Ssascha.bischoff@ARM.com     */
28211204Ssascha.bischoff@ARM.com     bool deviceUsed;
28310391SAndreas.Sandberg@ARM.com};
28410391SAndreas.Sandberg@ARM.com
28510391SAndreas.Sandberg@ARM.comstruct VirtIO9PDiodParams;
28610391SAndreas.Sandberg@ARM.com
28710391SAndreas.Sandberg@ARM.com/**
28810391SAndreas.Sandberg@ARM.com * VirtIO 9p proxy that communicates with the diod 9p server using
28910391SAndreas.Sandberg@ARM.com * pipes.
29010391SAndreas.Sandberg@ARM.com */
29110391SAndreas.Sandberg@ARM.comclass VirtIO9PDiod : public VirtIO9PProxy
29210391SAndreas.Sandberg@ARM.com{
29310391SAndreas.Sandberg@ARM.com  public:
29410391SAndreas.Sandberg@ARM.com    typedef VirtIO9PDiodParams Params;
29510391SAndreas.Sandberg@ARM.com    VirtIO9PDiod(Params *params);
29610391SAndreas.Sandberg@ARM.com    virtual ~VirtIO9PDiod();
29710391SAndreas.Sandberg@ARM.com
29810391SAndreas.Sandberg@ARM.com    void startup();
29910391SAndreas.Sandberg@ARM.com
30010391SAndreas.Sandberg@ARM.com  protected:
30110391SAndreas.Sandberg@ARM.com    /**
30210391SAndreas.Sandberg@ARM.com     * Start diod and setup the communication pipes.
30310391SAndreas.Sandberg@ARM.com     */
30410391SAndreas.Sandberg@ARM.com    void startDiod();
30510391SAndreas.Sandberg@ARM.com
30610391SAndreas.Sandberg@ARM.com    ssize_t read(uint8_t *data, size_t len);
30710391SAndreas.Sandberg@ARM.com    ssize_t write(const uint8_t *data, size_t len);
30812187Sanouk.vanlaer@arm.com    /** Kill the diod child process at the end of the simulation */
30912187Sanouk.vanlaer@arm.com    void terminateDiod();
31010391SAndreas.Sandberg@ARM.com
31110391SAndreas.Sandberg@ARM.com  private:
31210391SAndreas.Sandberg@ARM.com    class DiodDataEvent : public PollEvent
31310391SAndreas.Sandberg@ARM.com    {
31410391SAndreas.Sandberg@ARM.com      public:
31510391SAndreas.Sandberg@ARM.com        DiodDataEvent(VirtIO9PDiod &_parent, int fd, int event)
31610391SAndreas.Sandberg@ARM.com            : PollEvent(fd, event), parent(_parent) {}
31710391SAndreas.Sandberg@ARM.com
31810391SAndreas.Sandberg@ARM.com        virtual ~DiodDataEvent() {};
31910391SAndreas.Sandberg@ARM.com
32010391SAndreas.Sandberg@ARM.com        void process(int revent);
32110391SAndreas.Sandberg@ARM.com
32210391SAndreas.Sandberg@ARM.com      private:
32310391SAndreas.Sandberg@ARM.com        VirtIO9PDiod &parent;
32410391SAndreas.Sandberg@ARM.com    };
32510391SAndreas.Sandberg@ARM.com
32610391SAndreas.Sandberg@ARM.com    /** fd for data pipe going to diod (write end) */
32710391SAndreas.Sandberg@ARM.com    int fd_to_diod;
32810391SAndreas.Sandberg@ARM.com    /** fd for data pipe coming from diod (read end) */
32910391SAndreas.Sandberg@ARM.com    int fd_from_diod;
33010391SAndreas.Sandberg@ARM.com
33110391SAndreas.Sandberg@ARM.com    std::unique_ptr<DiodDataEvent> dataEvent;
33210391SAndreas.Sandberg@ARM.com
33310391SAndreas.Sandberg@ARM.com    /** PID of diod process */
33410391SAndreas.Sandberg@ARM.com    int diod_pid;
33510391SAndreas.Sandberg@ARM.com};
33610391SAndreas.Sandberg@ARM.com
33710391SAndreas.Sandberg@ARM.comstruct VirtIO9PSocketParams;
33810391SAndreas.Sandberg@ARM.com
33910391SAndreas.Sandberg@ARM.com/**
34010391SAndreas.Sandberg@ARM.com * VirtIO 9p proxy that communicates with a 9p server over tcp
34110391SAndreas.Sandberg@ARM.com * sockets.
34210391SAndreas.Sandberg@ARM.com */
34310391SAndreas.Sandberg@ARM.comclass VirtIO9PSocket : public VirtIO9PProxy
34410391SAndreas.Sandberg@ARM.com{
34510391SAndreas.Sandberg@ARM.com  public:
34610391SAndreas.Sandberg@ARM.com    typedef VirtIO9PSocketParams Params;
34710391SAndreas.Sandberg@ARM.com    VirtIO9PSocket(Params *params);
34810391SAndreas.Sandberg@ARM.com    virtual ~VirtIO9PSocket();
34910391SAndreas.Sandberg@ARM.com
35010391SAndreas.Sandberg@ARM.com    void startup();
35110391SAndreas.Sandberg@ARM.com
35210391SAndreas.Sandberg@ARM.com  protected:
35310391SAndreas.Sandberg@ARM.com    /**
35410391SAndreas.Sandberg@ARM.com     * Try to resolve the server name and connect to the 9p server.
35510391SAndreas.Sandberg@ARM.com     */
35610391SAndreas.Sandberg@ARM.com    void connectSocket();
35710391SAndreas.Sandberg@ARM.com
35810391SAndreas.Sandberg@ARM.com    /** 9p server disconnect notification */
35910391SAndreas.Sandberg@ARM.com    void socketDisconnect();
36010391SAndreas.Sandberg@ARM.com
36110391SAndreas.Sandberg@ARM.com    ssize_t read(uint8_t *data, size_t len);
36210391SAndreas.Sandberg@ARM.com    ssize_t write(const uint8_t *data, size_t len);
36310391SAndreas.Sandberg@ARM.com
36410391SAndreas.Sandberg@ARM.com  private:
36510391SAndreas.Sandberg@ARM.com    class SocketDataEvent : public PollEvent
36610391SAndreas.Sandberg@ARM.com    {
36710391SAndreas.Sandberg@ARM.com      public:
36810391SAndreas.Sandberg@ARM.com        SocketDataEvent(VirtIO9PSocket &_parent, int fd, int event)
36910391SAndreas.Sandberg@ARM.com            : PollEvent(fd, event), parent(_parent) {}
37010391SAndreas.Sandberg@ARM.com
37110391SAndreas.Sandberg@ARM.com        virtual ~SocketDataEvent() {};
37210391SAndreas.Sandberg@ARM.com
37310391SAndreas.Sandberg@ARM.com        void process(int revent);
37410391SAndreas.Sandberg@ARM.com
37510391SAndreas.Sandberg@ARM.com      private:
37610391SAndreas.Sandberg@ARM.com        VirtIO9PSocket &parent;
37710391SAndreas.Sandberg@ARM.com    };
37810391SAndreas.Sandberg@ARM.com
37910391SAndreas.Sandberg@ARM.com    /** Socket connected to the 9p server */
38010391SAndreas.Sandberg@ARM.com    int fdSocket;
38110391SAndreas.Sandberg@ARM.com
38210391SAndreas.Sandberg@ARM.com    std::unique_ptr<SocketDataEvent> dataEvent;
38310391SAndreas.Sandberg@ARM.com};
38410391SAndreas.Sandberg@ARM.com
38510391SAndreas.Sandberg@ARM.com#endif // __DEV_VIRTIO_FS9P_HH__
386