Index: /trunk/src/VBox/Devices/PC/BIOS/ahci.c
===================================================================
--- /trunk/src/VBox/Devices/PC/BIOS/ahci.c	(revision 55205)
+++ /trunk/src/VBox/Devices/PC/BIOS/ahci.c	(revision 55206)
@@ -44,4 +44,28 @@
     uint32_t    len;
 } ahci_prdt;
+
+/**
+ * SATA D2H FIS (Device to Host Frame Information Structure).
+ */
+typedef struct {
+    uint8_t     fis_type;   /* 34h */
+    uint8_t     intr;       /* Bit 6 indicates interrupt status. */
+    uint8_t     status;     /* Status register. */
+    uint8_t     error;      /* Error register. */
+    uint8_t     sec_no;     /* Sector number register. */
+    uint8_t     cyl_lo;     /* Cylinder low register. */
+    uint8_t     cyl_hi;     /* Cylinder high register. */
+    uint8_t     dev_hd;     /* Device/head register. */
+    uint8_t     sec_no_exp; /* Expanded sector number register. */
+    uint8_t     cyl_lo_exp; /* Expanded cylinder low register. */
+    uint8_t     cyl_hi_exp; /* Expanded cylinder high register. */
+    uint8_t     resvd0;
+    uint8_t     sec_cn;     /* Sector count register. */
+    uint8_t     sec_cn_exp; /* Expanded sector count register. */
+    uint16_t    resvd1;
+    uint32_t    resvd2;
+} fis_d2h;
+
+ct_assert(sizeof(fis_d2h) == 20);
 
 /**
@@ -305,6 +329,5 @@
         ahci_ctrl_clear_bits(io_base, AHCI_PORT_REG(port, AHCI_REG_PORT_CMD),
                              AHCI_REG_PORT_CMD_ST);
-
-        /** @todo: Examine status. */
+        /* Caller must examine status. */
     }
     else
@@ -315,5 +338,5 @@
  * Issue command to device.
  */
-static void ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
+static uint16_t ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
 {
     ahci_t __far    *ahci  = bios_dsk->ahci_seg :> 0;
@@ -321,4 +344,5 @@
     uint16_t        sectsz = bios_dsk->drqp.sect_sz;
     uint16_t        prdt_idx;
+    fis_d2h __far   *d2h;
 
     _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
@@ -384,6 +408,11 @@
     ahci_port_cmd_sync(ahci, cmd);
 
+    /* Examine operation status. */
+    d2h = (void __far *)&ahci->abFisRecv[0x40];
+    DBG_AHCI("AHCI: ERR=%02x, STAT=%02x, SCNT=%02x\n", d2h->error, d2h->status, d2h->sec_cn);
+
     /* Unlock the buffer again. */
     vds_free_sg_list(&ahci->edds);
+    return d2h->error ? 4 : 0;
 }
 
@@ -490,4 +519,5 @@
 {
     uint16_t        device_id;
+    uint16_t        rc;
 
     device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
@@ -501,5 +531,5 @@
     high_bits_save(bios_dsk->ahci_seg :> 0);
     ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
-    ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT);
+    rc = ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT);
     DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
     bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
@@ -508,5 +538,5 @@
 #endif
     high_bits_restore(bios_dsk->ahci_seg :> 0);
-    return 0;   //@todo!!
+    return rc;
 }
 
@@ -521,4 +551,5 @@
 {
     uint16_t        device_id;
+    uint16_t        rc;
 
     device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
@@ -532,9 +563,9 @@
     high_bits_save(bios_dsk->ahci_seg :> 0);
     ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
-    ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
+    rc = ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
     DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
     bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
     high_bits_restore(bios_dsk->ahci_seg :> 0);
-    return 0;   //@todo!!
+    return rc;
 }
 
@@ -605,5 +636,4 @@
 
     return ahci->aCmdHdr[1] == 0 ? 4 : 0;
-//    return 0;   //@todo!!
 }
 
