1
/*********************************************************
2
* Copyright (C) 2010 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation version 2 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
*********************************************************/
28
static Bool HgfsBdChannelOpen(HgfsTransportChannel *channel);
29
static void HgfsBdChannelClose(HgfsTransportChannel *channel);
30
static HgfsKReqObject * HgfsBdChannelAllocate(size_t payloadSize, int flags);
31
void HgfsBdChannelFree(HgfsKReqObject *req, size_t payloadSize);
32
static int HgfsBdChannelSend(HgfsTransportChannel *channel, HgfsKReqObject *req);
34
static HgfsTransportChannel gBdChannel = {
36
.ops.open = HgfsBdChannelOpen,
37
.ops.close = HgfsBdChannelClose,
38
.ops.allocate = HgfsBdChannelAllocate,
39
.ops.free = HgfsBdChannelFree,
40
.ops.send = HgfsBdChannelSend,
42
.status = HGFS_CHANNEL_NOTCONNECTED
47
*-----------------------------------------------------------------------------
49
* HgfsBdChannelOpen --
51
* Open the backdoor in an idempotent way.
54
* TRUE on success, FALSE on failure.
59
*-----------------------------------------------------------------------------
63
HgfsBdChannelOpen(HgfsTransportChannel *channel) // IN: Channel
67
if ((ret = HgfsBd_OpenBackdoor((RpcOut **)&channel->priv))) {
68
DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor opened.\n", __func__);
69
ASSERT(channel->priv != NULL);
70
channel->status = HGFS_CHANNEL_CONNECTED;
78
*-----------------------------------------------------------------------------
80
* HgfsBdChannelClose --
82
* Close the backdoor in an idempotent way.
90
*-----------------------------------------------------------------------------
94
HgfsBdChannelClose(HgfsTransportChannel *channel) // IN: Channel
98
if (channel->priv == NULL) {
102
ret = HgfsBd_CloseBackdoor((RpcOut **)&channel->priv);
104
DEBUG(VM_DEBUG_FAIL, "VMware hgfs: %s: Failed to close backdoor.\n", __func__);
106
DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor closed.\n", __func__);
108
channel->status = HGFS_CHANNEL_NOTCONNECTED;
113
*-----------------------------------------------------------------------------
115
* HgfsBdChannelAllocate --
117
* Allocate request in a way that is suitable for sending through
121
* NULL on failure; otherwise address of the new request.
126
*-----------------------------------------------------------------------------
129
static HgfsKReqObject *
130
HgfsBdChannelAllocate(size_t payloadSize, // IN: Size of allocation
133
return os_malloc(payloadSize, flags);
138
*-----------------------------------------------------------------------------
140
* HgfsBdChannelFree --
142
* Free previously allocated request.
150
*-----------------------------------------------------------------------------
154
HgfsBdChannelFree(HgfsKReqObject *req, // IN:
155
size_t payloadSize) // IN:
158
os_free(req, payloadSize);
163
*----------------------------------------------------------------------
165
* HgfsBdChannelSend --
167
* Send a request via backdoor.
170
* 0 on success, negative error on failure.
175
*----------------------------------------------------------------------
179
HgfsBdChannelSend(HgfsTransportChannel *channel, // IN: Channel
180
HgfsKReqObject *req) // IN: request to send
182
char const *replyPacket = NULL;
187
DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor sending.\n", __func__);
189
bcopy(HGFS_SYNC_REQREP_CLIENT_CMD, req->__rpc_packet._command,
190
HGFS_SYNC_REQREP_CLIENT_CMD_LEN);
192
ret = HgfsBd_Dispatch(channel->priv, req->payload, &req->payloadSize,
194
os_mutex_lock(req->stateLock);
197
* We have a response. (Maybe.) Re-lock the request, update its state,
200
if ((ret == 0) && (req->state == HGFS_REQ_SUBMITTED)) {
201
DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: Success in backdoor.\n", __func__);
202
bcopy(replyPacket, req->payload, req->payloadSize);
203
req->state = HGFS_REQ_COMPLETED;
205
DEBUG(VM_DEBUG_INFO, "hgfs: %s: Error in backdoor.\n", __func__);
206
req->state = HGFS_REQ_ERROR;
209
os_cv_signal(&req->stateCv);
210
os_mutex_unlock(req->stateLock);
216
*----------------------------------------------------------------------
218
* HgfsGetBdChannel --
220
* Get backdoor channel.
223
* Always return pointer to back door channel.
228
*----------------------------------------------------------------------
231
HgfsTransportChannel*
232
HgfsGetBdChannel(void)