From patchwork Thu Nov 25 07:07:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 73020 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 347B8B70A9 for ; Thu, 25 Nov 2010 19:04:22 +1100 (EST) Received: from localhost ([127.0.0.1]:37386 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLWoV-0000LI-3b for incoming@patchwork.ozlabs.org; Thu, 25 Nov 2010 03:04:19 -0500 Received: from [140.186.70.92] (port=43212 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLVvp-0005c6-GU for qemu-devel@nongnu.org; Thu, 25 Nov 2010 02:07:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PLVvm-0003Y4-S4 for qemu-devel@nongnu.org; Thu, 25 Nov 2010 02:07:49 -0500 Received: from cantor.suse.de ([195.135.220.2]:38689 helo=mx1.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PLVvm-0003WQ-D2 for qemu-devel@nongnu.org; Thu, 25 Nov 2010 02:07:46 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 89E3193EE3; Thu, 25 Nov 2010 08:07:43 +0100 (CET) From: Alexander Graf To: QEMU-devel Developers Date: Thu, 25 Nov 2010 08:07:34 +0100 Message-Id: <1290668862-11695-4-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1290668862-11695-1-git-send-email-agraf@suse.de> References: <1290668862-11695-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: Kevin Wolf , Joerg Roedel , Blue Swirl , Gerd Hoffmann , Stefan Hajnoczi , tj@kernel.org, Roland Elek , Sebastian Herbszt Subject: [Qemu-devel] [PATCH 03/11] ide: add support for ide bus ops X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Roland Elek We need to hook into some of the core IDE functionality for AHCI. To do that, the easiest way is to make explicit functions calls be implicit through a function call struct. Signed-off-by: Roland Elek Signed-off-by: Alexander Graf --- v1 -> v2: - rename IDEExtender to IDEBusOps and make a pointer (kraxel) --- hw/ide/core.c | 36 +++++++++++++++++++++++++++++++++++- hw/ide/internal.h | 26 +++++++++++++++++++------- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 1849069..c8d7810 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -67,6 +67,8 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret); static int ide_handle_rw_error(IDEState *s, int error, int op); static void ide_flush_cache(IDEState *s); +static void pata_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb); + static void padstr(char *str, const char *src, int len) { int i, v; @@ -325,6 +327,12 @@ static inline void ide_dma_submit_check(IDEState *s, static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, EndTransferFunc *end_transfer_func) { + s->bus->ops->transfer_start_fn(s,buf,size,end_transfer_func); +} + +static void pata_transfer_start(IDEState *s, uint8_t *buf, int size, + EndTransferFunc *end_transfer_func) +{ s->end_transfer_func = end_transfer_func; s->data_ptr = buf; s->data_end = buf + size; @@ -2580,6 +2588,18 @@ static void ide_dummy_transfer_stop(IDEState *s) s->io_buffer[3] = 0xff; } +static void pata_set_irq(IDEBus *bus) +{ + BMDMAState *bm = bus->bmdma; + + if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) { + if (bm) { + bm->status |= BM_STATUS_INT; + } + qemu_irq_raise(bus->irq); + } +} + static void ide_reset(IDEState *s) { #ifdef DEBUG_IDE @@ -2716,6 +2736,12 @@ static void ide_init1(IDEBus *bus, int unit) ide_sector_write_timer_cb, s); } +static IDEBusOps ide_bus_ops = { + .transfer_start_fn = pata_transfer_start, + .irq_set_fn = pata_set_irq, + .dma_start_fn = pata_dma_start, +}; + void ide_init2(IDEBus *bus, qemu_irq irq) { int i; @@ -2725,6 +2751,7 @@ void ide_init2(IDEBus *bus, qemu_irq irq) ide_reset(&bus->ifs[i]); } bus->irq = irq; + bus->ops = &ide_bus_ops; } /* TODO convert users to qdev and remove */ @@ -2748,6 +2775,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, } } bus->irq = irq; + bus->ops = &ide_bus_ops; } void ide_init_ioport(IDEBus *bus, int iobase, int iobase2) @@ -2919,9 +2947,10 @@ const VMStateDescription vmstate_ide_bus = { /***********************************************************/ /* PCI IDE definitions */ -static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) +static void pata_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) { BMDMAState *bm = s->bus->bmdma; + if(!bm) return; bm->unit = s->unit; @@ -2936,6 +2965,11 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) } } +static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) +{ + s->bus->ops->dma_start_fn(s,dma_cb); +} + static void ide_dma_restart(IDEState *s, int is_read) { BMDMAState *bm = s->bus->bmdma; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index e7e1f80..ee7e13e 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -20,6 +20,7 @@ typedef struct IDEDevice IDEDevice; typedef struct IDEDeviceInfo IDEDeviceInfo; typedef struct IDEState IDEState; typedef struct BMDMAState BMDMAState; +typedef struct IDEBusOps IDEBusOps; /* Bits of HD_STATUS */ #define ERR_STAT 0x01 @@ -366,6 +367,14 @@ typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind; typedef void EndTransferFunc(IDEState *); + +typedef void TransferStartFunc(IDEState *, + uint8_t *, + int, + EndTransferFunc *); +typedef void IRQSetFunc(IDEBus *); +typedef void DMAStartFunc(IDEState *, BlockDriverCompletionFunc *); + /* NOTE: IDEState represents in fact one drive */ struct IDEState { IDEBus *bus; @@ -442,12 +451,21 @@ struct IDEState { uint8_t *smart_selftest_data; }; +/* This struct represents a device that uses an IDE bus, but requires + * modifications to how it works. An example is AHCI. */ +struct IDEBusOps { + TransferStartFunc *transfer_start_fn; + IRQSetFunc *irq_set_fn; + DMAStartFunc *dma_start_fn; +}; + struct IDEBus { BusState qbus; IDEDevice *master; IDEDevice *slave; BMDMAState *bmdma; IDEState ifs[2]; + IDEBusOps *ops; uint8_t unit; uint8_t cmd; qemu_irq irq; @@ -512,13 +530,7 @@ static inline IDEState *bmdma_active_if(BMDMAState *bmdma) static inline void ide_set_irq(IDEBus *bus) { - BMDMAState *bm = bus->bmdma; - if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) { - if (bm) { - bm->status |= BM_STATUS_INT; - } - qemu_irq_raise(bus->irq); - } + bus->ops->irq_set_fn(bus); } /* hw/ide/core.c */