[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 07/14] ahci: send init d2h fis on fis enable
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 07/14] ahci: send init d2h fis on fis enable |
Date: |
Mon, 7 Feb 2011 13:40:23 +0100 |
From: Alexander Graf <address@hidden>
The drive sends a d2h init fis on initialization. Usually, the guest doesn't
receive fises yet at that point though, so the delivery is deferred.
Let's reflect that by sending the init fis on fis receive enablement.
Signed-off-by: Alexander Graf <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
hw/ide/ahci.c | 38 +++++++++++++++++++++++++++++++-------
hw/ide/ahci.h | 1 +
2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 6822046..e6ac77c 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -47,6 +47,7 @@ static void check_cmd(AHCIState *s, int port);
static int handle_cmd(AHCIState *s,int port,int slot);
static void ahci_reset_port(AHCIState *s, int port);
static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis);
+static void ahci_init_d2h(AHCIDevice *ad);
static uint32_t ahci_port_read(AHCIState *s, int port, int offset)
{
@@ -230,6 +231,16 @@ static void ahci_port_write(AHCIState *s, int port, int
offset, uint32_t val)
pr->cmd |= PORT_CMD_FIS_ON;
}
+ /* XXX usually the FIS would be pending on the bus here and
+ issuing deferred until the OS enables FIS receival.
+ Instead, we only submit it once - which works in most
+ cases, but is a hack. */
+ if ((pr->cmd & PORT_CMD_FIS_ON) &&
+ !s->dev[port].init_d2h_sent) {
+ ahci_init_d2h(&s->dev[port]);
+ s->dev[port].init_d2h_sent = 1;
+ }
+
check_cmd(s, port);
break;
case PORT_TFDATA:
@@ -462,12 +473,29 @@ static void ahci_check_cmd_bh(void *opaque)
check_cmd(ad->hba, ad->port_no);
}
+static void ahci_init_d2h(AHCIDevice *ad)
+{
+ uint8_t init_fis[0x20];
+ IDEState *ide_state = &ad->port.ifs[0];
+
+ memset(init_fis, 0, sizeof(init_fis));
+
+ init_fis[4] = 1;
+ init_fis[12] = 1;
+
+ if (ide_state->drive_kind == IDE_CD) {
+ init_fis[5] = ide_state->lcyl;
+ init_fis[6] = ide_state->hcyl;
+ }
+
+ ahci_write_fis_d2h(ad, init_fis);
+}
+
static void ahci_reset_port(AHCIState *s, int port)
{
AHCIDevice *d = &s->dev[port];
AHCIPortRegs *pr = &d->port_regs;
IDEState *ide_state = &d->port.ifs[0];
- uint8_t init_fis[0x20];
int i;
DPRINTF(port, "reset port\n");
@@ -482,6 +510,7 @@ static void ahci_reset_port(AHCIState *s, int port)
pr->scr_err = 0;
pr->scr_act = 0;
d->busy_slot = -1;
+ d->init_d2h_sent = 0;
ide_state = &s->dev[port].port.ifs[0];
if (!ide_state->bs) {
@@ -504,7 +533,6 @@ static void ahci_reset_port(AHCIState *s, int port)
ncq_tfs->used = 0;
}
- memset(init_fis, 0, sizeof(init_fis));
s->dev[port].port_state = STATE_RUN;
if (!ide_state->bs) {
s->dev[port].port_regs.sig = 0;
@@ -514,8 +542,6 @@ static void ahci_reset_port(AHCIState *s, int port)
ide_state->lcyl = 0x14;
ide_state->hcyl = 0xeb;
DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);
- init_fis[5] = ide_state->lcyl;
- init_fis[6] = ide_state->hcyl;
ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;
} else {
s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK;
@@ -523,9 +549,7 @@ static void ahci_reset_port(AHCIState *s, int port)
}
ide_state->error = 1;
- init_fis[4] = 1;
- init_fis[12] = 1;
- ahci_write_fis_d2h(d, init_fis);
+ ahci_init_d2h(d);
}
static void debug_print_fis(uint8_t *fis, int cmd_len)
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index d65b5e3..b2786d1 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -282,6 +282,7 @@ struct AHCIDevice {
int dma_status;
int done_atapi_packet;
int busy_slot;
+ int init_d2h_sent;
BlockDriverCompletionFunc *dma_cb;
AHCICmdHdr *cur_cmd;
NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
--
1.7.2.3
- [Qemu-devel] [PULL 00/14] Block patches for master, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 01/14] qcow2: Really use cache=unsafe for image creation, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 02/14] Documentation: add Sheepdog disk images, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 03/14] block/vdi: Fix wrong size in conditionally used memset, memcmp, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 05/14] ahci: add license header in ahci.h, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 07/14] ahci: send init d2h fis on fis enable,
Kevin Wolf <=
- [Qemu-devel] [PATCH 04/14] ahci: split ICH9 from core, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 06/14] ahci: split ICH and AHCI even more, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 08/14] ahci: Implement HBA reset, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 09/14] ahci: make number of ports runtime determined, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 10/14] block-migration: actually disable dirty tracking on cleanup, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 11/14] blockdev: add refcount to DriveInfo, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 13/14] Add flag to indicate external users to block device, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 12/14] block-migration: add reference to target DriveInfo, Kevin Wolf, 2011/02/07
- [Qemu-devel] [PATCH 14/14] block: enable in_use flag, Kevin Wolf, 2011/02/07
- [Qemu-devel] Re: [PULL 00/14] Block patches for master, Anthony Liguori, 2011/02/07