Blame view

net/nfs.c 23.3 KB
cbd8a35c6   wdenk   * Patch by Masami...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  /*
   * NFS support driver - based on etherboot and U-BOOT's tftp.c
   *
   * Masami Komiya <mkomiya@sonare.it> 2004
   *
   */
  
  /* NOTE: the NFS code is heavily inspired by the NetBSD netboot code (read:
   * large portions are copied verbatim) as distributed in OSKit 0.97.  A few
   * changes were necessary to adapt the code to Etherboot and to fix several
   * inconsistencies.  Also the RPC message preparation is done "by hand" to
   * avoid adding netsprintf() which I find hard to understand and use.  */
  
  /* NOTE 2: Etherboot does not care about things beyond the kernel image, so
   * it loads the kernel image off the boot server (ARP_SERVER) and does not
   * access the client root disk (root-path in dhcpd.conf), which would use
   * ARP_ROOTSERVER.  The root disk is something the operating system we are
   * about to load needs to use.	This is different from the OSKit 0.97 logic.  */
  
  /* NOTE 3: Symlink handling introduced by Anselm M Hoffmeister, 2003-July-14
   * If a symlink is encountered, it is followed as far as possible (recursion
   * possible, maximum 16 steps). There is no clearing of ".."'s inside the
   * path, so please DON'T DO THAT. thx. */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
24
25
26
  /* NOTE 4: NFSv3 support added by Guillaume GARDET, 2016-June-20.
   * NFSv2 is still used by default. But if server does not support NFSv2, then
   * NFSv3 is used, if available on NFS server. */
cbd8a35c6   wdenk   * Patch by Masami...
27
28
29
30
  #include <common.h>
  #include <command.h>
  #include <net.h>
  #include <malloc.h>
55d5fd9a8   Joe Hershberger   net: Access mappe...
31
  #include <mapmem.h>
cbd8a35c6   wdenk   * Patch by Masami...
32
33
  #include "nfs.h"
  #include "bootp.h"
cbd8a35c6   wdenk   * Patch by Masami...
34
  #define HASHES_PER_LINE 65	/* Number of "loading" hashes per line	*/
fe891ecf4   Hiroshi Ito   NFS Timeout with ...
35
  #define NFS_RETRY_COUNT 30
48a3e999c   Tetsuyuki Kobayashi   net: nfs: make NF...
36
37
38
39
40
  #ifndef CONFIG_NFS_TIMEOUT
  # define NFS_TIMEOUT 2000UL
  #else
  # define NFS_TIMEOUT CONFIG_NFS_TIMEOUT
  #endif
cbd8a35c6   wdenk   * Patch by Masami...
41

fa84fa708   Matthias Brugger   net: nfs: add dyn...
42
43
  #define NFS_RPC_ERR	1
  #define NFS_RPC_DROP	124
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
44
45
  static int fs_mounted;
  static unsigned long rpc_id;
cbd8a35c6   wdenk   * Patch by Masami...
46
47
  static int nfs_offset = -1;
  static int nfs_len;
fa84fa708   Matthias Brugger   net: nfs: add dyn...
48
  static ulong nfs_timeout = NFS_TIMEOUT;
cbd8a35c6   wdenk   * Patch by Masami...
49

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
50
  static char dirfh[NFS_FHSIZE];	/* NFSv2 / NFSv3 file handle of directory */
5280c7691   Joe Hershberger   net: nfs: Share t...
51
52
  static char filefh[NFS3_FHSIZE]; /* NFSv2 / NFSv3 file handle */
  static int filefh3_length;	/* (variable) length of filefh when NFSv3 */
cbd8a35c6   wdenk   * Patch by Masami...
53

22f6e99d5   Joe Hershberger   net: Refactor to ...
54
  static enum net_loop_state nfs_download_state;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
55
  static struct in_addr nfs_server_ip;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
56
57
58
59
60
  static int nfs_server_mount_port;
  static int nfs_server_port;
  static int nfs_our_port;
  static int nfs_timeout_count;
  static int nfs_state;
cbd8a35c6   wdenk   * Patch by Masami...
61
62
63
64
65
66
67
  #define STATE_PRCLOOKUP_PROG_MOUNT_REQ	1
  #define STATE_PRCLOOKUP_PROG_NFS_REQ	2
  #define STATE_MOUNT_REQ			3
  #define STATE_UMOUNT_REQ		4
  #define STATE_LOOKUP_REQ		5
  #define STATE_READ_REQ			6
  #define STATE_READLINK_REQ		7
cbd8a35c6   wdenk   * Patch by Masami...
68
69
70
  static char *nfs_filename;
  static char *nfs_path;
  static char nfs_path_buff[2048];
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
71
72
73
  #define NFSV2_FLAG 1
  #define NFSV3_FLAG 1 << 1
  static char supported_nfs_versions = NFSV2_FLAG | NFSV3_FLAG;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
74
  static inline int store_block(uchar *src, unsigned offset, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
75
  {
a084f7da8   wdenk   * Patch by Masami...
76
  	ulong newsize = offset + len;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
77
  #ifdef CONFIG_SYS_DIRECT_FLASH_NFS
cbd8a35c6   wdenk   * Patch by Masami...
78
  	int i, rc = 0;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
79
  	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
cbd8a35c6   wdenk   * Patch by Masami...
80
81
82
83
84
85
86
87
  		/* start address in flash? */
  		if (load_addr + offset >= flash_info[i].start[0]) {
  			rc = 1;
  			break;
  		}
  	}
  
  	if (rc) { /* Flash is destination for this packet */
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
88
  		rc = flash_write((uchar *)src, (ulong)(load_addr+offset), len);
cbd8a35c6   wdenk   * Patch by Masami...
89
  		if (rc) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
90
  			flash_perror(rc);
23a7a32d4   Wolfgang Denk   Fix return code o...
91
  			return -1;
cbd8a35c6   wdenk   * Patch by Masami...
92
93
  		}
  	} else
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
94
  #endif /* CONFIG_SYS_DIRECT_FLASH_NFS */
cbd8a35c6   wdenk   * Patch by Masami...
95
  	{
55d5fd9a8   Joe Hershberger   net: Access mappe...
96
97
98
99
  		void *ptr = map_sysmem(load_addr + offset, len);
  
  		memcpy(ptr, src, len);
  		unmap_sysmem(ptr);
cbd8a35c6   wdenk   * Patch by Masami...
100
  	}
a084f7da8   wdenk   * Patch by Masami...
101

1411157d8   Joe Hershberger   net: cosmetic: Fi...
102
103
  	if (net_boot_file_size < (offset + len))
  		net_boot_file_size = newsize;
23a7a32d4   Wolfgang Denk   Fix return code o...
104
  	return 0;
cbd8a35c6   wdenk   * Patch by Masami...
105
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
106
  static char *basename(char *path)
cbd8a35c6   wdenk   * Patch by Masami...
107
108
109
110
111
112
113
114
115
116
117
118
119
  {
  	char *fname;
  
  	fname = path + strlen(path) - 1;
  	while (fname >= path) {
  		if (*fname == '/') {
  			fname++;
  			break;
  		}
  		fname--;
  	}
  	return fname;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
120
  static char *dirname(char *path)
cbd8a35c6   wdenk   * Patch by Masami...
121
122
  {
  	char *fname;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
123
  	fname = basename(path);
cbd8a35c6   wdenk   * Patch by Masami...
124
125
126
127
128
129
  	--fname;
  	*fname = '\0';
  	return path;
  }
  
  /**************************************************************************
cbd8a35c6   wdenk   * Patch by Masami...
130
131
  RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries
  **************************************************************************/
e4ead4a21   Ralf Hubert   net: Fix incorrec...
132
  static uint32_t *rpc_add_credentials(uint32_t *p)
cbd8a35c6   wdenk   * Patch by Masami...
133
  {
cbd8a35c6   wdenk   * Patch by Masami...
134
135
136
137
138
139
140
141
  	/* Here's the executive summary on authentication requirements of the
  	 * various NFS server implementations:	Linux accepts both AUTH_NONE
  	 * and AUTH_UNIX authentication (also accepts an empty hostname field
  	 * in the AUTH_UNIX scheme).  *BSD refuses AUTH_NONE, but accepts
  	 * AUTH_UNIX (also accepts an empty hostname field in the AUTH_UNIX
  	 * scheme).  To be safe, use AUTH_UNIX and pass the hostname if we have
  	 * it (if the BOOTP/DHCP reply didn't give one, just use an empty
  	 * hostname).  */
cbd8a35c6   wdenk   * Patch by Masami...
142
143
  	/* Provide an AUTH_UNIX credential.  */
  	*p++ = htonl(1);		/* AUTH_UNIX */
1ff65d440   Joe Hershberger   net: nfs: Simplif...
144
145
146
  	*p++ = htonl(20);		/* auth length */
  	*p++ = 0;			/* stamp */
  	*p++ = 0;			/* hostname string */
cbd8a35c6   wdenk   * Patch by Masami...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  	*p++ = 0;			/* uid */
  	*p++ = 0;			/* gid */
  	*p++ = 0;			/* auxiliary gid list */
  
  	/* Provide an AUTH_NONE verifier.  */
  	*p++ = 0;			/* AUTH_NONE */
  	*p++ = 0;			/* auth length */
  
  	return p;
  }
  
  /**************************************************************************
  RPC_LOOKUP - Lookup RPC Port numbers
  **************************************************************************/
a73588fe4   Joe Hershberger   Revert "net: nfs:...
161
  static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
cbd8a35c6   wdenk   * Patch by Masami...
162
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
163
  	struct rpc_t rpc_pkt;
cbd8a35c6   wdenk   * Patch by Masami...
164
  	unsigned long id;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
165
  	uint32_t *p;
cbd8a35c6   wdenk   * Patch by Masami...
166
167
  	int pktlen;
  	int sport;
c3f9d4939   wdenk   * Patch by Yuli B...
168
  	id = ++rpc_id;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
169
170
171
172
  	rpc_pkt.u.call.id = htonl(id);
  	rpc_pkt.u.call.type = htonl(MSG_CALL);
  	rpc_pkt.u.call.rpcvers = htonl(2);	/* use RPC version 2 */
  	rpc_pkt.u.call.prog = htonl(rpc_prog);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
173
174
175
  	switch (rpc_prog) {
  	case PROG_NFS:
  		if (supported_nfs_versions & NFSV2_FLAG)
a73588fe4   Joe Hershberger   Revert "net: nfs:...
176
  			rpc_pkt.u.call.vers = htonl(2);	/* NFS v2 */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
177
  		else /* NFSV3_FLAG */
a73588fe4   Joe Hershberger   Revert "net: nfs:...
178
  			rpc_pkt.u.call.vers = htonl(3);	/* NFS v3 */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
179
180
181
182
  		break;
  	case PROG_PORTMAP:
  	case PROG_MOUNT:
  	default:
a73588fe4   Joe Hershberger   Revert "net: nfs:...
183
  		rpc_pkt.u.call.vers = htonl(2);	/* portmapper is version 2 */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
184
  	}
a73588fe4   Joe Hershberger   Revert "net: nfs:...
185
186
187
188
189
190
191
  	rpc_pkt.u.call.proc = htonl(rpc_proc);
  	p = (uint32_t *)&(rpc_pkt.u.call.data);
  
  	if (datalen)
  		memcpy((char *)p, (char *)data, datalen*sizeof(uint32_t));
  
  	pktlen = (char *)p + datalen * sizeof(uint32_t) - (char *)&rpc_pkt;
cbd8a35c6   wdenk   * Patch by Masami...
192

a73588fe4   Joe Hershberger   Revert "net: nfs:...
193
194
  	memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE,
  	       &rpc_pkt.u.data[0], pktlen);
cbd8a35c6   wdenk   * Patch by Masami...
195
196
197
198
  
  	if (rpc_prog == PROG_PORTMAP)
  		sport = SUNRPC_PORT;
  	else if (rpc_prog == PROG_MOUNT)
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
199
  		sport = nfs_server_mount_port;
cbd8a35c6   wdenk   * Patch by Masami...
200
  	else
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
201
  		sport = nfs_server_port;
cbd8a35c6   wdenk   * Patch by Masami...
202

1203fccee   Joe Hershberger   net: cosmetic: Cl...
203
  	net_send_udp_packet(net_server_ethaddr, nfs_server_ip, sport,
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
204
  			    nfs_our_port, pktlen);
cbd8a35c6   wdenk   * Patch by Masami...
205
206
207
208
209
  }
  
  /**************************************************************************
  RPC_LOOKUP - Lookup RPC Port numbers
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
210
  static void rpc_lookup_req(int prog, int ver)
cbd8a35c6   wdenk   * Patch by Masami...
211
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
212
  	uint32_t data[16];
cbd8a35c6   wdenk   * Patch by Masami...
213
214
215
216
217
218
219
  
  	data[0] = 0; data[1] = 0;	/* auth credential */
  	data[2] = 0; data[3] = 0;	/* auth verifier */
  	data[4] = htonl(prog);
  	data[5] = htonl(ver);
  	data[6] = htonl(17);	/* IP_UDP */
  	data[7] = 0;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
220
  	rpc_req(PROG_PORTMAP, PORTMAP_GETPORT, data, 8);
cbd8a35c6   wdenk   * Patch by Masami...
221
222
223
224
225
  }
  
  /**************************************************************************
  NFS_MOUNT - Mount an NFS Filesystem
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
226
  static void nfs_mount_req(char *path)
cbd8a35c6   wdenk   * Patch by Masami...
227
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
228
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
229
230
231
  	uint32_t *p;
  	int len;
  	int pathlen;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
232
  	pathlen = strlen(path);
cbd8a35c6   wdenk   * Patch by Masami...
233

a73588fe4   Joe Hershberger   Revert "net: nfs:...
234
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
235
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
236
237
  
  	*p++ = htonl(pathlen);
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
238
239
240
  	if (pathlen & 3)
  		*(p + pathlen / 4) = 0;
  	memcpy(p, path, pathlen);
cbd8a35c6   wdenk   * Patch by Masami...
241
  	p += (pathlen + 3) / 4;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
242
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
243

a73588fe4   Joe Hershberger   Revert "net: nfs:...
244
  	rpc_req(PROG_MOUNT, MOUNT_ADDENTRY, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
245
246
247
248
249
  }
  
  /**************************************************************************
  NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
250
  static void nfs_umountall_req(void)
cbd8a35c6   wdenk   * Patch by Masami...
251
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
252
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
253
254
  	uint32_t *p;
  	int len;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
255
  	if ((nfs_server_mount_port == -1) || (!fs_mounted))
cbd8a35c6   wdenk   * Patch by Masami...
256
257
  		/* Nothing mounted, nothing to umount */
  		return;
cbd8a35c6   wdenk   * Patch by Masami...
258

a73588fe4   Joe Hershberger   Revert "net: nfs:...
259
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
260
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
261

a73588fe4   Joe Hershberger   Revert "net: nfs:...
262
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
263

a73588fe4   Joe Hershberger   Revert "net: nfs:...
264
  	rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
265
266
267
268
269
270
271
272
273
  }
  
  /***************************************************************************
   * NFS_READLINK (AH 2003-07-14)
   * This procedure is called when read of the first block fails -
   * this probably happens when it's a directory or a symlink
   * In case of successful readlink(), the dirname is manipulated,
   * so that inside the nfs() function a recursion can be done.
   **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
274
  static void nfs_readlink_req(void)
cbd8a35c6   wdenk   * Patch by Masami...
275
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
276
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
277
278
  	uint32_t *p;
  	int len;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
279
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
280
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
281

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
282
283
284
285
286
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(p, filefh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  	} else { /* NFSV3_FLAG */
  		*p++ = htonl(filefh3_length);
5280c7691   Joe Hershberger   net: nfs: Share t...
287
  		memcpy(p, filefh, filefh3_length);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
288
289
  		p += (filefh3_length / 4);
  	}
cbd8a35c6   wdenk   * Patch by Masami...
290

a73588fe4   Joe Hershberger   Revert "net: nfs:...
291
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
292

a73588fe4   Joe Hershberger   Revert "net: nfs:...
293
  	rpc_req(PROG_NFS, NFS_READLINK, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
294
295
296
297
298
  }
  
  /**************************************************************************
  NFS_LOOKUP - Lookup Pathname
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
299
  static void nfs_lookup_req(char *fname)
cbd8a35c6   wdenk   * Patch by Masami...
300
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
301
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
302
303
304
  	uint32_t *p;
  	int len;
  	int fnamelen;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
305
  	fnamelen = strlen(fname);
cbd8a35c6   wdenk   * Patch by Masami...
306

a73588fe4   Joe Hershberger   Revert "net: nfs:...
307
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
308
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
309

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
310
311
312
313
314
315
316
317
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(p, dirfh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  		*p++ = htonl(fnamelen);
  		if (fnamelen & 3)
  			*(p + fnamelen / 4) = 0;
  		memcpy(p, fname, fnamelen);
  		p += (fnamelen + 3) / 4;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
318
  		len = (uint32_t *)p - (uint32_t *)&(data[0]);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
319

a73588fe4   Joe Hershberger   Revert "net: nfs:...
320
  		rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
321
322
323
324
325
326
327
328
329
  	} else {  /* NFSV3_FLAG */
  		*p++ = htonl(NFS_FHSIZE);	/* Dir handle length */
  		memcpy(p, dirfh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  		*p++ = htonl(fnamelen);
  		if (fnamelen & 3)
  			*(p + fnamelen / 4) = 0;
  		memcpy(p, fname, fnamelen);
  		p += (fnamelen + 3) / 4;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
330
  		len = (uint32_t *)p - (uint32_t *)&(data[0]);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
331

a73588fe4   Joe Hershberger   Revert "net: nfs:...
332
  		rpc_req(PROG_NFS, NFS3PROC_LOOKUP, data, len);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
333
  	}
cbd8a35c6   wdenk   * Patch by Masami...
334
335
336
337
338
  }
  
  /**************************************************************************
  NFS_READ - Read File on NFS Server
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
339
  static void nfs_read_req(int offset, int readlen)
cbd8a35c6   wdenk   * Patch by Masami...
340
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
341
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
342
343
  	uint32_t *p;
  	int len;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
344
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
345
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
346

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
347
348
349
350
351
352
353
354
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(p, filefh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  		*p++ = htonl(offset);
  		*p++ = htonl(readlen);
  		*p++ = 0;
  	} else { /* NFSV3_FLAG */
  		*p++ = htonl(filefh3_length);
5280c7691   Joe Hershberger   net: nfs: Share t...
355
  		memcpy(p, filefh, filefh3_length);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
356
357
358
359
360
361
  		p += (filefh3_length / 4);
  		*p++ = htonl(0); /* offset is 64-bit long, so fill with 0 */
  		*p++ = htonl(offset);
  		*p++ = htonl(readlen);
  		*p++ = 0;
  	}
cbd8a35c6   wdenk   * Patch by Masami...
362

a73588fe4   Joe Hershberger   Revert "net: nfs:...
363
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
364

a73588fe4   Joe Hershberger   Revert "net: nfs:...
365
  	rpc_req(PROG_NFS, NFS_READ, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
366
367
368
369
370
  }
  
  /**************************************************************************
  RPC request dispatcher
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
371
  static void nfs_send(void)
cbd8a35c6   wdenk   * Patch by Masami...
372
  {
0ebf04c60   Robin Getz   minor debug clean...
373
374
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
375

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
376
  	switch (nfs_state) {
cbd8a35c6   wdenk   * Patch by Masami...
377
  	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
378
379
380
381
  		if (supported_nfs_versions & NFSV2_FLAG)
  			rpc_lookup_req(PROG_MOUNT, 1);
  		else  /* NFSV3_FLAG */
  			rpc_lookup_req(PROG_MOUNT, 3);
cbd8a35c6   wdenk   * Patch by Masami...
382
383
  		break;
  	case STATE_PRCLOOKUP_PROG_NFS_REQ:
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
384
385
386
387
  		if (supported_nfs_versions & NFSV2_FLAG)
  			rpc_lookup_req(PROG_NFS, 2);
  		else  /* NFSV3_FLAG */
  			rpc_lookup_req(PROG_NFS, 3);
cbd8a35c6   wdenk   * Patch by Masami...
388
389
  		break;
  	case STATE_MOUNT_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
390
  		nfs_mount_req(nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
391
392
  		break;
  	case STATE_UMOUNT_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
393
  		nfs_umountall_req();
cbd8a35c6   wdenk   * Patch by Masami...
394
395
  		break;
  	case STATE_LOOKUP_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
396
  		nfs_lookup_req(nfs_filename);
cbd8a35c6   wdenk   * Patch by Masami...
397
398
  		break;
  	case STATE_READ_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
399
  		nfs_read_req(nfs_offset, nfs_len);
cbd8a35c6   wdenk   * Patch by Masami...
400
401
  		break;
  	case STATE_READLINK_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
402
  		nfs_readlink_req();
cbd8a35c6   wdenk   * Patch by Masami...
403
404
405
406
407
408
409
  		break;
  	}
  }
  
  /**************************************************************************
  Handlers for the reply from server
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
410
  static int rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
411
412
  {
  	struct rpc_t rpc_pkt;
0517cc45e   Joe Hershberger   net: nfs: Use con...
413
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
414

0ebf04c60   Robin Getz   minor debug clean...
415
416
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
417

fa84fa708   Matthias Brugger   net: nfs: add dyn...
418
419
420
421
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
422

cbd8a35c6   wdenk   * Patch by Masami...
423
424
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
425
  	    rpc_pkt.u.reply.astatus)
c3f9d4939   wdenk   * Patch by Yuli B...
426
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
427
428
429
  
  	switch (prog) {
  	case PROG_MOUNT:
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
430
  		nfs_server_mount_port = ntohl(rpc_pkt.u.reply.data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
431
432
  		break;
  	case PROG_NFS:
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
433
  		nfs_server_port = ntohl(rpc_pkt.u.reply.data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
434
435
436
437
438
  		break;
  	}
  
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
439
  static int nfs_mount_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
440
441
  {
  	struct rpc_t rpc_pkt;
0ebf04c60   Robin Getz   minor debug clean...
442
443
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
444

0517cc45e   Joe Hershberger   net: nfs: Use con...
445
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
446

fa84fa708   Matthias Brugger   net: nfs: add dyn...
447
448
449
450
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
451

cbd8a35c6   wdenk   * Patch by Masami...
452
453
454
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
455
  	    rpc_pkt.u.reply.data[0])
cbd8a35c6   wdenk   * Patch by Masami...
456
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
457
458
  
  	fs_mounted = 1;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
459
  	/*  NFSv2 and NFSv3 use same structure */
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
460
  	memcpy(dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
cbd8a35c6   wdenk   * Patch by Masami...
461
462
463
  
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
464
  static int nfs_umountall_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
465
466
  {
  	struct rpc_t rpc_pkt;
0ebf04c60   Robin Getz   minor debug clean...
467
468
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
469

0517cc45e   Joe Hershberger   net: nfs: Use con...
470
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
471

fa84fa708   Matthias Brugger   net: nfs: add dyn...
472
473
474
475
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
476

cbd8a35c6   wdenk   * Patch by Masami...
477
478
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
479
  	    rpc_pkt.u.reply.astatus)
cbd8a35c6   wdenk   * Patch by Masami...
480
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
481
482
  
  	fs_mounted = 0;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
483
  	memset(dirfh, 0, sizeof(dirfh));
cbd8a35c6   wdenk   * Patch by Masami...
484
485
486
  
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
487
  static int nfs_lookup_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
488
489
  {
  	struct rpc_t rpc_pkt;
0ebf04c60   Robin Getz   minor debug clean...
490
491
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
492

0517cc45e   Joe Hershberger   net: nfs: Use con...
493
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
494

fa84fa708   Matthias Brugger   net: nfs: add dyn...
495
496
497
498
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
499

cbd8a35c6   wdenk   * Patch by Masami...
500
501
502
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
69fd0d413   Guillaume GARDET   NFS: Add error me...
503
504
  	    rpc_pkt.u.reply.data[0]) {
  		switch (ntohl(rpc_pkt.u.reply.astatus)) {
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
505
  		case NFS_RPC_SUCCESS: /* Not an error */
69fd0d413   Guillaume GARDET   NFS: Add error me...
506
  			break;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
507
508
509
510
511
  		case NFS_RPC_PROG_MISMATCH:
  			/* Remote can't support NFS version */
  			switch (ntohl(rpc_pkt.u.reply.data[0])) {
  			/* Minimal supported NFS version */
  			case 3:
faecf84ab   Joe Hershberger   net: Always print...
512
513
  				debug("*** Warning: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d
  ",
347a90159   Joe Hershberger   net: nfs: Fix lin...
514
515
  				      (supported_nfs_versions & NFSV2_FLAG) ?
  						2 : 3,
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
516
517
518
519
520
521
522
523
524
  				      ntohl(rpc_pkt.u.reply.data[0]),
  				      ntohl(rpc_pkt.u.reply.data[1]));
  				debug("Will retry with NFSv3
  ");
  				/* Clear NFSV2_FLAG from supported versions */
  				supported_nfs_versions &= ~NFSV2_FLAG;
  				return -NFS_RPC_PROG_MISMATCH;
  			case 4:
  			default:
d89ff2df3   Joe Hershberger   net: nfs: Move so...
525
526
527
528
  				puts("*** ERROR: NFS version not supported");
  				debug(": Requested: V%d, accepted: min V%d - max V%d
  ",
  				      (supported_nfs_versions & NFSV2_FLAG) ?
347a90159   Joe Hershberger   net: nfs: Fix lin...
529
  						2 : 3,
d89ff2df3   Joe Hershberger   net: nfs: Move so...
530
531
532
533
  				      ntohl(rpc_pkt.u.reply.data[0]),
  				      ntohl(rpc_pkt.u.reply.data[1]));
  				puts("
  ");
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
534
  			}
69fd0d413   Guillaume GARDET   NFS: Add error me...
535
  			break;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
536
537
538
539
  		case NFS_RPC_PROG_UNAVAIL:
  		case NFS_RPC_PROC_UNAVAIL:
  		case NFS_RPC_GARBAGE_ARGS:
  		case NFS_RPC_SYSTEM_ERR:
69fd0d413   Guillaume GARDET   NFS: Add error me...
540
  		default: /* Unknown error on 'accept state' flag */
d89ff2df3   Joe Hershberger   net: nfs: Move so...
541
542
543
  			debug("*** ERROR: accept state error (%d)
  ",
  			      ntohl(rpc_pkt.u.reply.astatus));
69fd0d413   Guillaume GARDET   NFS: Add error me...
544
545
  			break;
  		}
cbd8a35c6   wdenk   * Patch by Masami...
546
  		return -1;
69fd0d413   Guillaume GARDET   NFS: Add error me...
547
  	}
cbd8a35c6   wdenk   * Patch by Masami...
548

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
549
550
551
552
553
554
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
  	} else {  /* NFSV3_FLAG */
  		filefh3_length = ntohl(rpc_pkt.u.reply.data[1]);
  		if (filefh3_length > NFS3_FHSIZE)
  			filefh3_length  = NFS3_FHSIZE;
5280c7691   Joe Hershberger   net: nfs: Share t...
555
  		memcpy(filefh, rpc_pkt.u.reply.data + 2, filefh3_length);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
556
  	}
cbd8a35c6   wdenk   * Patch by Masami...
557
558
559
  
  	return 0;
  }
051ed9af8   Joe Hershberger   net: nfs: Consoli...
560
561
562
563
  static int nfs3_get_attributes_offset(uint32_t *data)
  {
  	if (ntohl(data[1]) != 0) {
  		/* 'attributes_follow' flag is TRUE,
c629c45f3   Joe Hershberger   net: nfs: Correct...
564
  		 * so we have attributes on 21 dwords */
051ed9af8   Joe Hershberger   net: nfs: Consoli...
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
  		/* Skip unused values :
  			type;	32 bits value,
  			mode;	32 bits value,
  			nlink;	32 bits value,
  			uid;	32 bits value,
  			gid;	32 bits value,
  			size;	64 bits value,
  			used;	64 bits value,
  			rdev;	64 bits value,
  			fsid;	64 bits value,
  			fileid;	64 bits value,
  			atime;	64 bits value,
  			mtime;	64 bits value,
  			ctime;	64 bits value,
  		*/
  		return 22;
  	} else {
  		/* 'attributes_follow' flag is FALSE,
  		 * so we don't have any attributes */
  		return 1;
  	}
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
587
  static int nfs_readlink_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
588
589
590
  {
  	struct rpc_t rpc_pkt;
  	int rlen;
051ed9af8   Joe Hershberger   net: nfs: Consoli...
591
  	int nfsv3_data_offset = 0;
cbd8a35c6   wdenk   * Patch by Masami...
592

0ebf04c60   Robin Getz   minor debug clean...
593
594
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
595

c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
596
  	memcpy((unsigned char *)&rpc_pkt, pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
597

fa84fa708   Matthias Brugger   net: nfs: add dyn...
598
599
600
601
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
602

cbd8a35c6   wdenk   * Patch by Masami...
603
604
605
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
606
  	    rpc_pkt.u.reply.data[0])
cbd8a35c6   wdenk   * Patch by Masami...
607
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
608

051ed9af8   Joe Hershberger   net: nfs: Consoli...
609
610
611
612
  	if (!(supported_nfs_versions & NFSV2_FLAG)) { /* NFSV3_FLAG */
  		nfsv3_data_offset =
  			nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
  	}
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
613

051ed9af8   Joe Hershberger   net: nfs: Consoli...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
  	/* new path length */
  	rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
  
  	if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') {
  		int pathlen;
  
  		strcat(nfs_path, "/");
  		pathlen = strlen(nfs_path);
  		memcpy(nfs_path + pathlen,
  		       (uchar *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset]),
  		       rlen);
  		nfs_path[pathlen + rlen] = 0;
  	} else {
  		memcpy(nfs_path,
  		       (uchar *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset]),
  		       rlen);
  		nfs_path[rlen] = 0;
cbd8a35c6   wdenk   * Patch by Masami...
631
632
633
  	}
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
634
  static int nfs_read_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
635
636
637
  {
  	struct rpc_t rpc_pkt;
  	int rlen;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
638
  	uchar *data_ptr;
cbd8a35c6   wdenk   * Patch by Masami...
639

0ebf04c60   Robin Getz   minor debug clean...
640
641
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
642

0517cc45e   Joe Hershberger   net: nfs: Use con...
643
  	memcpy(&rpc_pkt.u.data[0], pkt, sizeof(rpc_pkt.u.reply));
cbd8a35c6   wdenk   * Patch by Masami...
644

fa84fa708   Matthias Brugger   net: nfs: add dyn...
645
646
647
648
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
649

cbd8a35c6   wdenk   * Patch by Masami...
650
651
652
653
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
  	    rpc_pkt.u.reply.data[0]) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
654
  		if (rpc_pkt.u.reply.rstatus)
cbd8a35c6   wdenk   * Patch by Masami...
655
  			return -9999;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
656
  		if (rpc_pkt.u.reply.astatus)
cbd8a35c6   wdenk   * Patch by Masami...
657
  			return -9999;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
658
  		return -ntohl(rpc_pkt.u.reply.data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
659
  	}
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
660
661
662
663
664
665
  	if ((nfs_offset != 0) && !((nfs_offset) %
  			(NFS_READ_SIZE / 2 * 10 * HASHES_PER_LINE)))
  		puts("
  \t ");
  	if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10)))
  		putc('#');
cbd8a35c6   wdenk   * Patch by Masami...
666

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
667
668
669
670
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		rlen = ntohl(rpc_pkt.u.reply.data[18]);
  		data_ptr = (uchar *)&(rpc_pkt.u.reply.data[19]);
  	} else {  /* NFSV3_FLAG */
051ed9af8   Joe Hershberger   net: nfs: Consoli...
671
672
673
674
675
676
677
678
679
680
681
  		int nfsv3_data_offset =
  			nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
  
  		/* count value */
  		rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
  		/* Skip unused values :
  			EOF:		32 bits value,
  			data_size:	32 bits value,
  		*/
  		data_ptr = (uchar *)
  			&(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
682
683
684
685
  	}
  
  	if (store_block(data_ptr, nfs_offset, rlen))
  			return -9999;
cbd8a35c6   wdenk   * Patch by Masami...
686
687
688
689
690
691
692
  
  	return rlen;
  }
  
  /**************************************************************************
  Interfaces of U-BOOT
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
693
  static void nfs_timeout_handler(void)
a5725fabc   wdenk   * Patch by Ganapa...
694
  {
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
695
  	if (++nfs_timeout_count > NFS_RETRY_COUNT) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
696
697
698
  		puts("
  Retry count exceeded; starting again
  ");
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
699
  		net_start_again();
aabb8cb08   Evan Samanas   nfs: NfsTimeout()...
700
701
  	} else {
  		puts("T ");
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
702
703
704
  		net_set_timeout_handler(nfs_timeout +
  					NFS_TIMEOUT * nfs_timeout_count,
  					nfs_timeout_handler);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
705
  		nfs_send();
fe891ecf4   Hiroshi Ito   NFS Timeout with ...
706
  	}
a5725fabc   wdenk   * Patch by Ganapa...
707
  }
049a95a77   Joe Hershberger   net: cosmetic: Ch...
708
709
  static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip,
  			unsigned src, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
710
711
  {
  	int rlen;
fa84fa708   Matthias Brugger   net: nfs: add dyn...
712
  	int reply;
cbd8a35c6   wdenk   * Patch by Masami...
713

0ebf04c60   Robin Getz   minor debug clean...
714
715
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
716

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
717
  	if (dest != nfs_our_port)
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
718
  		return;
cbd8a35c6   wdenk   * Patch by Masami...
719

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
720
  	switch (nfs_state) {
cbd8a35c6   wdenk   * Patch by Masami...
721
  	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
722
723
  		if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP)
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
724
725
  		nfs_state = STATE_PRCLOOKUP_PROG_NFS_REQ;
  		nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
726
727
728
  		break;
  
  	case STATE_PRCLOOKUP_PROG_NFS_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
729
730
  		if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP)
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
731
732
  		nfs_state = STATE_MOUNT_REQ;
  		nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
733
734
735
  		break;
  
  	case STATE_MOUNT_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
736
  		reply = nfs_mount_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
737
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
738
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
739
  		} else if (reply == -NFS_RPC_ERR) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
740
741
  			puts("*** ERROR: Cannot mount
  ");
cbd8a35c6   wdenk   * Patch by Masami...
742
  			/* just to be sure... */
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
743
744
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
745
  		} else {
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
746
747
  			nfs_state = STATE_LOOKUP_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
748
749
750
751
  		}
  		break;
  
  	case STATE_UMOUNT_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
752
  		reply = nfs_umountall_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
753
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
754
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
755
  		} else if (reply == -NFS_RPC_ERR) {
d89ff2df3   Joe Hershberger   net: nfs: Move so...
756
757
  			debug("*** ERROR: Cannot umount
  ");
22f6e99d5   Joe Hershberger   net: Refactor to ...
758
  			net_set_state(NETLOOP_FAIL);
cbd8a35c6   wdenk   * Patch by Masami...
759
  		} else {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
760
761
762
  			puts("
  done
  ");
22f6e99d5   Joe Hershberger   net: Refactor to ...
763
  			net_set_state(nfs_download_state);
cbd8a35c6   wdenk   * Patch by Masami...
764
765
766
767
  		}
  		break;
  
  	case STATE_LOOKUP_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
768
  		reply = nfs_lookup_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
769
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
770
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
771
  		} else if (reply == -NFS_RPC_ERR) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
772
773
  			puts("*** ERROR: File lookup fail
  ");
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
774
775
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
347a90159   Joe Hershberger   net: nfs: Fix lin...
776
777
  		} else if (reply == -NFS_RPC_PROG_MISMATCH &&
  			   supported_nfs_versions != 0) {
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
778
779
780
781
782
783
  			/* umount */
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
  			/* And retry with another supported version */
  			nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
784
  		} else {
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
785
  			nfs_state = STATE_READ_REQ;
cbd8a35c6   wdenk   * Patch by Masami...
786
787
  			nfs_offset = 0;
  			nfs_len = NFS_READ_SIZE;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
788
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
789
790
791
792
  		}
  		break;
  
  	case STATE_READLINK_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
793
  		reply = nfs_readlink_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
794
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
795
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
796
  		} else if (reply == -NFS_RPC_ERR) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
797
798
  			puts("*** ERROR: Symlink fail
  ");
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
799
800
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
801
  		} else {
0ebf04c60   Robin Getz   minor debug clean...
802
803
  			debug("Symlink --> %s
  ", nfs_path);
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
804
805
  			nfs_filename = basename(nfs_path);
  			nfs_path     = dirname(nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
806

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
807
808
  			nfs_state = STATE_MOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
809
810
811
812
  		}
  		break;
  
  	case STATE_READ_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
813
  		rlen = nfs_read_reply(pkt, len);
d48d40a09   Vasily Khoruzhick   net: nfs: don't f...
814
815
  		if (rlen == -NFS_RPC_DROP)
  			break;
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
816
  		net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
cbd8a35c6   wdenk   * Patch by Masami...
817
818
  		if (rlen > 0) {
  			nfs_offset += rlen;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
819
  			nfs_send();
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
820
  		} else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) {
cbd8a35c6   wdenk   * Patch by Masami...
821
  			/* symbolic link */
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
822
823
  			nfs_state = STATE_READLINK_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
824
  		} else {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
825
  			if (!rlen)
22f6e99d5   Joe Hershberger   net: Refactor to ...
826
  				nfs_download_state = NETLOOP_SUCCESS;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
827
  			if (rlen < 0)
d89ff2df3   Joe Hershberger   net: nfs: Move so...
828
829
  				debug("NFS READ error (%d)
  ", rlen);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
830
831
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
832
833
834
835
  		}
  		break;
  	}
  }
cbd8a35c6   wdenk   * Patch by Masami...
836

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
837
  void nfs_start(void)
cbd8a35c6   wdenk   * Patch by Masami...
838
  {
0ebf04c60   Robin Getz   minor debug clean...
839
840
  	debug("%s
  ", __func__);
22f6e99d5   Joe Hershberger   net: Refactor to ...
841
  	nfs_download_state = NETLOOP_FAIL;
cbd8a35c6   wdenk   * Patch by Masami...
842

049a95a77   Joe Hershberger   net: cosmetic: Ch...
843
  	nfs_server_ip = net_server_ip;
cbd8a35c6   wdenk   * Patch by Masami...
844
845
846
  	nfs_path = (char *)nfs_path_buff;
  
  	if (nfs_path == NULL) {
22f6e99d5   Joe Hershberger   net: Refactor to ...
847
  		net_set_state(NETLOOP_FAIL);
faecf84ab   Joe Hershberger   net: Always print...
848
849
  		printf("*** ERROR: Fail allocate memory
  ");
cbd8a35c6   wdenk   * Patch by Masami...
850
851
  		return;
  	}
6ab128309   Joe Hershberger   net: Consolidate ...
852
853
  	if (!net_parse_bootfile(&nfs_server_ip, nfs_path,
  				sizeof(nfs_path_buff))) {
f8b26c7ad   Joe Hershberger   net: nfs: Remove ...
854
  		sprintf(nfs_path, "/nfsroot/%02X%02X%02X%02X.img",
049a95a77   Joe Hershberger   net: cosmetic: Ch...
855
856
857
858
  			net_ip.s_addr & 0xFF,
  			(net_ip.s_addr >>  8) & 0xFF,
  			(net_ip.s_addr >> 16) & 0xFF,
  			(net_ip.s_addr >> 24) & 0xFF);
cbd8a35c6   wdenk   * Patch by Masami...
859

faecf84ab   Joe Hershberger   net: Always print...
860
861
862
  		printf("*** Warning: no boot file name; using '%s'
  ",
  		       nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
863
  	}
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
864
865
  	nfs_filename = basename(nfs_path);
  	nfs_path     = dirname(nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
866

faecf84ab   Joe Hershberger   net: Always print...
867
868
  	printf("Using %s device
  ", eth_get_name());
cbd8a35c6   wdenk   * Patch by Masami...
869

faecf84ab   Joe Hershberger   net: Always print...
870
871
  	printf("File transfer via NFS from server %pI4; our IP address is %pI4",
  	       &nfs_server_ip, &net_ip);
cbd8a35c6   wdenk   * Patch by Masami...
872
873
  
  	/* Check if we need to send across this subnet */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
874
875
876
  	if (net_gateway.s_addr && net_netmask.s_addr) {
  		struct in_addr our_net;
  		struct in_addr server_net;
cbd8a35c6   wdenk   * Patch by Masami...
877

049a95a77   Joe Hershberger   net: cosmetic: Ch...
878
  		our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
347e32b01   Joe Hershberger   net: Check subnet...
879
  		server_net.s_addr = nfs_server_ip.s_addr & net_netmask.s_addr;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
880
  		if (our_net.s_addr != server_net.s_addr)
faecf84ab   Joe Hershberger   net: Always print...
881
882
  			printf("; sending through gateway %pI4",
  			       &net_gateway);
cbd8a35c6   wdenk   * Patch by Masami...
883
  	}
faecf84ab   Joe Hershberger   net: Always print...
884
885
  	printf("
  Filename '%s/%s'.", nfs_path, nfs_filename);
cbd8a35c6   wdenk   * Patch by Masami...
886

1411157d8   Joe Hershberger   net: cosmetic: Fi...
887
  	if (net_boot_file_expected_size_in_blocks) {
faecf84ab   Joe Hershberger   net: Always print...
888
889
  		printf(" Size is 0x%x Bytes = ",
  		       net_boot_file_expected_size_in_blocks << 9);
1411157d8   Joe Hershberger   net: cosmetic: Fi...
890
  		print_size(net_boot_file_expected_size_in_blocks << 9, "");
cbd8a35c6   wdenk   * Patch by Masami...
891
  	}
faecf84ab   Joe Hershberger   net: Always print...
892
893
894
  	printf("
  Load address: 0x%lx
  Loading: *\b", load_addr);
cbd8a35c6   wdenk   * Patch by Masami...
895

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
896
  	net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
049a95a77   Joe Hershberger   net: cosmetic: Ch...
897
  	net_set_udp_handler(nfs_handler);
cbd8a35c6   wdenk   * Patch by Masami...
898

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
899
900
  	nfs_timeout_count = 0;
  	nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
cbd8a35c6   wdenk   * Patch by Masami...
901

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
902
  	/*nfs_our_port = 4096 + (get_ticks() % 3072);*/
cbd8a35c6   wdenk   * Patch by Masami...
903
  	/*FIX ME !!!*/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
904
  	nfs_our_port = 1000;
cbd8a35c6   wdenk   * Patch by Masami...
905
906
  
  	/* zero out server ether in case the server ip has changed */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
907
  	memset(net_server_ethaddr, 0, 6);
cbd8a35c6   wdenk   * Patch by Masami...
908

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
909
  	nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
910
  }