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:
Vladimir 'phcoder' Serbinenko 2011-07-25 08:14:34 +02:00
parent 9222759765
commit 6795300e7f
3 changed files with 30 additions and 3 deletions

View file

@ -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> 2011-07-25 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-install.in: Don't use uhci outside of x86. * util/grub-install.in: Don't use uhci outside of x86.

View file

@ -57,6 +57,7 @@ grub_ata_dumpinfo (struct grub_ata *dev, char *info)
{ {
grub_dprintf ("ata", "Addressing: %d\n", dev->addr); grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size); 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 else
dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100])); 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. */ /* Read CHS information. */
dev->cylinders = info16[1]; dev->cylinders = info16[1];
dev->heads = info16[3]; 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); grub_ata_setaddress (ata, &parms, sector, batch, addressing);
parms.taskfile.cmd = (! rw ? cmd : cmd_write); parms.taskfile.cmd = (! rw ? cmd : cmd_write);
parms.buffer = buf; parms.buffer = buf;
parms.size = batch * GRUB_DISK_SECTOR_SIZE; parms.size = batch << ata->log_sector_size;
parms.write = rw; parms.write = rw;
if (ata->dma) if (ata->dma)
parms.dma = 1; 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); err = ata->dev->readwrite (ata, &parms, 0);
if (err) if (err)
return 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"); return grub_error (GRUB_ERR_READ_ERROR, "incomplete read");
buf += GRUB_DISK_SECTOR_SIZE * batch; buf += batch << ata->log_sector_size;
sector += batch; sector += batch;
nsectors += 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"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
disk->total_sectors = ata->size; disk->total_sectors = ata->size;
disk->log_sector_size = ata->log_sector_size;
disk->id = grub_make_scsi_id (id, bus, 0); disk->id = grub_make_scsi_id (id, bus, 0);

View file

@ -170,6 +170,7 @@ struct grub_ata
/* Sector count. */ /* Sector count. */
grub_uint64_t size; grub_uint64_t size;
grub_uint32_t log_sector_size;
/* CHS maximums. */ /* CHS maximums. */
grub_uint16_t cylinders; grub_uint16_t cylinders;