aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/ide/ahci.c18
-rw-r--r--hw/ide/ahci.h8
2 files changed, 17 insertions, 9 deletions
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index d80ddd2..61dbed1 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -570,24 +570,24 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished)
AHCIDevice *ad = &s->dev[port];
AHCIPortRegs *pr = &ad->port_regs;
IDEState *ide_state;
- uint8_t *sdb_fis;
+ SDBFIS *sdb_fis;
if (!s->dev[port].res_fis ||
!(pr->cmd & PORT_CMD_FIS_RX)) {
return;
}
- sdb_fis = &ad->res_fis[RES_FIS_SDBFIS];
+ sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS];
ide_state = &ad->port.ifs[0];
- /* clear memory */
- *(uint32_t*)sdb_fis = 0;
-
- /* write values */
- sdb_fis[0] = ide_state->error;
- sdb_fis[2] = ide_state->status & 0x77;
+ sdb_fis->type = 0xA1;
+ /* Interrupt pending & Notification bit */
+ sdb_fis->flags = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
+ sdb_fis->status = ide_state->status & 0x77;
+ sdb_fis->error = ide_state->error;
+ /* update SAct field in SDB_FIS */
s->dev[port].finished |= finished;
- *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(ad->finished);
+ sdb_fis->payload = cpu_to_le32(ad->finished);
/* Update shadow registers (except BSY 0x80 and DRQ 0x08) */
pr->tfdata = (ad->port.ifs[0].error << 8) |
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index e8ea34a..b123237 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -327,6 +327,14 @@ typedef struct NCQFrame {
uint8_t reserved10;
} QEMU_PACKED NCQFrame;
+typedef struct SDBFIS {
+ uint8_t type;
+ uint8_t flags;
+ uint8_t status;
+ uint8_t error;
+ uint32_t payload;
+} QEMU_PACKED SDBFIS;
+
void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports);
void ahci_uninit(AHCIState *s);