#include "nfs.h"
#include "bootp.h"
-/*#define NFS_DEBUG*/
-
-#if ((CONFIG_COMMANDS & CFG_CMD_NET) && (CONFIG_COMMANDS & CFG_CMD_NFS))
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_CMD_NFS)
#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */
-#define NFS_TIMEOUT 10
+#define NFS_RETRY_COUNT 30
+#define NFS_TIMEOUT 2000UL
static int fs_mounted = 0;
-static unsigned long rpc_id;
+static unsigned long rpc_id = 0;
static int nfs_offset = -1;
static int nfs_len;
static char dirfh[NFS_FHSIZE]; /* file handle of directory */
static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
+static int NfsDownloadState;
static IPaddr_t NfsServerIP;
static int NfsSrvMountPort;
static int NfsSrvNfsPort;
static char *nfs_path;
static char nfs_path_buff[2048];
-static __inline__ void
+static __inline__ int
store_block (uchar * src, unsigned offset, unsigned len)
{
ulong newsize = offset + len;
-#ifdef CFG_DIRECT_FLASH_NFS
+#ifdef CONFIG_SYS_DIRECT_FLASH_NFS
int i, rc = 0;
- for (i=0; i<CFG_MAX_FLASH_BANKS; i++) {
+ for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; i++) {
/* start address in flash? */
if (load_addr + offset >= flash_info[i].start[0]) {
rc = 1;
rc = flash_write ((uchar *)src, (ulong)(load_addr+offset), len);
if (rc) {
flash_perror (rc);
- NetState = NETLOOP_FAIL;
- return;
+ return -1;
}
} else
-#endif /* CFG_DIRECT_FLASH_NFS */
+#endif /* CONFIG_SYS_DIRECT_FLASH_NFS */
{
(void)memcpy ((void *)(load_addr + offset), src, len);
}
if (NetBootFileXferSize < (offset+len))
NetBootFileXferSize = newsize;
+ return 0;
}
static char*
return path;
}
-/**************************************************************************
-RPC_INIT - set up the ID counter to something fairly random
-**************************************************************************/
-static void
-rpc_init (void)
-{
- unsigned long t;
- t=get_ticks();
- rpc_id = t ^ (t << 8) ^ (t << 16);
-}
-
/**************************************************************************
RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries
**************************************************************************/
int pktlen;
int sport;
- id = rpc_id++;
+ id = ++rpc_id;
pkt.u.call.id = htonl(id);
pkt.u.call.type = htonl(MSG_CALL);
pkt.u.call.rpcvers = htonl(2); /* use RPC version 2 */
pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt;
- memcpy ((char *)NetTxPacket+ETHER_HDR_SIZE+IP_HDR_SIZE, (char *)&pkt, pktlen);
+ memcpy ((char *)NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE, (char *)&pkt, pktlen);
if (rpc_prog == PROG_PORTMAP)
sport = SUNRPC_PORT;
static void
NfsSend (void)
{
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
switch (NfsState) {
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
+
+ if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+ return -1;
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
- rpc_pkt.u.reply.astatus ||
rpc_pkt.u.reply.astatus) {
+ return -1;
}
switch (prog) {
{
struct rpc_t rpc_pkt;
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+ return -1;
+
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
{
struct rpc_t rpc_pkt;
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+ return -1;
+
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus) {
{
struct rpc_t rpc_pkt;
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+ return -1;
+
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
struct rpc_t rpc_pkt;
int rlen;
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
memcpy ((unsigned char *)&rpc_pkt, pkt, len);
+ if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+ return -1;
+
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
rpc_pkt.u.reply.astatus ||
strcat (nfs_path, "/");
pathlen = strlen(nfs_path);
memcpy (nfs_path+pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
- nfs_path[pathlen+rlen+1] = 0;
+ nfs_path[pathlen + rlen] = 0;
} else {
memcpy (nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
nfs_path[rlen] = 0;
struct rpc_t rpc_pkt;
int rlen;
-#ifdef NFS_DEBUG_nop
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
- memcpy ((uchar *)&rpc_pkt, pkt, len);
+ memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply));
+
+ if (ntohl(rpc_pkt.u.reply.id) != rpc_id)
+ return -1;
if (rpc_pkt.u.reply.rstatus ||
rpc_pkt.u.reply.verifier ||
}
rlen = ntohl(rpc_pkt.u.reply.data[18]);
- store_block ((uchar *)&(rpc_pkt.u.reply.data[19]), nfs_offset, rlen);
+ if ( store_block ((uchar *)pkt+sizeof(rpc_pkt.u.reply), nfs_offset, rlen) )
+ return -9999;
return rlen;
}
Interfaces of U-BOOT
**************************************************************************/
+static void
+NfsTimeout (void)
+{
+ if ( ++NfsTimeoutCount > NFS_RETRY_COUNT ) {
+ puts ("\nRetry count exceeded; starting again\n");
+ NetStartAgain ();
+ } else {
+ puts("T ");
+ NetSetTimeout (NFS_TIMEOUT, NfsTimeout);
+ NfsSend ();
+ }
+}
+
static void
NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
int rlen;
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
if (dest != NfsOurPort) return;
NetState = NETLOOP_FAIL;
} else {
puts ("\ndone\n");
- NetState = NETLOOP_SUCCESS;
+ NetState = NfsDownloadState;
}
break;
NfsState = STATE_UMOUNT_REQ;
NfsSend ();
} else {
-#ifdef NFS_DEBUG
- printf ("Symlink --> %s\n", nfs_path);
-#endif
+ debug("Symlink --> %s\n", nfs_path);
nfs_filename = basename (nfs_path);
nfs_path = dirname (nfs_path);
case STATE_READ_REQ:
rlen = nfs_read_reply (pkt, len);
+ NetSetTimeout (NFS_TIMEOUT, NfsTimeout);
if (rlen > 0) {
nfs_offset += rlen;
NfsSend ();
NfsState = STATE_READLINK_REQ;
NfsSend ();
} else {
+ if ( ! rlen ) NfsDownloadState = NETLOOP_SUCCESS;
NfsState = STATE_UMOUNT_REQ;
NfsSend ();
}
}
}
-static void
-NfsTimeout (void)
-{
- puts ("Timeout\n");
- NetState = NETLOOP_FAIL;
- return;
-}
void
NfsStart (void)
{
-#ifdef NFS_DEBUG
- printf ("%s\n", __FUNCTION__);
-#endif
+ debug("%s\n", __func__);
+ NfsDownloadState = NETLOOP_FAIL;
NfsServerIP = NetServerIP;
nfs_path = (char *)nfs_path_buff;
}
if (BootFile[0] == '\0') {
- IPaddr_t OurIP = ntohl (NetOurIP);
-
sprintf (default_filename, "/nfsroot/%02lX%02lX%02lX%02lX.img",
- OurIP & 0xFF,
- (OurIP >> 8) & 0xFF,
- (OurIP >> 16) & 0xFF,
- (OurIP >> 24) & 0xFF );
+ NetOurIP & 0xFF,
+ (NetOurIP >> 8) & 0xFF,
+ (NetOurIP >> 16) & 0xFF,
+ (NetOurIP >> 24) & 0xFF );
strcpy (nfs_path, default_filename);
printf ("*** Warning: no boot file name; using '%s'\n",
printf ("Using %s device\n", eth_get_name());
#endif
- puts ("File transfer via NFS from server "); print_IPaddr (NfsServerIP);
- puts ("; our IP address is "); print_IPaddr (NetOurIP);
+ printf("File transfer via NFS from server %pI4"
+ "; our IP address is %pI4", &NfsServerIP, &NetOurIP);
/* Check if we need to send across this subnet */
if (NetOurGatewayIP && NetOurSubnetMask) {
IPaddr_t OurNet = NetOurIP & NetOurSubnetMask;
IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask;
- if (OurNet != ServerNet) {
- puts ("; sending through gateway ");
- print_IPaddr (NetOurGatewayIP) ;
- }
+ if (OurNet != ServerNet)
+ printf("; sending through gateway %pI4", &NetOurGatewayIP);
}
- putc ('\n');
-
- printf ("Filename '%s/%s'.", nfs_path, nfs_filename);
+ printf ("\nFilename '%s/%s'.", nfs_path, nfs_filename);
if (NetBootFileSize) {
printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9);
print_size (NetBootFileSize<<9, "");
}
- putc ('\n');
+ printf ("\nLoad address: 0x%lx\n"
+ "Loading: *\b", load_addr);
- printf ("Load address: 0x%lx\n", load_addr);
-
- printf ("Loading: *\b");
-
- NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout);
+ NetSetTimeout (NFS_TIMEOUT, NfsTimeout);
NetSetHandler (NfsHandler);
- rpc_init ();
NfsTimeoutCount = 0;
NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
NfsSend ();
}
-#endif /* CONFIG_COMMANDS & CFG_CMD_NFS */
+#endif