char *grub_devpath;
int is_boot;
int is_removable;
+ int block_size_fails;
/* Pointer to shortest available name on nodes representing canonical names,
otherwise NULL. */
const char *shortest;
struct ofdisk_hash_ent *next;
};
+static grub_err_t
+grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
+ struct ofdisk_hash_ent *op);
+
#define OFDISK_HASH_SZ 8
static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
/* XXX: This should be large enough for any possible case. */
char prop[64];
grub_ssize_t actual;
+ grub_uint32_t block_size = 0;
+ grub_err_t err;
if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
}
- grub_uint32_t block_size = 0;
- if (grub_ofdisk_get_block_size (devpath, &block_size) == 0)
- {
- for (disk->log_sector_size = 0;
- (1U << disk->log_sector_size) < block_size;
- disk->log_sector_size++);
- }
-
/* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */
return grub_errno;
disk->id = (unsigned long) op;
disk->data = op->open_path;
+
+ err = grub_ofdisk_get_block_size (devpath, &block_size, op);
+ if (err)
+ return err;
+ if (block_size != 0)
+ {
+ for (disk->log_sector_size = 0;
+ (1U << disk->log_sector_size) < block_size;
+ disk->log_sector_size++);
+ }
+ else
+ disk->log_sector_size = 9;
}
return 0;
grub_disk_dev_register (&grub_ofdisk_dev);
}
-grub_err_t
-grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size)
+static grub_err_t
+grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
+ struct ofdisk_hash_ent *op)
{
struct size_args_ieee1275
{
if (! last_ihandle)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+ *block_size = 0;
+
+ if (op->block_size_fails >= 2)
+ return GRUB_ERR_NONE;
+
INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2);
args_ieee1275.method = (grub_ieee1275_cell_t) "block-size";
args_ieee1275.ihandle = last_ihandle;
args_ieee1275.result = 1;
- *block_size = GRUB_DISK_SECTOR_SIZE;
-
- if ((IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1) || (args_ieee1275.result))
- grub_dprintf ("disk", "can't get block size\n");
- else
- if (args_ieee1275.size1
- && !(args_ieee1275.size1 & (args_ieee1275.size1 - 1))
- && args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384)
+ if (IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1)
+ {
+ grub_dprintf ("disk", "can't get block size: failed call-method\n");
+ op->block_size_fails++;
+ }
+ else if (args_ieee1275.result)
+ {
+ grub_dprintf ("disk", "can't get block size: %lld\n",
+ (long long) args_ieee1275.result);
+ op->block_size_fails++;
+ }
+ else if (args_ieee1275.size1
+ && !(args_ieee1275.size1 & (args_ieee1275.size1 - 1))
+ && args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384)
+ {
+ op->block_size_fails = 0;
*block_size = args_ieee1275.size1;
+ }
return 0;
}