From: Alexander Graf <agraf@suse.de>
To: QEMU-devel Developers <qemu-devel@nongnu.org>
Cc: tj@kernel.org, Joerg Roedel <Joerg.Roedel@amd.com>,
Sebastian Herbszt <herbszt@gmx.de>,
Roland Elek <elek.roland@gmail.com>
Subject: [Qemu-devel] [PATCH 03/10] ide: add support for ide extenders
Date: Wed, 17 Nov 2010 02:05:29 +0100 [thread overview]
Message-ID: <1289955937-24121-4-git-send-email-agraf@suse.de> (raw)
In-Reply-To: <1289955937-24121-1-git-send-email-agraf@suse.de>
From: Roland Elek <elek.roland@gmail.com>
An "extender" (from the "extends" keyword denoting a subclass in
various object-oriented languages) is a device that builds upon an
IDE bus, but needs to change various aspects of its inner workings
to customize it to its needs. An example of an extender is an AHCI
HBA. We add support for extenders by defining a struct that contains
callback function pointers that can be set by the device building
upon the bus. The IDE core was modified so that ide_transfer_start,
ide_set_irq and ide_dma_start call the function pointed to by the
respective field in the extender struct, instead of doing their
original jobs. The original functions are available as
pata_transfer_start, pata_set_irq and pata_dma_start. The extender
callbacks are initialized to these in ide_init2, making them the
defaults, and eliminating the need to modify ATA controller code.
Signed-off-by: Roland Elek <elek.roland@gmail.com>
---
hw/ide/core.c | 34 +++++++++++++++++++++++++++++++++-
hw/ide/internal.h | 26 +++++++++++++++++++-------
2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 1849069..276b853 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->extender.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
@@ -2725,6 +2745,9 @@ void ide_init2(IDEBus *bus, qemu_irq irq)
ide_reset(&bus->ifs[i]);
}
bus->irq = irq;
+ bus->extender.transfer_start_fn = pata_transfer_start;
+ bus->extender.irq_set_fn = pata_set_irq;
+ bus->extender.dma_start_fn = pata_dma_start;
}
/* TODO convert users to qdev and remove */
@@ -2748,6 +2771,9 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
}
}
bus->irq = irq;
+ bus->extender.transfer_start_fn = pata_transfer_start;
+ bus->extender.irq_set_fn = pata_set_irq;
+ bus->extender.dma_start_fn = pata_dma_start;
}
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2)
@@ -2919,9 +2945,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 +2963,11 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
}
}
+static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
+{
+ s->bus->extender.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..19e5efb 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 IDEExtender IDEExtender;
/* 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 IDEExtender {
+ 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];
+ IDEExtender extender;
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->extender.irq_set_fn(bus);
}
/* hw/ide/core.c */
--
1.6.0.2
next prev parent reply other threads:[~2010-11-17 1:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-17 1:05 [Qemu-devel] [PATCH 00/10] AHCI emulation support Alexander Graf
2010-11-17 1:05 ` [Qemu-devel] [PATCH 01/10] ide: split ide command interpretation off Alexander Graf
2010-11-17 1:05 ` [Qemu-devel] [PATCH 02/10] ide: fix whitespace gap in ide_exec_cmd Alexander Graf
2010-11-17 1:05 ` Alexander Graf [this message]
2010-11-17 8:57 ` [Qemu-devel] [PATCH 03/10] ide: add support for ide extenders Gerd Hoffmann
2010-11-17 1:05 ` [Qemu-devel] [PATCH 04/10] ide: enable preallocated sg lists Alexander Graf
2010-11-17 8:59 ` Gerd Hoffmann
2010-11-17 9:21 ` Stefan Hajnoczi
2010-11-17 1:05 ` [Qemu-devel] [PATCH 05/10] ide: add ncq identify data for ahci sata drives Alexander Graf
2010-11-17 1:05 ` [Qemu-devel] [PATCH 06/10] pci: add storage class for sata Alexander Graf
2010-11-17 1:05 ` [Qemu-devel] [PATCH 07/10] pci: add ich7 pci id Alexander Graf
2010-11-17 1:05 ` [Qemu-devel] [PATCH 08/10] ahci: add ahci emulation Alexander Graf
2010-11-17 9:08 ` Gerd Hoffmann
2010-11-17 12:21 ` Alexander Graf
2010-11-17 13:56 ` Gerd Hoffmann
2010-11-17 1:05 ` [Qemu-devel] [PATCH 09/10] ahci: add -drive support Alexander Graf
2010-11-17 1:05 ` [Qemu-devel] [PATCH 10/10] ahci: spawn controller on demand Alexander Graf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1289955937-24121-4-git-send-email-agraf@suse.de \
--to=agraf@suse.de \
--cc=Joerg.Roedel@amd.com \
--cc=elek.roland@gmail.com \
--cc=herbszt@gmx.de \
--cc=qemu-devel@nongnu.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).