Index: trunk/bootcode/regular/driveio.asm
===================================================================
--- trunk/bootcode/regular/driveio.asm	(revision 146)
+++ trunk/bootcode/regular/driveio.asm	(revision 147)
@@ -419,10 +419,90 @@
 
 
-; Keeps DS:SI for caller, sets carry if valid LVM sector encountered
-DriveIO_LoadLVMSector   Proc Near  Uses ax bx cx dx
-
-IFDEF   AUX_DEBUG
-        IF 0
+;##############################################################################
+;# The location of LVM sectors depends on the OS/2 geometry used when the disk
+;# was prepared. This geometry is present in the Master LVM sector, which has
+;# already been located if it exists. All partitions, whether primary or
+;# logical, have an entry in a partition table. For primary partitions this
+;# table is located in the MBR, while for logical partitions this table is
+;# located in the EBR for that logical partition. An LVM record is located
+;# LVM_SPT-1 sectors above an MBR or EBR. The Master LVM record contains the
+;# information for all primary partitions. For logical partitions, the LVM
+;# sector only has one entry, because EBRs are chained. The global LVM info,
+;# like disk-name, sectors per track, etc. is replicated between the Master
+;# LVM sector and LVM sectors corresponding to logical partitions. This info
+;# is kept in sync by the OS/2 LVM Engine.
+;##############################################################################
+;# ACTION   : Attempts to load the corresponding LVM sector for a partition
+;# ----------------------------------------------------------------------------
+;# EFFECTS  : Modifies DAP structure and fills or clears sector buffer
+;# ----------------------------------------------------------------------------
+;# IN       : None   - Location info is in [CurPartition_Location]
+;# ----------------------------------------------------------------------------
+;# OUT      : CF=1   - failure, no valid LVM sector was loaded
+;#          : SI     - Points to the sector buffer ([LVMSector])
+;##############################################################################
+DriveIO_LoadLVMSector   Proc Near  Uses ax bx cx dx di
+
+IFDEF   AUX_DEBUG
+        IF 1
         DBG_TEXT_OUT_AUX    'DriveIO_LoadLVMSector:'
+        PUSHRF
+            call    DEBUG_DumpRegisters
+            ;~ call    AuxIO_DumpSector
+            ;~ call    AuxIO_DumpParagraph
+            ;~ call    AuxIO_TeletypeNL
+        POPRF
+        ENDIF
+ENDIF
+
+        ; Clear the sector buffer
+        mov     si, offset [LVMSector]
+        call    ClearSectorBuffer
+
+        ; Quit with CY if LVM is ignored in SETUP
+        test    byte ptr [CFG_IgnoreLVM], 1     ; ZF=0 means ignore LVM
+        jnz     DIOLLVMS_NoLVMSector            ; Quit if so
+
+        ; Calculate the entry in the DISKINFO array for this disk
+        call    DriveIO_CalcDiskInfoPointer
+
+        ; If the LVM_SPT is ZERO, no LVM info is present and we quit with CY
+        mov     di, [bx+LocDISKINFO_LVM_Secs]   ; Get LVM_SPT
+        test    di, di                          ; See if it is 0
+        jz      DIOLLVMS_NoLVMSector            ; Quit if so
+
+        ; Load the location of the current partition being acted upon.
+        ; Note that this is not the actual LBA of the partition, but the
+        ; sector that has the partition table that contains the entry
+        ; for the partition. In other words, for primary partitions the LBA
+        ; address points to the MBR while for extended partitions it points
+        ; to an EBR. In both cases the LVM sector is located LVM_SPT-1 above.
+        ; Also note that the BIOS CHS values (DH and CX) below are not used,
+        ; because we explicitly use LBA sector loading.
+        mov     ax, wptr cs:[CurPartition_Location+0]   ; LBA lo of MBR/EBR
+        mov     bx, wptr cs:[CurPartition_Location+2]   ; LBA hi of MBR/EBR
+        mov     dx, wptr cs:[CurPartition_Location+4]   ; BIOS disk num & head
+        mov     cx, wptr cs:[CurPartition_Location+6]   ; BIOS cyl & sec
+
+        ; Adjust the location to point to the LVM sector
+        add     ax, di      ; Add the LVM sectors-per-track
+        adc     bx, 0       ; Propagate LBA lo overflow to LBA hi
+        sub     ax, 1       ; LVM sector is located one sector below
+        sbb     bx, 0       ; Propagate borrow to LBA hi
+
+        ; Load the LVM sector into [LVMSector]
+        mov     si, offset [LVMSector]          ; Points to sector buffer
+        mov     di, ds                          ; Segment of that buffer
+        call    DriveIO_ReadSectorLBA           ; Read the LVM sector
+        jc      DIOLLVMS_NoLVMSector            ; Quit on error
+
+        ; Check the validity of the LVM sector, quit with CY if invalid
+        call    LVM_ValidateSector              ; Check signature and CRC
+        jnc     DIOLLVMS_NoLVMSector            ; Quit if not valid
+
+
+IFDEF   AUX_DEBUG
+        IF 1
+        DBG_TEXT_OUT_AUX    'CurPartition'
         PUSHRF
             call    DEBUG_DumpRegisters
@@ -434,46 +514,20 @@
 ENDIF
 
-        test    byte ptr [CFG_IgnoreLVM], 1            ; We are supposed to ignore LVM, so
-        jnz     DIOLLVMS_NoLVMSector          ;  don't load but declare as bad!
-        mov     ax, wptr cs:[CurPartition_Location+0]
-        mov     bx, wptr cs:[CurPartition_Location+2]
-        mov     dx, wptr cs:[CurPartition_Location+4]
-        mov     cx, wptr cs:[CurPartition_Location+6] ; Gets cur. partition location
-
-        call    DriveIO_LVMAdjustToInfoSector
-
+        ; We're done, indicate success and return
+        clc
+        jmp     DIOLLVMS_Done
+
+    DIOLLVMS_NoLVMSector:
+
+        ; Clear the sector buffer
         mov     si, offset [LVMSector]
-        call    DriveIO_LoadSector
-
-IFDEF   AUX_DEBUG
-        IF 0
-        DBG_TEXT_OUT_AUX    'lvm record ex'
-        PUSHRF
-            ;~ call    AuxIO_TeletypeHexWord
-            ;~ call    AuxIO_TeletypeNL
-            call    DEBUG_DumpRegisters
-            ;~ call    AuxIO_DumpSector
-            mov     cx, 7
-        @@:
-            call    AuxIO_DumpParagraph
-            call    AuxIO_TeletypeNL
-            add     si, 16
-            loop @B
-        POPRF
-        ENDIF
-ENDIF
-
-
-        call    LVM_CheckSectorSignature
-        jnc     DIOLLVMS_NoLVMSector
-        call    LVM_CheckSectorCRC
-        jnc     DIOLLVMS_NoLVMSector
-        ret
-
-        ; This here is called, if an invalid (or no) LVM information sector is found
-        ;  It will truncate the first byte of the sector, so all other routines
-        ;  will notice it easily by just comparing the first byte.
-    DIOLLVMS_NoLVMSector:
+        call    ClearSectorBuffer
         mov     bptr [si+LocLVM_SignatureStart], 0
+
+        ; Indicate no valid LVM sector was loaded
+        stc
+
+    DIOLLVMS_Done:
+
         ret
 DriveIO_LoadLVMSector   EndP
