blob: fb2a6ffd35f9cbaa5b15ed2998a5e389ededf67c [file] [log] [blame]
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com
*/
#include "bootloader.h"
/* this is the stupidest "file system" imaginable -- it applies an */
/* offset to the seek pointers and optionally checks against a length */
struct offsets {
int fd;
__u64 start;
__u64 length;
} ofd [MAX_FD];
static int offset_read(int fd, char *buf, unsigned count, __u64 devaddr)
{
struct offsets *o = &ofd[fd];
if (Debug) printf("offset_read(%d, 0x%p, %d, %lld)\r\n",
fd, buf, count, devaddr);
/* abort early if we reach firmware limit */
if (disk_2gb_limit && ((devaddr + count) >> 31)) {
printf("offset_read(%lld): block not reachable via firmware call\r\n",
devaddr + count);
return -1;
}
/* truncate 'count' according to max device/file size */
if (o->length > 0 && devaddr < o->length && devaddr + count > o->length)
count = o->length - devaddr;
else if (o->length > 0 && devaddr + count > o->length)
{
printf("offset_read(%d, 0x%p, %d, %lld) can't seek past %lld\r\n",
fd, buf, count, devaddr, o->length);
return -1;
}
return seekread(o->fd, buf, count, devaddr + o->start);
}
static void offset_describe(int fd, int *bufalign,
int *blocksize)
{
describe(ofd[fd].fd, bufalign, blocksize);
}
/* returns true if OK */
int offset_open(int otherfd, __u64 offset, __u64 length)
{
int fd = fileio_open(offset_describe, offset_read);
if (fd >= 0)
{
struct offsets *o = &ofd[fd];
o->fd = otherfd;
o->start = offset;
o->length = length;
}
if (Debug) printf("offset_open(%d, %lld, %lld) = %d\n",
otherfd, offset, length, fd);
return fd;
}