Support Openfirmware disks with non-512B sectors.

* grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Get the block
	size of the disk.
	* (grub_ofdisk_get_block_size): New function.
	* (grub_ofdisk_prepare): Use the correct block size.
	* (grub_ofdisk_read): Likewise.
	* (grub_ofdisk_write): Likewise.
	* include/grub/ieee1275/ofdisk.h (grub_ofdisk_get_block_size):
	New proto.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-02-19 09:10:26 +01:00
parent cc0e476fe8
commit b5ea6ce03a
3 changed files with 70 additions and 5 deletions

View file

@ -1,3 +1,16 @@
2013-02-19 Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
Support Openfirmware disks with non-512B sectors.
* grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Get the block
size of the disk.
* (grub_ofdisk_get_block_size): New function.
* (grub_ofdisk_prepare): Use the correct block size.
* (grub_ofdisk_read): Likewise.
* (grub_ofdisk_write): Likewise.
* include/grub/ieee1275/ofdisk.h (grub_ofdisk_get_block_size):
New proto.
2013-02-06 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/commands/lsacpi.c: Fix types on 64-bit platform.

View file

@ -349,6 +349,14 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
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. */
@ -415,7 +423,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
last_devpath = disk->data;
}
pos = sector << GRUB_DISK_SECTOR_BITS;
pos = sector << disk->log_sector_size;
grub_ieee1275_seek (last_ihandle, pos, &status);
if (status < 0)
@ -434,9 +442,9 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
err = grub_ofdisk_prepare (disk, sector);
if (err)
return err;
grub_ieee1275_read (last_ihandle, buf, size << GRUB_DISK_SECTOR_BITS,
grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size,
&actual);
if (actual != (grub_ssize_t) (size << GRUB_DISK_SECTOR_BITS))
if (actual != (grub_ssize_t) (size << disk->log_sector_size))
return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx "
"from `%s'"),
(unsigned long long) sector,
@ -454,9 +462,9 @@ grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
err = grub_ofdisk_prepare (disk, sector);
if (err)
return err;
grub_ieee1275_write (last_ihandle, buf, size << GRUB_DISK_SECTOR_BITS,
grub_ieee1275_write (last_ihandle, buf, size << disk->log_sector_size,
&actual);
if (actual != (grub_ssize_t) (size << GRUB_DISK_SECTOR_BITS))
if (actual != (grub_ssize_t) (size << disk->log_sector_size))
return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx "
"to `%s'"),
(unsigned long long) sector,
@ -493,3 +501,44 @@ grub_ofdisk_fini (void)
grub_disk_dev_unregister (&grub_ofdisk_dev);
}
grub_err_t
grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size)
{
struct size_args_ieee1275
{
struct grub_ieee1275_common_hdr common;
grub_ieee1275_cell_t method;
grub_ieee1275_cell_t ihandle;
grub_ieee1275_cell_t result;
grub_ieee1275_cell_t size1;
grub_ieee1275_cell_t size2;
} args_ieee1275;
if (last_ihandle)
grub_ieee1275_close (last_ihandle);
last_ihandle = 0;
last_devpath = NULL;
grub_ieee1275_open (device, &last_ihandle);
if (! last_ihandle)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
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)
*block_size = args_ieee1275.size1;
return 0;
}

View file

@ -22,4 +22,7 @@
extern void grub_ofdisk_init (void);
extern void grub_ofdisk_fini (void);
extern grub_err_t grub_ofdisk_get_block_size (const char *device,
grub_uint32_t *block_size);
#endif /* ! GRUB_INIT_HEADER */