kernel debug: priv can be NULL early on
[minix.git] / lib / libhgfs / channel.c
blob3fca1beec434e7d70f03b711478e455147efd279
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(ch, type)
23 struct channel *ch; /* struct describing the new channel */
24 u32_t type; /* channel type: CH_IN or CH_OUT */
26 /* Open a new backdoor channel. Upon success, the given channel structure will
27 * be filled with information and can be used in subsequent channel calls.
28 * Return OK on success, or a negative error code on error.
30 u32_t ptr[6];
32 ptr[1] = type | 0x80000000;
33 ptr[2] = MAKELONG(CMD_XFER, XFER_OPEN);
35 backdoor(ptr);
37 if ((STATUS(ptr) & 1) == 0) return EIO;
39 ch->id = HIWORD(ptr[3]);
40 ch->cookie1 = ptr[4];
41 ch->cookie2 = ptr[5];
43 return OK;
46 /*===========================================================================*
47 * channel_close *
48 *===========================================================================*/
49 void channel_close(ch)
50 struct channel *ch; /* backdoor channel to close */
52 /* Close a previously opened backdoor channel.
54 u32_t ptr[6];
56 ptr[2] = MAKELONG(CMD_XFER, XFER_CLOSE);
57 ptr[3] = MAKELONG(0, ch->id);
58 ptr[4] = ch->cookie1;
59 ptr[5] = ch->cookie2;
61 backdoor(ptr);
64 /*===========================================================================*
65 * channel_send *
66 *===========================================================================*/
67 int channel_send(ch, buf, len)
68 struct channel *ch; /* backdoor channel to send to */
69 char *buf; /* buffer to send data from */
70 int len; /* size of the data to send */
72 /* Receive data over a backdoor channel. Return OK on success, or a negative
73 * error code on error.
75 u32_t ptr[7];
77 ptr[1] = len;
78 ptr[2] = MAKELONG(CMD_XFER, XFER_SENDLEN);
79 ptr[3] = MAKELONG(0, ch->id);
80 ptr[4] = ch->cookie1;
81 ptr[5] = ch->cookie2;
83 backdoor(ptr);
85 if ((STATUS(ptr) & 1) == 0) return EIO;
87 if (len == 0) return OK;
89 ptr[1] = MAKELONG(0, 1);
90 ptr[2] = len;
91 ptr[3] = MAKELONG(0, ch->id);
92 ptr[4] = (u32_t)buf;
93 ptr[5] = ch->cookie2;
94 ptr[6] = ch->cookie1;
96 backdoor_out(ptr);
98 return OK;
101 /*===========================================================================*
102 * channel_recv *
103 *===========================================================================*/
104 int channel_recv(ch, buf, max)
105 struct channel *ch; /* backdoor channel to receive from */
106 char *buf; /* buffer to receive data into */
107 int max; /* size of the buffer */
109 /* Receive data on a backdoor channel. Return the number of bytes received, or
110 * a negative error code on error.
112 u32_t ptr[7];
113 int len;
115 ptr[2] = MAKELONG(CMD_XFER, XFER_RECVLEN);
116 ptr[3] = MAKELONG(0, ch->id);
117 ptr[4] = ch->cookie1;
118 ptr[5] = ch->cookie2;
120 backdoor(ptr);
122 if ((STATUS(ptr) & 0x81) == 0) return EIO;
124 if ((len = ptr[1]) == 0 || (STATUS(ptr) & 3) == 1) return 0;
126 if (len > max) return E2BIG;
128 ptr[1] = MAKELONG(0, 1);
129 ptr[2] = len;
130 ptr[3] = MAKELONG(0, ch->id);
131 ptr[4] = ch->cookie1;
132 ptr[5] = (u32_t)buf;
133 ptr[6] = ch->cookie2;
135 backdoor_in(ptr);
137 ptr[1] = 1;
138 ptr[2] = MAKELONG(CMD_XFER, XFER_RECVACK);
139 ptr[3] = MAKELONG(0, ch->id);
140 ptr[4] = ch->cookie1;
141 ptr[5] = ch->cookie2;
143 backdoor(ptr);
145 return len;