Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/block.c | 16 +++++++++------- src/block.h | 2 +- src/disk.c | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/block.c b/src/block.c index a1054ac..cd732c1 100644 --- a/src/block.c +++ b/src/block.c @@ -288,10 +288,12 @@ map_floppy_drive(struct drive_s *drive) ****************************************************************/
static int -fill_generic_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf +fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf , u32 dpte_so, char *iface_type , int bdf, u8 channel, u16 iobase, u64 device_path) { + u16 seg = edd.seg; + struct int13dpt_s *param_far = (void*)(edd.offset+0); u16 size = GET_FARVAR(seg, param_far->size); u16 t13 = size == 74;
@@ -394,7 +396,7 @@ fill_generic_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf struct dpte_s DefaultDPTE VARLOW;
static int -fill_ata_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf) +fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf) { if (!CONFIG_ATA) return DISK_RET_EPARAM; @@ -446,24 +448,24 @@ fill_ata_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf) SET_LOW(DefaultDPTE.checksum, -sum);
return fill_generic_edd( - seg, param_far, drive_gf, SEGOFF(SEG_LOW, (u32)&DefaultDPTE).segoff + edd, drive_gf, SEGOFF(SEG_LOW, (u32)&DefaultDPTE).segoff , "ATA ", bdf, channel, iobase1, slave); }
int noinline -fill_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf) +fill_edd(struct segoff_s edd, struct drive_s *drive_gf) { switch (GET_GLOBALFLAT(drive_gf->type)) { case DTYPE_ATA: case DTYPE_ATA_ATAPI: - return fill_ata_edd(seg, param_far, drive_gf); + return fill_ata_edd(edd, drive_gf); case DTYPE_VIRTIO_BLK: case DTYPE_VIRTIO_SCSI: return fill_generic_edd( - seg, param_far, drive_gf, 0xffffffff + edd, drive_gf, 0xffffffff , "SCSI ", GET_GLOBALFLAT(drive_gf->cntl_id), 0, 0, 0); default: - return fill_generic_edd(seg, param_far, drive_gf, 0, NULL, 0, 0, 0, 0); + return fill_generic_edd(edd, drive_gf, 0, NULL, 0, 0, 0, 0); } }
diff --git a/src/block.h b/src/block.h index 702f357..2ff359f 100644 --- a/src/block.h +++ b/src/block.h @@ -110,7 +110,7 @@ void map_floppy_drive(struct drive_s *drive); void map_hd_drive(struct drive_s *drive); void map_cd_drive(struct drive_s *drive); struct int13dpt_s; -int fill_edd(u16 seg, struct int13dpt_s *param_far, struct drive_s *drive_gf); +int fill_edd(struct segoff_s edd, struct drive_s *drive_gf); int default_process_op(struct disk_op_s *op); int process_op(struct disk_op_s *op); int send_disk_op(struct disk_op_s *op); diff --git a/src/disk.c b/src/disk.c index 91d939a..3854d00 100644 --- a/src/disk.c +++ b/src/disk.c @@ -522,7 +522,7 @@ disk_1347(struct bregs *regs, struct drive_s *drive_gf) static void disk_1348(struct bregs *regs, struct drive_s *drive_gf) { - int ret = fill_edd(regs->ds, (void*)(regs->si+0), drive_gf); + int ret = fill_edd(SEGOFF(regs->ds, regs->si), drive_gf); disk_ret(regs, ret); }
Have callers of fill_generic_edd() calculate the edd iface_path field. Have callers determine if the bus type is PCI vs ISA.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/block.c | 77 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 32 deletions(-)
diff --git a/src/block.c b/src/block.c index cd732c1..97e05fa 100644 --- a/src/block.c +++ b/src/block.c @@ -287,10 +287,18 @@ map_floppy_drive(struct drive_s *drive) * Extended Disk Drive (EDD) get drive parameters ****************************************************************/
+// flags for bus_iface field in fill_generic_edd() +#define EDD_ISA 0x01 +#define EDD_PCI 0x02 +#define EDD_BUS_MASK 0x0f +#define EDD_ATA 0x10 +#define EDD_SCSI 0x20 +#define EDD_IFACE_MASK 0xf0 + +// Fill in EDD info static int fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf - , u32 dpte_so, char *iface_type - , int bdf, u8 channel, u16 iobase, u64 device_path) + , u32 dpte_so, u8 bus_iface, u32 iface_path, u32 device_path) { u16 seg = edd.seg; struct int13dpt_s *param_far = (void*)(edd.offset+0); @@ -342,7 +350,7 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf SET_FARVAR(seg, param_far->size, 30); SET_FARVAR(seg, param_far->dpte.segoff, dpte_so);
- if (size < 66 || !iface_type) + if (size < 66 || !bus_iface) return DISK_RET_SUCCESS;
// EDD 3.x @@ -351,32 +359,22 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf SET_FARVAR(seg, param_far->reserved1, 0); SET_FARVAR(seg, param_far->reserved2, 0);
- int i; - for (i=0; i<sizeof(param_far->iface_type); i++) - SET_FARVAR(seg, param_far->iface_type[i], GET_GLOBAL(iface_type[i])); - - if (bdf != -1) { - SET_FARVAR(seg, param_far->host_bus[0], 'P'); - SET_FARVAR(seg, param_far->host_bus[1], 'C'); - SET_FARVAR(seg, param_far->host_bus[2], 'I'); - SET_FARVAR(seg, param_far->host_bus[3], ' '); - - u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) - | (pci_bdf_to_fn(bdf) << 16)); - if (t13) - path |= channel << 24; - - SET_FARVAR(seg, param_far->iface_path, path); - } else { - // ISA - SET_FARVAR(seg, param_far->host_bus[0], 'I'); - SET_FARVAR(seg, param_far->host_bus[1], 'S'); - SET_FARVAR(seg, param_far->host_bus[2], 'A'); - SET_FARVAR(seg, param_far->host_bus[3], ' '); - - SET_FARVAR(seg, param_far->iface_path, iobase); + const char *host_bus = "ISA "; + if ((bus_iface & EDD_BUS_MASK) == EDD_PCI) { + host_bus = "PCI "; + if (!t13) + // Phoenix v3 spec (pre t13) did not define the PCI channel field + iface_path &= 0x00ffffff; } - + memcpy_far(seg, param_far->host_bus, SEG_BIOS, host_bus + , sizeof(param_far->host_bus)); + SET_FARVAR(seg, param_far->iface_path, iface_path); + + const char *iface_type = "ATA "; + if ((bus_iface & EDD_IFACE_MASK) == EDD_SCSI) + iface_type = "SCSI "; + memcpy_far(seg, param_far->iface_type, SEG_BIOS, iface_type + , sizeof(param_far->iface_type)); if (t13) { SET_FARVAR(seg, param_far->t13.device_path[0], device_path); SET_FARVAR(seg, param_far->t13.device_path[1], 0); @@ -393,8 +391,17 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf return DISK_RET_SUCCESS; }
+// Build an EDD "iface_path" field for a PCI device +static u32 +edd_pci_path(u16 bdf, u8 channel) +{ + return (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8) + | (pci_bdf_to_fn(bdf) << 16) | ((u32)channel << 24)); +} + struct dpte_s DefaultDPTE VARLOW;
+// EDD info for ATA and ATAPI drives static int fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf) { @@ -447,11 +454,17 @@ fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf) u8 sum = checksum_far(SEG_LOW, &DefaultDPTE, 15); SET_LOW(DefaultDPTE.checksum, -sum);
+ u32 bustype = EDD_ISA, ifpath = iobase1; + if (bdf >= 0) { + bustype = EDD_PCI; + ifpath = edd_pci_path(bdf, channel); + } return fill_generic_edd( edd, drive_gf, SEGOFF(SEG_LOW, (u32)&DefaultDPTE).segoff - , "ATA ", bdf, channel, iobase1, slave); + , bustype | EDD_ATA, ifpath, slave); }
+// Fill Extended Disk Drive (EDD) "Get drive parameters" info for a drive int noinline fill_edd(struct segoff_s edd, struct drive_s *drive_gf) { @@ -462,10 +475,10 @@ fill_edd(struct segoff_s edd, struct drive_s *drive_gf) case DTYPE_VIRTIO_BLK: case DTYPE_VIRTIO_SCSI: return fill_generic_edd( - edd, drive_gf, 0xffffffff - , "SCSI ", GET_GLOBALFLAT(drive_gf->cntl_id), 0, 0, 0); + edd, drive_gf, 0xffffffff, EDD_PCI | EDD_SCSI + , edd_pci_path(GET_GLOBALFLAT(drive_gf->cntl_id), 0), 0); default: - return fill_generic_edd(edd, drive_gf, 0, NULL, 0, 0, 0, 0); + return fill_generic_edd(edd, drive_gf, 0, 0, 0, 0); } }
On Thu, Aug 13, 2015 at 11:49:09AM -0400, Kevin O'Connor wrote:
Signed-off-by: Kevin O'Connor kevin@koconnor.net
FYI, I committed this series.
-Kevin