From patchwork Mon Jun 24 09:10:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 253771 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E4D812C016F for ; Mon, 24 Jun 2013 19:27:45 +1000 (EST) Received: from localhost ([::1]:51831 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur2pm-0004yl-NH for incoming@patchwork.ozlabs.org; Mon, 24 Jun 2013 05:13:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47239) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur2nS-0001eT-21 for qemu-devel@nongnu.org; Mon, 24 Jun 2013 05:10:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ur2nM-0007EE-M0 for qemu-devel@nongnu.org; Mon, 24 Jun 2013 05:10:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23337) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ur2nM-0007E9-Ab for qemu-devel@nongnu.org; Mon, 24 Jun 2013 05:10:44 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r5O9AhhH023655 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 24 Jun 2013 05:10:43 -0400 Received: from localhost (ovpn-112-34.ams2.redhat.com [10.36.112.34]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r5O9AgXF010001; Mon, 24 Jun 2013 05:10:42 -0400 From: Stefan Hajnoczi To: Date: Mon, 24 Jun 2013 11:10:13 +0200 Message-Id: <1372065035-19601-2-git-send-email-stefanha@redhat.com> In-Reply-To: <1372065035-19601-1-git-send-email-stefanha@redhat.com> References: <1372065035-19601-1-git-send-email-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi Subject: [Qemu-devel] [PATCH 01/23] ide: Add handler to ide_cmd_table X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Kevin Wolf As a preparation for moving all IDE commands into their own function like in the ATAPI code, introduce a 'handler' callback to ide_cmd_table. Commands using this new infrastructure get some things handled automatically: * The BSY flag is set before calling the handler (in order to avoid bugs like the one fixed in f68ec837) and reset on completion. * The (obsolete) DSC flag in the status register is set on completion if the command is flagged with SET_DSC in the command table * An IRQ is triggered on completion. * The error register and the ERR flag in the status register are cleared before calling the handler and on completion it is asserted that either none or both of them are set. No commands are converted at this point. Signed-off-by: Kevin Wolf Signed-off-by: Stefan Hajnoczi --- hw/ide/core.c | 144 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 58 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 9926d92..cd9de14 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1010,71 +1010,78 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) #define HD_CFA_OK (HD_OK | CFA_OK) #define ALL_OK (HD_OK | CD_OK | CFA_OK) +/* Set the Disk Seek Completed status bit during completion */ +#define SET_DSC (1u << 8) + /* See ACS-2 T13/2015-D Table B.2 Command codes */ -static const uint8_t ide_cmd_table[0x100] = { +static const struct { + /* Returns true if the completion code should be run */ + bool (*handler)(IDEState *s, uint8_t cmd); + int flags; +} ide_cmd_table[0x100] = { /* NOP not implemented, mandatory for CD */ - [CFA_REQ_EXT_ERROR_CODE] = CFA_OK, - [WIN_DSM] = ALL_OK, - [WIN_DEVICE_RESET] = CD_OK, - [WIN_RECAL] = HD_CFA_OK, - [WIN_READ] = ALL_OK, - [WIN_READ_ONCE] = ALL_OK, - [WIN_READ_EXT] = HD_CFA_OK, - [WIN_READDMA_EXT] = HD_CFA_OK, - [WIN_READ_NATIVE_MAX_EXT] = HD_CFA_OK, - [WIN_MULTREAD_EXT] = HD_CFA_OK, - [WIN_WRITE] = HD_CFA_OK, - [WIN_WRITE_ONCE] = HD_CFA_OK, - [WIN_WRITE_EXT] = HD_CFA_OK, - [WIN_WRITEDMA_EXT] = HD_CFA_OK, - [CFA_WRITE_SECT_WO_ERASE] = CFA_OK, - [WIN_MULTWRITE_EXT] = HD_CFA_OK, - [WIN_WRITE_VERIFY] = HD_CFA_OK, - [WIN_VERIFY] = HD_CFA_OK, - [WIN_VERIFY_ONCE] = HD_CFA_OK, - [WIN_VERIFY_EXT] = HD_CFA_OK, - [WIN_SEEK] = HD_CFA_OK, - [CFA_TRANSLATE_SECTOR] = CFA_OK, - [WIN_DIAGNOSE] = ALL_OK, - [WIN_SPECIFY] = HD_CFA_OK, - [WIN_STANDBYNOW2] = ALL_OK, - [WIN_IDLEIMMEDIATE2] = ALL_OK, - [WIN_STANDBY2] = ALL_OK, - [WIN_SETIDLE2] = ALL_OK, - [WIN_CHECKPOWERMODE2] = ALL_OK, - [WIN_SLEEPNOW2] = ALL_OK, - [WIN_PACKETCMD] = CD_OK, - [WIN_PIDENTIFY] = CD_OK, - [WIN_SMART] = HD_CFA_OK, - [CFA_ACCESS_METADATA_STORAGE] = CFA_OK, - [CFA_ERASE_SECTORS] = CFA_OK, - [WIN_MULTREAD] = HD_CFA_OK, - [WIN_MULTWRITE] = HD_CFA_OK, - [WIN_SETMULT] = HD_CFA_OK, - [WIN_READDMA] = HD_CFA_OK, - [WIN_READDMA_ONCE] = HD_CFA_OK, - [WIN_WRITEDMA] = HD_CFA_OK, - [WIN_WRITEDMA_ONCE] = HD_CFA_OK, - [CFA_WRITE_MULTI_WO_ERASE] = CFA_OK, - [WIN_STANDBYNOW1] = ALL_OK, - [WIN_IDLEIMMEDIATE] = ALL_OK, - [WIN_STANDBY] = ALL_OK, - [WIN_SETIDLE1] = ALL_OK, - [WIN_CHECKPOWERMODE1] = ALL_OK, - [WIN_SLEEPNOW1] = ALL_OK, - [WIN_FLUSH_CACHE] = ALL_OK, - [WIN_FLUSH_CACHE_EXT] = HD_CFA_OK, - [WIN_IDENTIFY] = ALL_OK, - [WIN_SETFEATURES] = ALL_OK, - [IBM_SENSE_CONDITION] = CFA_OK, - [CFA_WEAR_LEVEL] = HD_CFA_OK, - [WIN_READ_NATIVE_MAX] = ALL_OK, + [CFA_REQ_EXT_ERROR_CODE] = { NULL, CFA_OK }, + [WIN_DSM] = { NULL, ALL_OK }, + [WIN_DEVICE_RESET] = { NULL, CD_OK }, + [WIN_RECAL] = { NULL, HD_CFA_OK }, + [WIN_READ] = { NULL, ALL_OK }, + [WIN_READ_ONCE] = { NULL, ALL_OK }, + [WIN_READ_EXT] = { NULL, HD_CFA_OK }, + [WIN_READDMA_EXT] = { NULL, HD_CFA_OK }, + [WIN_READ_NATIVE_MAX_EXT] = { NULL, HD_CFA_OK }, + [WIN_MULTREAD_EXT] = { NULL, HD_CFA_OK }, + [WIN_WRITE] = { NULL, HD_CFA_OK }, + [WIN_WRITE_ONCE] = { NULL, HD_CFA_OK }, + [WIN_WRITE_EXT] = { NULL, HD_CFA_OK }, + [WIN_WRITEDMA_EXT] = { NULL, HD_CFA_OK }, + [CFA_WRITE_SECT_WO_ERASE] = { NULL, CFA_OK }, + [WIN_MULTWRITE_EXT] = { NULL, HD_CFA_OK }, + [WIN_WRITE_VERIFY] = { NULL, HD_CFA_OK }, + [WIN_VERIFY] = { NULL, HD_CFA_OK }, + [WIN_VERIFY_ONCE] = { NULL, HD_CFA_OK }, + [WIN_VERIFY_EXT] = { NULL, HD_CFA_OK }, + [WIN_SEEK] = { NULL, HD_CFA_OK }, + [CFA_TRANSLATE_SECTOR] = { NULL, CFA_OK }, + [WIN_DIAGNOSE] = { NULL, ALL_OK }, + [WIN_SPECIFY] = { NULL, HD_CFA_OK }, + [WIN_STANDBYNOW2] = { NULL, ALL_OK }, + [WIN_IDLEIMMEDIATE2] = { NULL, ALL_OK }, + [WIN_STANDBY2] = { NULL, ALL_OK }, + [WIN_SETIDLE2] = { NULL, ALL_OK }, + [WIN_CHECKPOWERMODE2] = { NULL, ALL_OK }, + [WIN_SLEEPNOW2] = { NULL, ALL_OK }, + [WIN_PACKETCMD] = { NULL, CD_OK }, + [WIN_PIDENTIFY] = { NULL, CD_OK }, + [WIN_SMART] = { NULL, HD_CFA_OK }, + [CFA_ACCESS_METADATA_STORAGE] = { NULL, CFA_OK }, + [CFA_ERASE_SECTORS] = { NULL, CFA_OK }, + [WIN_MULTREAD] = { NULL, HD_CFA_OK }, + [WIN_MULTWRITE] = { NULL, HD_CFA_OK }, + [WIN_SETMULT] = { NULL, HD_CFA_OK }, + [WIN_READDMA] = { NULL, HD_CFA_OK }, + [WIN_READDMA_ONCE] = { NULL, HD_CFA_OK }, + [WIN_WRITEDMA] = { NULL, HD_CFA_OK }, + [WIN_WRITEDMA_ONCE] = { NULL, HD_CFA_OK }, + [CFA_WRITE_MULTI_WO_ERASE] = { NULL, CFA_OK }, + [WIN_STANDBYNOW1] = { NULL, ALL_OK }, + [WIN_IDLEIMMEDIATE] = { NULL, ALL_OK }, + [WIN_STANDBY] = { NULL, ALL_OK }, + [WIN_SETIDLE1] = { NULL, ALL_OK }, + [WIN_CHECKPOWERMODE1] = { NULL, ALL_OK }, + [WIN_SLEEPNOW1] = { NULL, ALL_OK }, + [WIN_FLUSH_CACHE] = { NULL, ALL_OK }, + [WIN_FLUSH_CACHE_EXT] = { NULL, HD_CFA_OK }, + [WIN_IDENTIFY] = { NULL, ALL_OK }, + [WIN_SETFEATURES] = { NULL, ALL_OK }, + [IBM_SENSE_CONDITION] = { NULL, CFA_OK }, + [CFA_WEAR_LEVEL] = { NULL, HD_CFA_OK }, + [WIN_READ_NATIVE_MAX] = { NULL, ALL_OK }, }; static bool ide_cmd_permitted(IDEState *s, uint32_t cmd) { return cmd < ARRAY_SIZE(ide_cmd_table) - && (ide_cmd_table[cmd] & (1u << s->drive_kind)); + && (ide_cmd_table[cmd].flags & (1u << s->drive_kind)); } void ide_exec_cmd(IDEBus *bus, uint32_t val) @@ -1100,6 +1107,27 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val) goto abort_cmd; } + if (ide_cmd_table[val].handler != NULL) { + bool complete; + + s->status = READY_STAT | BUSY_STAT; + s->error = 0; + + complete = ide_cmd_table[val].handler(s, val); + if (complete) { + s->status &= ~BUSY_STAT; + assert(!!s->error == !!(s->status & ERR_STAT)); + + if ((ide_cmd_table[val].flags & SET_DSC) && !s->error) { + s->status |= SEEK_STAT; + } + + ide_set_irq(s->bus); + } + + return; + } + switch(val) { case WIN_DSM: switch (s->feature) {