Support ATA disks with 4K sectors.
* include/grub/ata.h (grub_ata): New member log_sector_size. * grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. (grub_ata_identify): Read sector size. (grub_ata_readwrite): Use log_sector_size rather than hardcoded value.
This commit is contained in:
parent
9222759765
commit
6795300e7f
3 changed files with 30 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
|||
2011-07-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Support ATA disks with non-4K sectors.
|
||||
|
||||
* include/grub/ata.h (grub_ata): New member log_sector_size.
|
||||
* grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size.
|
||||
(grub_ata_identify): Read sector size.
|
||||
(grub_ata_readwrite): Use log_sector_size rather than hardcoded value.
|
||||
|
||||
2011-07-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/grub-install.in: Don't use uhci outside of x86.
|
||||
|
|
|
@ -57,6 +57,7 @@ grub_ata_dumpinfo (struct grub_ata *dev, char *info)
|
|||
{
|
||||
grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
|
||||
grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size);
|
||||
grub_dprintf ("ata", "Sector size: %u\n", 1U << dev->log_sector_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,6 +171,21 @@ grub_ata_identify (struct grub_ata *dev)
|
|||
else
|
||||
dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100]));
|
||||
|
||||
if (info16[106] & (1 << 12))
|
||||
{
|
||||
grub_uint32_t secsize;
|
||||
secsize = grub_le_to_cpu32 (*((grub_uint32_t *) &info16[117]));
|
||||
if (secsize & (secsize - 1) || !secsize
|
||||
|| secsize > 1048576)
|
||||
secsize = 256;
|
||||
for (dev->log_sector_size = 0;
|
||||
(1U << dev->log_sector_size) < secsize;
|
||||
dev->log_sector_size++);
|
||||
dev->log_sector_size++;
|
||||
}
|
||||
else
|
||||
dev->log_sector_size = 9;
|
||||
|
||||
/* Read CHS information. */
|
||||
dev->cylinders = info16[1];
|
||||
dev->heads = info16[3];
|
||||
|
@ -314,7 +330,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
grub_ata_setaddress (ata, &parms, sector, batch, addressing);
|
||||
parms.taskfile.cmd = (! rw ? cmd : cmd_write);
|
||||
parms.buffer = buf;
|
||||
parms.size = batch * GRUB_DISK_SECTOR_SIZE;
|
||||
parms.size = batch << ata->log_sector_size;
|
||||
parms.write = rw;
|
||||
if (ata->dma)
|
||||
parms.dma = 1;
|
||||
|
@ -322,9 +338,9 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
err = ata->dev->readwrite (ata, &parms, 0);
|
||||
if (err)
|
||||
return err;
|
||||
if (parms.size != batch * GRUB_DISK_SECTOR_SIZE)
|
||||
if (parms.size != batch << ata->log_sector_size)
|
||||
return grub_error (GRUB_ERR_READ_ERROR, "incomplete read");
|
||||
buf += GRUB_DISK_SECTOR_SIZE * batch;
|
||||
buf += batch << ata->log_sector_size;
|
||||
sector += batch;
|
||||
nsectors += batch;
|
||||
}
|
||||
|
@ -433,6 +449,7 @@ grub_ata_open (const char *name, grub_disk_t disk)
|
|||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
|
||||
|
||||
disk->total_sectors = ata->size;
|
||||
disk->log_sector_size = ata->log_sector_size;
|
||||
|
||||
disk->id = grub_make_scsi_id (id, bus, 0);
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ struct grub_ata
|
|||
|
||||
/* Sector count. */
|
||||
grub_uint64_t size;
|
||||
grub_uint32_t log_sector_size;
|
||||
|
||||
/* CHS maximums. */
|
||||
grub_uint16_t cylinders;
|
||||
|
|
Loading…
Reference in a new issue