From b55a81d93991dbc0f8d6852310b1466e9591d5cd Mon Sep 17 00:00:00 2001 From: Theo de Raadt Date: Tue, 26 May 2020 13:38:08 +0000 Subject: iodcstrategy() maintains a cache for READ performance (tapes are supported here, and alternatively would need to rewind). WRITE code exists, but was always wrong -- it writes the cache-buffer to disk, rather than the provided write-buffer. Copy the write-buffer into the cache, and invalidate the cache completely so that future reads start from scratch. --- sys/arch/hppa/stand/libsa/pdc.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'sys') diff --git a/sys/arch/hppa/stand/libsa/pdc.c b/sys/arch/hppa/stand/libsa/pdc.c index 7ab9abbbd4e..6926e1ab001 100644 --- a/sys/arch/hppa/stand/libsa/pdc.c +++ b/sys/arch/hppa/stand/libsa/pdc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pdc.c,v 1.21 2013/03/23 16:08:28 deraadt Exp $ */ +/* $OpenBSD: pdc.c,v 1.22 2020/05/26 13:38:07 deraadt Exp $ */ /* * Copyright (c) 1998-2004 Michael Shalayeff @@ -201,8 +201,9 @@ iodcstrategy(devdata, rw, blk, size, buf, rsize) } xfer = 0; - /* see if we can scratch anything from buffer */ - if (dp->last_blk <= blk && (dp->last_blk + dp->last_read) > blk) { + /* On read, see if we can scratch anything from buffer */ + if (rw == F_READ && + dp->last_blk <= blk && (dp->last_blk + dp->last_read) > blk) { twiddle(); offset = blk - dp->last_blk; xfer = min(dp->last_read - offset, size); @@ -222,6 +223,12 @@ iodcstrategy(devdata, rw, blk, size, buf, rsize) */ for (; size; size -= ret, buf += ret, blk += ret, xfer += ret) { offset = blk & IOPGOFSET; + if (rw != F_READ) { + /* put block into cache, but invalidate cache */ + bcopy(buf, dp->buf, size); + dp->last_blk = 0; + dp->last_read = 0; + } if ((ret = ((iodcio_t)pzdev->pz_iodc_io)(pzdev->pz_hpa, (rw == F_READ? IODC_IO_READ: IODC_IO_WRITE), pzdev->pz_spa, pzdev->pz_layers, pdcbuf, @@ -238,11 +245,13 @@ iodcstrategy(devdata, rw, blk, size, buf, rsize) } if ((ret = pdcbuf[0]) <= 0) break; - dp->last_blk = blk - offset; - dp->last_read = ret; - if ((ret -= offset) > size) - ret = size; - bcopy(dp->buf + offset, buf, ret); + if (rw == F_READ) { + dp->last_blk = blk - offset; + dp->last_read = ret; + if ((ret -= offset) > size) + ret = size; + bcopy(dp->buf + offset, buf, ret); + } #ifdef PDCDEBUG if (debug) printf("read %d(%d,%d)@%x ", ret, -- cgit v1.2.3