etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libhgfs / channel.c
blob985e842934bbcaaaff27749dd4dc1b48c17a3eba
1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
3 #include "inc.h"
5 #define CMD_XFER 0x1E /* vmware backdoor transfer command */
7 enum {
8 XFER_OPEN, /* open transfer channel */
9 XFER_SENDLEN, /* specify length of data to send */
10 XFER_SEND, /* send data */
11 XFER_RECVLEN, /* get length of data to receive */
12 XFER_RECV, /* receive data */
13 XFER_RECVACK, /* acknowledge receipt of data */
14 XFER_CLOSE /* close transfer channel */
17 #define STATUS(p) (HIWORD((p)[2]) & 0xff)
19 /*===========================================================================*
20 * channel_open *
21 *===========================================================================*/
22 int channel_open(
23 struct channel *ch, /* struct describing the new channel */
24 u32_t type /* channel type: CH_IN or CH_OUT */
27 /* Open a new backdoor channel. Upon success, the given channel structure will
28 * be filled with information and can be used in subsequent channel calls.
29 * Return OK on success, or a negative error code on error.
31 u32_t ptr[6];
33 ptr[1] = type | 0x80000000;
34 ptr[2] = MAKELONG(CMD_XFER, XFER_OPEN);
36 backdoor(ptr);
38 if ((STATUS(ptr) & 1) == 0) return EIO;
40 ch->id = HIWORD(ptr[3]);
41 ch->cookie1 = ptr[4];
42 ch->cookie2 = ptr[5];
44 return OK;
47 /*===========================================================================*
48 * channel_close *
49 *===========================================================================*/
50 void channel_close(
51 struct channel *ch /* backdoor channel to close */
54 /* Close a previously opened backdoor channel.
56 u32_t ptr[6];
58 ptr[2] = MAKELONG(CMD_XFER, XFER_CLOSE);
59 ptr[3] = MAKELONG(0, ch->id);
60 ptr[4] = ch->cookie1;
61 ptr[5] = ch->cookie2;
63 backdoor(ptr);
66 /*===========================================================================*
67 * channel_send *
68 *===========================================================================*/
69 int channel_send(
70 struct channel *ch, /* backdoor channel to send to */
71 char *buf, /* buffer to send data from */
72 int len /* size of the data to send */
75 /* Receive data over a backdoor channel. Return OK on success, or a negative
76 * error code on error.
78 u32_t ptr[7];
80 ptr[1] = len;
81 ptr[2] = MAKELONG(CMD_XFER, XFER_SENDLEN);
82 ptr[3] = MAKELONG(0, ch->id);
83 ptr[4] = ch->cookie1;
84 ptr[5] = ch->cookie2;
86 backdoor(ptr);
88 if ((STATUS(ptr) & 1) == 0) return EIO;
90 if (len == 0) return OK;
92 ptr[1] = MAKELONG(0, 1);
93 ptr[2] = len;
94 ptr[3] = MAKELONG(0, ch->id);
95 ptr[4] = (u32_t)buf;
96 ptr[5] = ch->cookie2;
97 ptr[6] = ch->cookie1;
99 backdoor_out(ptr);
101 return OK;
104 /*===========================================================================*
105 * channel_recv *
106 *===========================================================================*/
107 int channel_recv(
108 struct channel *ch, /* backdoor channel to receive from */
109 char *buf, /* buffer to receive data into */
110 int max /* size of the buffer */
113 /* Receive data on a backdoor channel. Return the number of bytes received, or
114 * a negative error code on error.
116 u32_t ptr[7];
117 int len;
119 ptr[2] = MAKELONG(CMD_XFER, XFER_RECVLEN);
120 ptr[3] = MAKELONG(0, ch->id);
121 ptr[4] = ch->cookie1;
122 ptr[5] = ch->cookie2;
124 backdoor(ptr);
126 if ((STATUS(ptr) & 0x81) == 0) return EIO;
128 if ((len = ptr[1]) == 0 || (STATUS(ptr) & 3) == 1) return 0;
130 if (len > max) return E2BIG;
132 ptr[1] = MAKELONG(0, 1);
133 ptr[2] = len;
134 ptr[3] = MAKELONG(0, ch->id);
135 ptr[4] = ch->cookie1;
136 ptr[5] = (u32_t)buf;
137 ptr[6] = ch->cookie2;
139 backdoor_in(ptr);
141 ptr[1] = 1;
142 ptr[2] = MAKELONG(CMD_XFER, XFER_RECVACK);
143 ptr[3] = MAKELONG(0, ch->id);
144 ptr[4] = ch->cookie1;
145 ptr[5] = ch->cookie2;
147 backdoor(ptr);
149 return len;