From ffbed36b7bee5f705e4058e17a11a54b4f649a75 Mon Sep 17 00:00:00 2001 From: scottl Date: Thu, 19 Jun 2003 01:49:04 +0000 Subject: Fixing some glaring problems with aac_disk_dump(). - Mark that it cannot handle greater than 4GB of RAM at this time. Fixing that will come later. Fail any attempts to dump above thati limit. - If a call to aac_disk_dump() needs to be split into multiple i/o's, increment the virtual offset after each i/o instead of just dumping the same offset over and over again. - Bail out if bus_dmamap_load() returns an error. Error recovery is likely not possible. --- sys/dev/aac/aac_disk.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'sys') diff --git a/sys/dev/aac/aac_disk.c b/sys/dev/aac/aac_disk.c index 48288c1..2ac9f6b 100644 --- a/sys/dev/aac/aac_disk.c +++ b/sys/dev/aac/aac_disk.c @@ -182,6 +182,9 @@ aac_disk_strategy(struct bio *bp) /* * Map the S/G elements for doing a dump. + * + * XXX This does not handle >4GB of RAM. Fixing it is possible except on + * adapters that cannot do 64bit s/g lists. */ static void aac_dump_map_sg(void *arg, bus_dma_segment_t *segs, int nsegs, int error) @@ -198,6 +201,8 @@ aac_dump_map_sg(void *arg, bus_dma_segment_t *segs, int nsegs, int error) if (sg != NULL) { sg->SgCount = nsegs; for (i = 0; i < nsegs; i++) { + if (segs[i].ds_addr >= BUS_SPACE_MAXADDR_32BIT) + return; sg->SgEntry[i].SgAddress = segs[i].ds_addr; sg->SgEntry[i].SgByteCount = segs[i].ds_len; } @@ -249,8 +254,17 @@ aac_disk_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size bw->BlockNumber = offset / AAC_BLOCK_SIZE; bw->ByteCount = len; bw->Stable = CUNSTABLE; - bus_dmamap_load(sc->aac_buffer_dmat, dump_datamap, virtual, - len, aac_dump_map_sg, fib, 0); + + /* + * There really isn't any way to recover from errors or + * resource shortages here. Oh well. Because of that, don't + * bother trying to send the command from the callback; there + * is too much required context. + */ + if (bus_dmamap_load(sc->aac_buffer_dmat, dump_datamap, virtual, + len, aac_dump_map_sg, fib, 0) != 0) + return (EIO); + bus_dmamap_sync(sc->aac_buffer_dmat, dump_datamap, BUS_DMASYNC_PREWRITE); @@ -261,8 +275,10 @@ aac_disk_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size printf("Error dumping block 0x%x\n", physical); return (EIO); } + length -= len; offset += len; + (vm_offset_t)virtual += len; } return (0); -- cgit v1.1