From patchwork Wed Dec 1 19:17:11 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 73883 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 B172DB6EED for ; Thu, 2 Dec 2010 06:26:53 +1100 (EST) Received: from localhost ([127.0.0.1]:54005 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PNsKI-0006mf-O6 for incoming@patchwork.ozlabs.org; Wed, 01 Dec 2010 14:26:50 -0500 Received: from [140.186.70.92] (port=47431 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PNsB7-00031N-6o for qemu-devel@nongnu.org; Wed, 01 Dec 2010 14:17:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PNsB3-0004tn-4L for qemu-devel@nongnu.org; Wed, 01 Dec 2010 14:17:21 -0500 Received: from cantor2.suse.de ([195.135.220.15]:56929 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PNsB2-0004s9-Jp for qemu-devel@nongnu.org; Wed, 01 Dec 2010 14:17:17 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 3C8CC927A5; Wed, 1 Dec 2010 20:17:14 +0100 (CET) From: Alexander Graf To: QEMU-devel Developers Date: Wed, 1 Dec 2010 20:17:11 +0100 Message-Id: <1291231032-21150-10-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1291231032-21150-1-git-send-email-agraf@suse.de> References: <1291231032-21150-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 , Paul Brook , Blue Swirl , Gerd Hoffmann , Stefan Hajnoczi , tj@kernel.org, Roland Elek , Sebastian Herbszt Subject: [Qemu-devel] [PATCH 09/10] ide: move pata specific parts to pata.c 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 Due to popular request, this patch moves pieces that are successfully identified as PATA only to a new file called pata.c. Signed-off-by: Alexander Graf Reviewed-by: Stefan Hajnoczi --- v6 -> v7: - stick to new IDEBusOps (stefanha, kwolf) --- Makefile.objs | 2 +- hw/ide/core.c | 144 +------------------------------------------ hw/ide/internal.h | 3 + hw/ide/pata.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 143 deletions(-) create mode 100644 hw/ide/pata.c diff --git a/Makefile.objs b/Makefile.objs index d903571..69c7d92 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -230,7 +230,7 @@ hw-obj-$(CONFIG_LAN9118) += lan9118.o hw-obj-$(CONFIG_NE2000_ISA) += ne2000-isa.o # IDE -hw-obj-$(CONFIG_IDE_CORE) += ide/core.o +hw-obj-$(CONFIG_IDE_CORE) += ide/core.o ide/pata.o hw-obj-$(CONFIG_IDE_QDEV) += ide/qdev.o hw-obj-$(CONFIG_IDE_PCI) += ide/pci.o hw-obj-$(CONFIG_IDE_ISA) += ide/isa.o diff --git a/hw/ide/core.c b/hw/ide/core.c index cac209e..3ebf406 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -34,8 +34,6 @@ #include -#define IDE_PAGE_SIZE 4096 - static const int smart_attributes[][5] = { /* id, flags, val, wrst, thrsh */ { 0x01, 0x03, 0x64, 0x64, 0x06}, /* raw read */ @@ -67,8 +65,6 @@ 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; @@ -337,16 +333,6 @@ static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, s->bus->ops->transfer_start(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; - if (!(s->status & ERR_STAT)) - s->status |= DRQ_STAT; -} - static void ide_transfer_stop(IDEState *s) { s->end_transfer_func = ide_transfer_stop; @@ -443,46 +429,6 @@ static void ide_sector_read(IDEState *s) } -/* return 0 if buffer completed */ -static int dma_buf_prepare(BMDMAState *bm, int is_write) -{ - IDEState *s = bmdma_active_if(bm); - struct { - uint32_t addr; - uint32_t size; - } prd; - int l, len; - - qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1); - s->io_buffer_size = 0; - for(;;) { - if (bm->cur_prd_len == 0) { - /* end of table (with a fail safe of one page) */ - if (bm->cur_prd_last || - (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) - return s->io_buffer_size != 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); - bm->cur_addr += 8; - prd.addr = le32_to_cpu(prd.addr); - prd.size = le32_to_cpu(prd.size); - len = prd.size & 0xfffe; - if (len == 0) - len = 0x10000; - bm->cur_prd_len = len; - bm->cur_prd_addr = prd.addr; - bm->cur_prd_last = (prd.size & 0x80000000); - } - l = bm->cur_prd_len; - if (l > 0) { - qemu_sglist_add(&s->sg, bm->cur_prd_addr, l); - bm->cur_prd_addr += l; - bm->cur_prd_len -= l; - s->io_buffer_size += l; - } - } - return 1; -} - static void dma_buf_commit(IDEState *s, int is_write) { qemu_sglist_destroy(&s->sg); @@ -535,54 +481,6 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) return 1; } -/* return 0 if buffer completed */ -static int dma_buf_rw(BMDMAState *bm, int is_write) -{ - IDEState *s = bmdma_active_if(bm); - struct { - uint32_t addr; - uint32_t size; - } prd; - int l, len; - - for(;;) { - l = s->io_buffer_size - s->io_buffer_index; - if (l <= 0) - break; - if (bm->cur_prd_len == 0) { - /* end of table (with a fail safe of one page) */ - if (bm->cur_prd_last || - (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) - return 0; - cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); - bm->cur_addr += 8; - prd.addr = le32_to_cpu(prd.addr); - prd.size = le32_to_cpu(prd.size); - len = prd.size & 0xfffe; - if (len == 0) - len = 0x10000; - bm->cur_prd_len = len; - bm->cur_prd_addr = prd.addr; - bm->cur_prd_last = (prd.size & 0x80000000); - } - if (l > bm->cur_prd_len) - l = bm->cur_prd_len; - if (l > 0) { - if (is_write) { - cpu_physical_memory_write(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); - } else { - cpu_physical_memory_read(bm->cur_prd_addr, - s->io_buffer + s->io_buffer_index, l); - } - bm->cur_prd_addr += l; - bm->cur_prd_len -= l; - s->io_buffer_index += l; - } - } - return 1; -} - static void ide_read_dma_cb(void *opaque, int ret) { BMDMAState *bm = opaque; @@ -2596,18 +2494,6 @@ 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 @@ -2745,14 +2631,6 @@ static void ide_init1(IDEBus *bus, int unit) ide_sector_write_timer_cb, s); } -static IDEBusOps pata_bus_ops = { - .transfer_start = pata_transfer_start, - .set_irq = pata_set_irq, - .dma_start = pata_dma_start, - .dma_prepare = dma_buf_prepare, - .dma_rw = dma_buf_rw, -}; - void ide_init2(IDEBus *bus, qemu_irq irq) { int i; @@ -2762,7 +2640,7 @@ void ide_init2(IDEBus *bus, qemu_irq irq) ide_reset(&bus->ifs[i]); } bus->irq = irq; - bus->ops = &pata_bus_ops; + pata_init(bus); } /* TODO convert users to qdev and remove */ @@ -2786,7 +2664,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, } } bus->irq = irq; - bus->ops = &pata_bus_ops; + pata_init(bus); } void ide_init_ioport(IDEBus *bus, int iobase, int iobase2) @@ -2958,24 +2836,6 @@ const VMStateDescription vmstate_ide_bus = { /***********************************************************/ /* PCI IDE definitions */ -static void pata_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) -{ - BMDMAState *bm = s->bus->bmdma; - - if(!bm) - return; - bm->unit = s->unit; - bm->dma_cb = dma_cb; - bm->cur_prd_last = 0; - bm->cur_prd_addr = 0; - bm->cur_prd_len = 0; - bm->sector_num = ide_get_sector(s); - bm->nsector = s->nsector; - if (bm->status & BM_STATUS_DMAING) { - bm->dma_cb(bm, 0); - } -} - static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) { s->bus->ops->dma_start(s,dma_cb); diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 85cb938..15f294a 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -590,4 +590,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val); void ide_bus_new(IDEBus *idebus, DeviceState *dev); IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive); +/* hw/ide/pata.c */ +void pata_init(IDEBus *bus); + #endif /* HW_IDE_INTERNAL_H */ diff --git a/hw/ide/pata.c b/hw/ide/pata.c new file mode 100644 index 0000000..691499f --- /dev/null +++ b/hw/ide/pata.c @@ -0,0 +1,178 @@ +/* + * QEMU Parallel ATA (IDE) Emulator + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2006 Openedhand Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include "qemu-error.h" +#include "qemu-timer.h" +#include "sysemu.h" +#include "dma.h" +#include "blockdev.h" + +#include + +#define IDE_PAGE_SIZE 4096 + +static void pata_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) +{ + BMDMAState *bm = s->bus->bmdma; + + if(!bm) + return; + bm->unit = s->unit; + bm->dma_cb = dma_cb; + bm->cur_prd_last = 0; + bm->cur_prd_addr = 0; + bm->cur_prd_len = 0; + bm->sector_num = ide_get_sector(s); + bm->nsector = s->nsector; + if (bm->status & BM_STATUS_DMAING) { + bm->dma_cb(bm, 0); + } +} + +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; + if (!(s->status & ERR_STAT)) + s->status |= DRQ_STAT; +} + +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); + } +} + +/* return 0 if buffer completed */ +static int dma_buf_prepare(BMDMAState *bm, int is_write) +{ + IDEState *s = bmdma_active_if(bm); + struct { + uint32_t addr; + uint32_t size; + } prd; + int l, len; + + qemu_sglist_init(&s->sg, s->nsector / (IDE_PAGE_SIZE / 512) + 1); + s->io_buffer_size = 0; + for(;;) { + if (bm->cur_prd_len == 0) { + /* end of table (with a fail safe of one page) */ + if (bm->cur_prd_last || + (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) + return s->io_buffer_size != 0; + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + bm->cur_addr += 8; + prd.addr = le32_to_cpu(prd.addr); + prd.size = le32_to_cpu(prd.size); + len = prd.size & 0xfffe; + if (len == 0) + len = 0x10000; + bm->cur_prd_len = len; + bm->cur_prd_addr = prd.addr; + bm->cur_prd_last = (prd.size & 0x80000000); + } + l = bm->cur_prd_len; + if (l > 0) { + qemu_sglist_add(&s->sg, bm->cur_prd_addr, l); + bm->cur_prd_addr += l; + bm->cur_prd_len -= l; + s->io_buffer_size += l; + } + } + return 1; +} + +/* return 0 if buffer completed */ +static int dma_buf_rw(BMDMAState *bm, int is_write) +{ + IDEState *s = bmdma_active_if(bm); + struct { + uint32_t addr; + uint32_t size; + } prd; + int l, len; + + for(;;) { + l = s->io_buffer_size - s->io_buffer_index; + if (l <= 0) + break; + if (bm->cur_prd_len == 0) { + /* end of table (with a fail safe of one page) */ + if (bm->cur_prd_last || + (bm->cur_addr - bm->addr) >= IDE_PAGE_SIZE) + return 0; + cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8); + bm->cur_addr += 8; + prd.addr = le32_to_cpu(prd.addr); + prd.size = le32_to_cpu(prd.size); + len = prd.size & 0xfffe; + if (len == 0) + len = 0x10000; + bm->cur_prd_len = len; + bm->cur_prd_addr = prd.addr; + bm->cur_prd_last = (prd.size & 0x80000000); + } + if (l > bm->cur_prd_len) + l = bm->cur_prd_len; + if (l > 0) { + if (is_write) { + cpu_physical_memory_write(bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); + } else { + cpu_physical_memory_read(bm->cur_prd_addr, + s->io_buffer + s->io_buffer_index, l); + } + bm->cur_prd_addr += l; + bm->cur_prd_len -= l; + s->io_buffer_index += l; + } + } + return 1; +} + +static IDEBusOps pata_bus_ops = { + .transfer_start = pata_transfer_start, + .set_irq = pata_set_irq, + .dma_start = pata_dma_start, + .dma_prepare = dma_buf_prepare, + .dma_rw = dma_buf_rw, +}; + +void pata_init(IDEBus *bus) +{ + bus->ops = &pata_bus_ops; +}