summaryrefslogtreecommitdiff
path: root/open-vm-tools/modules/linux/vmhgfs/request.h
blob: 4303924b098f1830497c423c70c94df7f43b1be8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*********************************************************
 * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 *********************************************************/

/*
 * request.h --
 *
 * Functions dealing with the creation, deletion, and sending of HGFS
 * requests are defined here.
 */

#ifndef _HGFS_DRIVER_REQUEST_H_
#define _HGFS_DRIVER_REQUEST_H_

/* Must come before any kernel header file. */
#include "driver-config.h"

#include <linux/kref.h>
#include <linux/list.h>
#include <linux/wait.h>
#include "compat_sched.h"
#include "compat_spinlock.h"

#include "hgfs.h" /* For common HGFS definitions. */
#include "hgfsTransport.h"
#include "vm_basic_types.h"

/* Macros for accessing the payload portion of the HGFS request packet. */
#define HGFS_REQ_PAYLOAD(hgfsReq) ((hgfsReq)->payload)

/* XXX: Needs change when VMCI is supported. */
#define HGFS_REQ_PAYLOAD_V3(hgfsReq) (HGFS_REQ_PAYLOAD(hgfsReq) + sizeof(HgfsRequest))
#define HGFS_REP_PAYLOAD_V3(hgfsRep) (HGFS_REQ_PAYLOAD(hgfsRep) + sizeof(HgfsReply))

/*
 * HGFS_REQ_STATE_ALLOCATED:
 *    The filesystem half has allocated the request from the slab
 *    allocator. The request is not on any list.
 *
 * HGFS_REQ_STATE_UNSENT:
 *    The filesystem half of the driver has filled in the request fields
 *    and placed the request in the global unsent list. It is now the
 *    request handler's responsibility to submit this request to
 *    the channel. Requests in this state are on the global unsent list.
 *
 * HGFS_REQ_STATE_SUBMITTED:
 *    The packet has been sent, but the reply will arrive asynchronously.
 *    The request will be on the hgfsRepPending list, and whenever
 *    the reply arrives, the reply handler will remove the request from
 *    the hgfsRepPending list and stuff the reply into the request's
 *    packet buffer.
 *
 *    This is only for asynchronous channel communication.
 *
 * HGFS_REQ_STATE_COMPLETED:
 *    The request handler sent the request and received a reply. The reply
 *    is stuffed in the request's packet buffer. Requests in this state
 *    are not on any list.
 */
typedef enum {
   HGFS_REQ_STATE_ALLOCATED,
   HGFS_REQ_STATE_UNSENT,
   HGFS_REQ_STATE_SUBMITTED,
   HGFS_REQ_STATE_COMPLETED,  /* Both header and payload were received. */
} HgfsState;

/*
 * Each page that is sent from guest to host is described in the following
 * format.
 */
typedef struct HgfsDataPacket {
   struct page *page;
   uint32 offset;
   uint32 len;
} HgfsDataPacket;

/*
 * A request to be sent to the user process.
 */
typedef struct HgfsReq {

   /* Reference count */
   struct kref kref;

   /* Links to place the object on various lists. */
   struct list_head list;

   /* ID of the transport (its address) */
   void *transportId;

   /*
    * When clients wait for the reply to a request, they'll wait on this
    * wait queue.
    */
   wait_queue_head_t queue;

   /* Current state of the request. */
   HgfsState state;

   /* ID of this request */
   uint32 id;

   /* Pointer to payload in the buffer */
   void *payload;

   /* Total size of the payload.*/
   size_t payloadSize;

   /*
    * Size of the data buffer (below), not including size of chunk
    * used by transport. Must be enough to hold both request and
    * reply (but not at the same time). Initialized in channels.
    */
   size_t bufferSize;

  /*
   * Used by read and write calls. Hgfs client passes in
   * pages to the vmci channel using datapackets and vmci channel
   * uses it to pass PA's to the host.
   */
   HgfsDataPacket *dataPacket;

   /* Number of entries in data packet */
   uint32 numEntries;

   /*
    * Packet of data, for both incoming and outgoing messages.
    * Include room for the command.
    */
   unsigned char buffer[];
} HgfsReq;

/* Public functions (with respect to the entire module). */
HgfsReq *HgfsGetNewRequest(void);
HgfsReq *HgfsCopyRequest(HgfsReq *req);
int HgfsSendRequest(HgfsReq *req);
HgfsReq *HgfsRequestGetRef(HgfsReq *req);
void HgfsRequestPutRef(HgfsReq *req);
#define HgfsFreeRequest(req)  HgfsRequestPutRef(req)
HgfsStatus HgfsReplyStatus(HgfsReq *req);
void HgfsCompleteReq(HgfsReq *req);
void HgfsFailReq(HgfsReq *req, int error);

#endif // _HGFS_DRIVER_REQUEST_H_