Signed-off-by: Doug Maxey <dwm@austin.ibm.com>
Cc: Ben Herrenschmidt <benh@kernel.crashing.org>
static int opened = 0; /* We can't open twice ! */
static unsigned int bs; /* Blocksize */
static unsigned long long doff; /* Byte offset where partition starts */
static int opened = 0; /* We can't open twice ! */
static unsigned int bs; /* Blocksize */
static unsigned long long doff; /* Byte offset where partition starts */
+static unsigned long long dend; /* Byte offset where partition ends */
static ino_t root,cwd;
static ext2_filsys fs = 0;
static struct boot_file_t* cur_file;
static ino_t root,cwd;
static ext2_filsys fs = 0;
static struct boot_file_t* cur_file;
* compatible with older versions of OF
*/
bs = 1024;
* compatible with older versions of OF
*/
bs = 1024;
+
+ /*
+ * On the other hand, we do care about the actual size of the
+ * partition, reads or seeks past the end may cause undefined
+ * behavior on some devices. A netapp that tries to seek and
+ * read past the end of the lun takes ~30 secs to recover per
+ * attempt.
+ */
+ doff = dend = 0;
+ if (part) {
doff = (unsigned long long)(part->part_start) * part->blocksize;
doff = (unsigned long long)(part->part_start) * part->blocksize;
+ dend = doff + (unsigned long long)part->part_size * part->blocksize;
+ }
- DEBUG_F("partition offset: %Lu\n", doff);
+ DEBUG_F("partition offset: %Lx, end: %Lx\n", doff, dend);
/* Open the OF device for the entire disk */
strncpy(buffer, dev_name, 1020);
/* Open the OF device for the entire disk */
strncpy(buffer, dev_name, 1020);
static errcode_t linux_set_blksize (io_channel channel, int blksize)
{
static errcode_t linux_set_blksize (io_channel channel, int blksize)
{
+ DEBUG_F("bs set to 0x%x\n", blksize);
channel->block_size = bs = blksize;
if (block_buffer) {
free(block_buffer);
channel->block_size = bs = blksize;
if (block_buffer) {
free(block_buffer);
tempb = (((unsigned long long) block) *
((unsigned long long)bs)) + (unsigned long long)doff;
tempb = (((unsigned long long) block) *
((unsigned long long)bs)) + (unsigned long long)doff;
+ /*
+ * Only test tempb exceeding dend if dend is set to allow things
+ * like boot: hd:0,\xxxx
+ */
+ if (dend && tempb > dend) {
+ DEBUG_F("\nSeek error on block %lx, tempb=%Lx\n", block, tempb >> 9);
+ return EXT2_ET_LLSEEK_FAILED;
+ }
+
size = (count < 0) ? -count : count * bs;
prom_lseek(cur_file->of_device, tempb);
if (prom_read(cur_file->of_device, data, size) != size) {
size = (count < 0) ? -count : count * bs;
prom_lseek(cur_file->of_device, tempb);
if (prom_read(cur_file->of_device, data, size) != size) {
#include "linux/iso_fs.h"
#include "debug.h"
#include "errors.h"
#include "linux/iso_fs.h"
#include "debug.h"
#include "errors.h"
/* We currently don't check the partition type, some users
* are putting crap there and still expect it to work...
/* We currently don't check the partition type, some users
* are putting crap there and still expect it to work...
-/* Local functions */
-static unsigned long swab32(unsigned long value);
-
#define MAX_BLOCK_SIZE 2048
static unsigned char block_buffer[MAX_BLOCK_SIZE];
#define MAX_BLOCK_SIZE 2048
static unsigned char block_buffer[MAX_BLOCK_SIZE];
partition,
"Linux", /* type */
'\0', /* name */
partition,
"Linux", /* type */
'\0', /* name */
- swab32(*(unsigned int *)(part->start4)),
- swab32(*(unsigned int *)(part->size4)),
+ le32_to_cpu(*(unsigned int *)part->start4),
+ le32_to_cpu(*(unsigned int *)part->size4),
512 /*blksize*/,
part->sys_ind /* partition type */ );
}
512 /*blksize*/,
part->sys_ind /* partition type */ );
}
-unsigned long
-swab32(unsigned long value)
-{
- __u32 result;
-
- __asm__("rlwimi %0,%1,24,16,23\n\t"
- "rlwimi %0,%1,8,8,15\n\t"
- "rlwimi %0,%1,24,0,7"
- : "=r" (result)
- : "r" (value), "0" (value >> 24));
- return result;
-}