From: Lubomir Rintel <lkund...@v3.sk> CompactFlash uses features 0x01 and 0x81 to enable/disable 8-bit data path. Implement them.
Signed-off-by: Lubomir Rintel <lkund...@v3.sk> Message-Id: <20221130120238.706717-1-lkund...@v3.sk> Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- hw/ide/core.c | 43 ++++++++++++++++++++++++++++++--------- include/hw/ide/internal.h | 1 + 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 39afdc0006b9..5d1039378f1d 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1648,6 +1648,13 @@ static bool cmd_set_features(IDEState *s, uint8_t cmd) /* XXX: valid for CDROM ? */ switch (s->feature) { + case 0x01: /* 8-bit I/O enable (CompactFlash) */ + case 0x81: /* 8-bit I/O disable (CompactFlash) */ + if (s->drive_kind != IDE_CFATA) { + goto abort_cmd; + } + s->io8 = !(s->feature & 0x80); + return true; case 0x02: /* write cache enable */ blk_set_enable_write_cache(s->blk, true); identify_data = (uint16_t *)s->identify_data; @@ -2374,12 +2381,20 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) } p = s->data_ptr; - if (p + 2 > s->data_end) { - return; - } + if (s->io8) { + if (p + 1 > s->data_end) { + return; + } - *(uint16_t *)p = le16_to_cpu(val); - p += 2; + *p++ = val; + } else { + if (p + 2 > s->data_end) { + return; + } + + *(uint16_t *)p = le16_to_cpu(val); + p += 2; + } s->data_ptr = p; if (p >= s->data_end) { s->status &= ~DRQ_STAT; @@ -2401,12 +2416,20 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr) } p = s->data_ptr; - if (p + 2 > s->data_end) { - return 0; - } + if (s->io8) { + if (p + 1 > s->data_end) { + return 0; + } - ret = cpu_to_le16(*(uint16_t *)p); - p += 2; + ret = *p++; + } else { + if (p + 2 > s->data_end) { + return 0; + } + + ret = cpu_to_le16(*(uint16_t *)p); + p += 2; + } s->data_ptr = p; if (p >= s->data_end) { s->status &= ~DRQ_STAT; diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h index b17f36df957d..fc0aa81a88b9 100644 --- a/include/hw/ide/internal.h +++ b/include/hw/ide/internal.h @@ -402,6 +402,7 @@ struct IDEState { uint8_t select; uint8_t status; + bool io8; bool reset_reverts; /* set for lba48 access */ -- 2.38.1