From patchwork Fri Dec 10 15:01:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 75104 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 CEBADB7080 for ; Sat, 11 Dec 2010 02:17:09 +1100 (EST) Received: from localhost ([127.0.0.1]:42977 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PR4iY-00028D-C4 for incoming@patchwork.ozlabs.org; Fri, 10 Dec 2010 10:17:06 -0500 Received: from [140.186.70.92] (port=47373 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PR4TG-0001Ff-Ew for qemu-devel@nongnu.org; Fri, 10 Dec 2010 10:01:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PR4TE-0003mO-Ny for qemu-devel@nongnu.org; Fri, 10 Dec 2010 10:01:18 -0500 Received: from verein.lst.de ([213.95.11.210]:55200) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PR4TE-0003mE-At for qemu-devel@nongnu.org; Fri, 10 Dec 2010 10:01:16 -0500 Received: from verein.lst.de (localhost [127.0.0.1]) by verein.lst.de (8.12.3/8.12.3/Debian-7.1) with ESMTP id oBAF1F88031167 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Fri, 10 Dec 2010 16:01:15 +0100 Received: (from hch@localhost) by verein.lst.de (8.12.3/8.12.3/Debian-7.2) id oBAF1FIO031166 for qemu-devel@nongnu.org; Fri, 10 Dec 2010 16:01:15 +0100 Date: Fri, 10 Dec 2010 16:01:15 +0100 From: Christoph Hellwig To: qemu-devel@nongnu.org Message-ID: <20101210150115.GD31114@lst.de> References: <20101210150038.GA30990@lst.de> Mime-Version: 1.0 Content-Disposition: inline In-Reply-To: <20101210150038.GA30990@lst.de> User-Agent: Mutt/1.3.28i X-Scanned-By: MIMEDefang 2.39 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 4/7] ide: factor dma handling helpers 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 The DMA I/O path is duplicated between read and write commands, and support for the TRIM command would add another copy. Factor the code into common helpers using the s->is_read flag added for the macio ATA controller, and the newly added dma_bdrv_io function. Signed-off-by: Christoph Hellwig Index: qemu/hw/ide/core.c =================================================================== --- qemu.orig/hw/ide/core.c 2010-12-10 11:17:57.328254648 +0100 +++ qemu/hw/ide/core.c 2010-12-10 11:35:23.164005731 +0100 @@ -61,7 +61,8 @@ static inline int media_is_cd(IDEState * return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS); } -static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb); +static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb, + DMAIOFunc *io_func); static void ide_dma_restart(IDEState *s, int is_read); static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret); static int ide_handle_rw_error(IDEState *s, int error, int op); @@ -568,7 +569,7 @@ static int dma_buf_rw(BMDMAState *bm, in return 1; } -static void ide_read_dma_cb(void *opaque, int ret) +static void ide_dma_cb(void *opaque, int ret) { BMDMAState *bm = opaque; IDEState *s = bmdma_active_if(bm); @@ -576,9 +577,12 @@ static void ide_read_dma_cb(void *opaque int64_t sector_num; if (ret < 0) { - if (ide_handle_rw_error(s, -ret, - BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ)) - { + int op = BM_STATUS_DMA_RETRY; + + if (s->is_read) + op |= BM_STATUS_RETRY_READ; + + if (ide_handle_rw_error(s, -ret, op)) { return; } } @@ -586,7 +590,7 @@ static void ide_read_dma_cb(void *opaque n = s->io_buffer_size >> 9; sector_num = ide_get_sector(s); if (n > 0) { - dma_buf_commit(s, 1); + dma_buf_commit(s, s->is_read); sector_num += n; ide_set_sector(s, sector_num); s->nsector -= n; @@ -596,32 +600,39 @@ static void ide_read_dma_cb(void *opaque if (s->nsector == 0) { s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); - eot: - bm->status |= BM_STATUS_INT; - ide_dma_set_inactive(bm); - return; + goto eot; } /* launch next transfer */ n = s->nsector; - s->io_buffer_index = 0; + if (s->is_read) + s->io_buffer_index = 0; s->io_buffer_size = n * 512; - if (dma_buf_prepare(bm, 1) == 0) + if (dma_buf_prepare(bm, s->is_read) == 0) goto eot; + #ifdef DEBUG_AIO - printf("aio_read: sector_num=%" PRId64 " n=%d\n", sector_num, n); + printf("ide_dma_cb: read: %d sector_num=%" PRId64 " n=%d\n", + s->is_read, sector_num, n); #endif - bm->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, ide_read_dma_cb, bm); - ide_dma_submit_check(s, ide_read_dma_cb, bm); + + bm->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, bm->io_func, + ide_dma_cb, bm, !s->is_read); + ide_dma_submit_check(s, ide_dma_cb, bm); + return; + +eot: + bm->status |= BM_STATUS_INT; + ide_dma_set_inactive(bm); } -static void ide_sector_read_dma(IDEState *s) +static void ide_sector_dma(IDEState *s, DMAIOFunc *io_func, bool is_read) { s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; s->io_buffer_index = 0; s->io_buffer_size = 0; - s->is_read = 1; - ide_dma_start(s, ide_read_dma_cb); + s->is_read = is_read; + ide_dma_start(s, ide_dma_cb, io_func); } static void ide_sector_write_timer_cb(void *opaque) @@ -714,58 +725,6 @@ void ide_dma_restart_cb(void *opaque, in } } -static void ide_write_dma_cb(void *opaque, int ret) -{ - BMDMAState *bm = opaque; - IDEState *s = bmdma_active_if(bm); - int n; - int64_t sector_num; - - if (ret < 0) { - if (ide_handle_rw_error(s, -ret, BM_STATUS_DMA_RETRY)) - return; - } - - n = s->io_buffer_size >> 9; - sector_num = ide_get_sector(s); - if (n > 0) { - dma_buf_commit(s, 0); - sector_num += n; - ide_set_sector(s, sector_num); - s->nsector -= n; - } - - /* end of transfer ? */ - if (s->nsector == 0) { - s->status = READY_STAT | SEEK_STAT; - ide_set_irq(s->bus); - eot: - bm->status |= BM_STATUS_INT; - ide_dma_set_inactive(bm); - return; - } - - n = s->nsector; - s->io_buffer_size = n * 512; - /* launch next transfer */ - if (dma_buf_prepare(bm, 0) == 0) - goto eot; -#ifdef DEBUG_AIO - printf("aio_write: sector_num=%" PRId64 " n=%d\n", sector_num, n); -#endif - bm->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, ide_write_dma_cb, bm); - ide_dma_submit_check(s, ide_write_dma_cb, bm); -} - -static void ide_sector_write_dma(IDEState *s) -{ - s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; - s->io_buffer_index = 0; - s->io_buffer_size = 0; - s->is_read = 0; - ide_dma_start(s, ide_write_dma_cb); -} - void ide_atapi_cmd_ok(IDEState *s) { s->error = 0; @@ -1003,7 +962,7 @@ static void ide_atapi_cmd_reply(IDEState if (s->atapi_dma) { s->status = READY_STAT | SEEK_STAT | DRQ_STAT; - ide_dma_start(s, ide_atapi_cmd_read_dma_cb); + ide_dma_start(s, ide_atapi_cmd_read_dma_cb, NULL); } else { s->status = READY_STAT | SEEK_STAT; ide_atapi_cmd_reply_end(s); @@ -1111,7 +1070,7 @@ static void ide_atapi_cmd_read_dma(IDESt /* XXX: check if BUSY_STAT should be set */ s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; - ide_dma_start(s, ide_atapi_cmd_read_dma_cb); + ide_dma_start(s, ide_atapi_cmd_read_dma_cb, NULL); } static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, @@ -1968,7 +1927,7 @@ void ide_ioport_write(void *opaque, uint if (!s->bs) goto abort_cmd; ide_cmd_lba48_transform(s, lba48); - ide_sector_read_dma(s); + ide_sector_dma(s, bdrv_aio_readv, 1); break; case WIN_WRITEDMA_EXT: lba48 = 1; @@ -1977,7 +1936,7 @@ void ide_ioport_write(void *opaque, uint if (!s->bs) goto abort_cmd; ide_cmd_lba48_transform(s, lba48); - ide_sector_write_dma(s); + ide_sector_dma(s, bdrv_aio_writev, 0); s->media_changed = 1; break; case WIN_READ_NATIVE_MAX_EXT: @@ -2912,13 +2871,15 @@ const VMStateDescription vmstate_ide_bus /***********************************************************/ /* PCI IDE definitions */ -static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb) +static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb, + DMAIOFunc *io_func) { BMDMAState *bm = s->bus->bmdma; if(!bm) return; bm->unit = s->unit; bm->dma_cb = dma_cb; + bm->io_func = io_func; bm->cur_prd_last = 0; bm->cur_prd_addr = 0; bm->cur_prd_len = 0; @@ -2936,15 +2897,11 @@ static void ide_dma_restart(IDEState *s, s->io_buffer_index = 0; s->io_buffer_size = 0; s->nsector = bm->nsector; + s->is_read = is_read; bm->cur_addr = bm->addr; - if (is_read) { - bm->dma_cb = ide_read_dma_cb; - } else { - bm->dma_cb = ide_write_dma_cb; - } - - ide_dma_start(s, bm->dma_cb); + bm->dma_cb = ide_dma_cb; + ide_dma_start(s, bm->dma_cb, bm->io_func); } void ide_dma_cancel(BMDMAState *bm) Index: qemu/hw/ide/internal.h =================================================================== --- qemu.orig/hw/ide/internal.h 2010-12-10 11:17:57.348254927 +0100 +++ qemu/hw/ide/internal.h 2010-12-10 11:33:41.444006150 +0100 @@ -433,7 +433,6 @@ struct IDEState { uint32_t mdata_size; uint8_t *mdata_storage; int media_changed; - /* for pmac */ int is_read; /* SMART */ uint8_t smart_enabled; @@ -493,6 +492,7 @@ struct BMDMAState { uint8_t unit; BlockDriverCompletionFunc *dma_cb; BlockDriverAIOCB *aiocb; + DMAIOFunc *io_func; struct iovec iov; QEMUIOVector qiov; int64_t sector_num; Index: qemu/hw/ide/macio.c =================================================================== --- qemu.orig/hw/ide/macio.c 2010-12-10 11:17:57.357254927 +0100 +++ qemu/hw/ide/macio.c 2010-12-10 11:19:00.936260584 +0100 @@ -146,12 +146,8 @@ static void pmac_ide_transfer_cb(void *o io->addr += io->len; io->len = 0; - if (s->is_read) - m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, - pmac_ide_transfer_cb, io); - else - m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, - pmac_ide_transfer_cb, io); + m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, s->io_func, + pmac_ide_transfer_cb, io, !s->is_read); if (!m->aiocb) pmac_ide_transfer_cb(io, -1); }