Index: trunk/src/VBox/Devices/PC/BIOS/ata.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/ata.c	(revision 104193)
+++ trunk/src/VBox/Devices/PC/BIOS/ata.c	(revision 104194)
@@ -131,13 +131,67 @@
 
 // ---------------------------------------------------------------------------
+// ATA/ATAPI driver : initialize device parameters (CHS geometry)
+// ---------------------------------------------------------------------------
+uint16_t ata_set_params(bio_dsk_t __far *bios_dsk, uint8_t device)
+{
+    uint16_t        iobase1, iobase2;
+    uint8_t         lheads, lsectors;
+    uint8_t         pheads, psectors;
+    uint8_t         status;
+
+    psectors = bios_dsk->devices[device].pchs.spt;
+    pheads   = bios_dsk->devices[device].pchs.heads - 1;
+
+    lsectors = bios_dsk->devices[device].lchs.spt;
+    lheads   = bios_dsk->devices[device].lchs.heads - 1;
+
+    if ((psectors == lsectors) && (pheads == lheads)) {
+        // If LCHS == PCHS, we can save ourselves the bother
+        // because INITIALIZE DEVICE PARAMETERS won't change anything.
+        return 0;
+    }
+
+    iobase1 = bios_dsk->channels[device / 2].iobase1;
+    iobase2 = bios_dsk->channels[device / 2].iobase2;
+
+    status = inb(iobase1 + ATA_CB_STAT);
+    if (status & ATA_CB_STAT_BSY)
+    {
+        BX_DEBUG_ATA("%s: disk busy\n", __func__);
+        return 1;
+    }
+
+    outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
+    outb(iobase1 + ATA_CB_FR, 0x00);
+    outb(iobase1 + ATA_CB_SC, lsectors);
+    outb(iobase1 + ATA_CB_DH, ((device & 1) ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | lheads );
+    outb(iobase1 + ATA_CB_CMD, ATA_CMD_INITIALIZE_DEVICE_PARAMETERS);
+
+    int_enable(); // enable higher priority interrupts
+
+    while (1) {
+        status = inb(iobase1 + ATA_CB_STAT);
+        if ( !(status & ATA_CB_STAT_BSY) )
+            break;
+    }
+
+    // Enable interrupts
+    outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
+    return 0;
+}
+
+
+// ---------------------------------------------------------------------------
 // ATA/ATAPI driver : software reset
 // ---------------------------------------------------------------------------
 // ATA-3
 // 8.2.1 Software reset - Device 0
+// NB: If two hard disks are installed on a single channel, *both* are reset
+//     by setting the SRST bit.
 
 void   ata_reset(uint16_t device)
 {
     uint16_t        iobase1, iobase2;
-    uint8_t         channel, slave, sn, sc;
+    uint8_t         channel, sn, sc;
     uint16_t        max;
     uint16_t        pdelay;
@@ -146,5 +200,5 @@
     bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
     channel = device / 2;
-    slave = device % 2;
+    device  = channel * 2;
 
     iobase1 = bios_dsk->channels[channel].iobase1;
@@ -179,18 +233,21 @@
     }
 
-    if (bios_dsk->devices[device].type != DSK_TYPE_NONE) {
-        // 8.2.1 (g) -- check for sc==sn==0x01
-        // select device
-        outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0);
-        sc = inb(iobase1+ATA_CB_SC);
-        sn = inb(iobase1+ATA_CB_SN);
-
-        if ( (sc==0x01) && (sn==0x01) ) {
-            // 8.2.1 (i) -- wait for DRDY
-            max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */
-            while(--max>0) {
-                uint8_t status = inb(iobase1+ATA_CB_STAT);
-                if ((status & ATA_CB_STAT_RDY) != 0)
-                    break;
+    for ( ; (device & ~1) == (channel * 2); ++device) {
+        if (bios_dsk->devices[device].type == DSK_TYPE_ATA) {
+            // 8.2.1 (g) -- check for sc==sn==0x01
+            // select device
+            outb(iobase1+ATA_CB_DH, (device & 1) ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
+            sc = inb(iobase1+ATA_CB_SC);
+            sn = inb(iobase1+ATA_CB_SN);
+
+            if ( (sc==0x01) && (sn==0x01) ) {
+                // 8.2.1 (i) -- wait for DRDY
+                max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */
+                while(--max>0) {
+                    uint8_t status = inb(iobase1+ATA_CB_STAT);
+                    if ((status & ATA_CB_STAT_RDY) != 0)
+                        break;
+                }
+                ata_set_params(bios_dsk, device);
             }
         }
@@ -673,4 +730,7 @@
                 }
             }
+
+            // Set the right CHS geometry if needed
+            ata_set_params(bios_dsk, device);
 
             // fill hdidmap
Index: trunk/src/VBox/Devices/PC/BIOS/disk.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/disk.c	(revision 104193)
+++ trunk/src/VBox/Devices/PC/BIOS/disk.c	(revision 104194)
@@ -314,9 +314,7 @@
 
     case 0x00: /* disk controller reset */
-#ifdef VBOX_WITH_SCSI
-        /* SCSI controller does not need a reset. */
-        if (!VBOX_IS_SCSI_DEVICE(device))
-#endif
-        ata_reset (device);
+        /* For ATA drives only. NB: This resets both drives on a channel. */
+        if (VBOX_IS_ATA_DEVICE(device))
+            ata_reset(device);
         goto int13_success;
         break;
Index: trunk/src/VBox/Devices/PC/BIOS/ebda.h
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/ebda.h	(revision 104193)
+++ trunk/src/VBox/Devices/PC/BIOS/ebda.h	(revision 104194)
@@ -77,4 +77,6 @@
 #define BX_USE_ATADRV           1
 #define BX_ELTORITO_BOOT        1
+
+#define VBOX_IS_ATA_DEVICE(device_id) (device_id < BX_MAX_ATA_DEVICES)
 
 #ifdef VBOX_WITH_SCSI
Index: trunk/src/VBox/Devices/PC/BIOS/notes.txt
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/notes.txt	(revision 104193)
+++ trunk/src/VBox/Devices/PC/BIOS/notes.txt	(revision 104194)
@@ -76,4 +76,12 @@
   at least in protected mode, assumes that those vectors must point into
   the F000h segment.
+
+- NetWare 2.0a INSTALL and VREPAIR utilities run in real mode but have their
+  own ATA disk driver. Like NetWare itself, the utilities obtain drive
+  geometry from the FDPT, but unlike NetWare, they assume that the drive
+  already had the correct geometry set during POST and that INT 13h/00h
+  will keep it in place by executing INITIALIZE DRIVE PARAMETERS.
+  NB: The BIOS itself always uses LBA and thus does not depend on the
+  drive's current CHS geometry at all.
 
 - Windows NT (including XP) uses INT 13h/08h to obtain the DPT for each floppy
