summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-12-23 11:29:35 +0200
committerKevin O'Connor <kevin@koconnor.net>2010-12-24 10:33:17 -0500
commitf77e1795bce49c4824084b92ffe0a09cf76de795 (patch)
treea326374547385af15e68ac949758034ee027eb05
parent67863beb71e67433b38a20ba408e490ae173f324 (diff)
Provide full EDD 3.0 info for virtio disk
Fill out entire EDD 3.0 structure for virtio disk. Currently only EDD 1.0 part is filled which is missing such important info as device path. Use SCSI device type since virtio is not defined by EDD spec and virtio disk pci device uses SCSI class. Signed-off-by: Gleb Natapov <gleb@redhat.com>
-rw-r--r--src/disk.c126
1 files changed, 73 insertions, 53 deletions
diff --git a/src/disk.c b/src/disk.c
index 242c742..56c369a 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -544,64 +544,78 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
}
SET_INT13DPT(regs, blksize, blksize);
- if (size < 30 || (type != DTYPE_ATA && type != DTYPE_ATAPI)) {
+ if (size < 30 ||
+ (type != DTYPE_ATA && type != DTYPE_ATAPI && type != DTYPE_VIRTIO)) {
disk_ret(regs, DISK_RET_SUCCESS);
return;
}
// EDD 2.x
- u16 ebda_seg = get_ebda_seg();
+ int bdf;
+ u16 iobase1;
+ u64 device_path;
SET_INT13DPT(regs, size, 30);
+ if (type == DTYPE_ATA || type == DTYPE_ATAPI) {
+ u16 ebda_seg = get_ebda_seg();
- SET_INT13DPT(regs, dpte_segment, ebda_seg);
- SET_INT13DPT(regs, dpte_offset
- , offsetof(struct extended_bios_data_area_s, dpte));
-
- // Fill in dpte
- struct atadrive_s *adrive_g = container_of(
- drive_g, struct atadrive_s, drive);
- struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
- u8 slave = GET_GLOBAL(adrive_g->slave);
- u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
- u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
- u8 irq = GET_GLOBALFLAT(chan_gf->irq);
-
- u16 options = 0;
- if (type == DTYPE_ATA) {
- u8 translation = GET_GLOBAL(drive_g->translation);
- if (translation != TRANSLATION_NONE) {
- options |= 1<<3; // CHS translation
- if (translation == TRANSLATION_LBA)
- options |= 1<<9;
- if (translation == TRANSLATION_RECHS)
- options |= 3<<9;
+ SET_INT13DPT(regs, dpte_segment, ebda_seg);
+ SET_INT13DPT(regs, dpte_offset
+ , offsetof(struct extended_bios_data_area_s, dpte));
+
+ // Fill in dpte
+ struct atadrive_s *adrive_g = container_of(
+ drive_g, struct atadrive_s, drive);
+ struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
+ u8 slave = GET_GLOBAL(adrive_g->slave);
+ u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
+ u8 irq = GET_GLOBALFLAT(chan_gf->irq);
+ iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
+ bdf = GET_GLOBALFLAT(chan_gf->pci_bdf);
+ device_path = slave;
+
+ u16 options = 0;
+ if (type == DTYPE_ATA) {
+ u8 translation = GET_GLOBAL(drive_g->translation);
+ if (translation != TRANSLATION_NONE) {
+ options |= 1<<3; // CHS translation
+ if (translation == TRANSLATION_LBA)
+ options |= 1<<9;
+ if (translation == TRANSLATION_RECHS)
+ options |= 3<<9;
+ }
+ } else {
+ // ATAPI
+ options |= 1<<5; // removable device
+ options |= 1<<6; // atapi device
}
+ options |= 1<<4; // lba translation
+ if (CONFIG_ATA_PIO32)
+ options |= 1<<7;
+
+ SET_EBDA2(ebda_seg, dpte.iobase1, iobase1);
+ SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC);
+ SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
+ | ATA_CB_DH_LBA));
+ SET_EBDA2(ebda_seg, dpte.unused, 0xcb);
+ SET_EBDA2(ebda_seg, dpte.irq, irq);
+ SET_EBDA2(ebda_seg, dpte.blkcount, 1);
+ SET_EBDA2(ebda_seg, dpte.dma, 0);
+ SET_EBDA2(ebda_seg, dpte.pio, 0);
+ SET_EBDA2(ebda_seg, dpte.options, options);
+ SET_EBDA2(ebda_seg, dpte.reserved, 0);
+ SET_EBDA2(ebda_seg, dpte.revision, 0x11);
+
+ u8 sum = checksum_far(
+ ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15);
+ SET_EBDA2(ebda_seg, dpte.checksum, -sum);
} else {
- // ATAPI
- options |= 1<<5; // removable device
- options |= 1<<6; // atapi device
+ SET_INT13DPT(regs, dpte_segment, 0);
+ SET_INT13DPT(regs, dpte_offset, 0);
+ bdf = GET_GLOBAL(drive_g->cntl_id);
+ device_path = 0;
+ iobase1 = 0;
}
- options |= 1<<4; // lba translation
- if (CONFIG_ATA_PIO32)
- options |= 1<<7;
-
- SET_EBDA2(ebda_seg, dpte.iobase1, iobase1);
- SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC);
- SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
- | ATA_CB_DH_LBA));
- SET_EBDA2(ebda_seg, dpte.unused, 0xcb);
- SET_EBDA2(ebda_seg, dpte.irq, irq);
- SET_EBDA2(ebda_seg, dpte.blkcount, 1);
- SET_EBDA2(ebda_seg, dpte.dma, 0);
- SET_EBDA2(ebda_seg, dpte.pio, 0);
- SET_EBDA2(ebda_seg, dpte.options, options);
- SET_EBDA2(ebda_seg, dpte.reserved, 0);
- SET_EBDA2(ebda_seg, dpte.revision, 0x11);
-
- u8 sum = checksum_far(
- ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15);
- SET_EBDA2(ebda_seg, dpte.checksum, -sum);
if (size < 66) {
disk_ret(regs, DISK_RET_SUCCESS);
@@ -614,7 +628,6 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
SET_INT13DPT(regs, reserved1, 0);
SET_INT13DPT(regs, reserved2, 0);
- int bdf = GET_GLOBALFLAT(chan_gf->pci_bdf);
if (bdf != -1) {
SET_INT13DPT(regs, host_bus[0], 'P');
SET_INT13DPT(regs, host_bus[1], 'C');
@@ -634,16 +647,23 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
SET_INT13DPT(regs, iface_path, iobase1);
}
- SET_INT13DPT(regs, iface_type[0], 'A');
- SET_INT13DPT(regs, iface_type[1], 'T');
- SET_INT13DPT(regs, iface_type[2], 'A');
- SET_INT13DPT(regs, iface_type[3], 0);
+ if (type != DTYPE_VIRTIO) {
+ SET_INT13DPT(regs, iface_type[0], 'A');
+ SET_INT13DPT(regs, iface_type[1], 'T');
+ SET_INT13DPT(regs, iface_type[2], 'A');
+ SET_INT13DPT(regs, iface_type[3], 0);
+ } else {
+ SET_INT13DPT(regs, iface_type[0], 'S');
+ SET_INT13DPT(regs, iface_type[1], 'C');
+ SET_INT13DPT(regs, iface_type[2], 'S');
+ SET_INT13DPT(regs, iface_type[3], 'I');
+ }
SET_INT13DPT(regs, iface_type[4], 0);
SET_INT13DPT(regs, iface_type[5], 0);
SET_INT13DPT(regs, iface_type[6], 0);
SET_INT13DPT(regs, iface_type[7], 0);
- SET_INT13DPT(regs, device_path, slave);
+ SET_INT13DPT(regs, device_path, device_path);
SET_INT13DPT(regs, checksum
, -checksum_far(regs->ds, (void*)(regs->si+30), 35));