Add support for downloading file from the given offset (in bytes) and limit the size up to given
bytes.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-Id: I9f442d375d6b37986cb7c10f93c11d265886cceb
ulong addr;
net_boot_file_name_explicit = false;
+ net_boot_file_offset = 0;
+ net_boot_file_size_limit = 0;
/* pre-set load_addr */
s = env_get("loadaddr");
return rcode;
}
+int netboot_nfs(unsigned long addr, const char *filename,
+ unsigned long offset, unsigned long limit)
+{
+ int rcode = 0;
+ int size;
+
+ load_addr = addr;
+ net_boot_file_name_explicit = true;
+ net_boot_file_offset = offset;
+ net_boot_file_size_limit = limit;
+
+ copy_filename(net_boot_file_name, filename,
+ sizeof(net_boot_file_name));
+
+ bootstage_mark(BOOTSTAGE_ID_NET_START);
+
+ size = net_loop(NFS);
+ if (size < 0) {
+ bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
+ return CMD_RET_FAILURE;
+ }
+ bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
+
+ /* done if no file was loaded (no errors though) */
+ if (size == 0) {
+ bootstage_error(BOOTSTAGE_ID_NET_LOADED);
+ return CMD_RET_SUCCESS;
+ }
+
+ bootstage_mark(BOOTSTAGE_ID_NET_LOADED);
+
+ if (rcode == CMD_RET_SUCCESS)
+ bootstage_mark(BOOTSTAGE_ID_NET_DONE);
+ else
+ bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
+ return rcode;
+}
+
+
#if defined(CONFIG_CMD_PING)
static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
extern bool net_boot_file_name_explicit;
/* The actual transferred size of the bootfile (in bytes) */
extern u32 net_boot_file_size;
+
+/* Offset/size for partial downloads for nfsdown tool */
+extern u32 net_boot_file_size_limit;
+extern u32 net_boot_file_offset;
+extern int netboot_nfs(unsigned long addr, const char *filename,
+ unsigned long offset, unsigned long size);
+
/* Boot file size in blocks as reported by the DHCP server */
extern u32 net_boot_file_expected_size_in_blocks;
static int nfs_offset = -1;
static int nfs_len;
static ulong nfs_timeout = NFS_TIMEOUT;
+u32 net_boot_file_size_limit;
+u32 net_boot_file_offset;
static char dirfh[NFS_FHSIZE]; /* NFSv2 / NFSv3 file handle of directory */
static char filefh[NFS3_FHSIZE]; /* NFSv2 / NFSv3 file handle */
if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
return -9999;
- if (store_block(data_ptr, nfs_offset, rlen))
+ if (store_block(data_ptr, nfs_offset - net_boot_file_offset, rlen))
return -9999;
return rlen;
nfs_send();
} else {
nfs_state = STATE_READ_REQ;
- nfs_offset = 0;
+ nfs_offset = net_boot_file_offset;
nfs_len = NFS_READ_SIZE;
nfs_send();
}
net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
if (rlen > 0) {
nfs_offset += rlen;
+ if (nfs_offset - net_boot_file_offset ==
+ net_boot_file_size_limit) {
+ nfs_download_state = NETLOOP_SUCCESS;
+ nfs_state = STATE_UMOUNT_REQ;
+ }
nfs_send();
} else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) {
/* symbolic link */