diff options
author | sos <sos@FreeBSD.org> | 2003-11-11 07:49:45 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2003-11-11 07:49:45 +0000 |
commit | f94d8d190f9352650fb74cd5cde444d121b207cc (patch) | |
tree | a3e6f9f613211f79706723ab06f8f466d0f9cbea /sys/dev | |
parent | 850659706db5b428ff2c27204b346bdf0d6c8f84 (diff) | |
download | FreeBSD-src-f94d8d190f9352650fb74cd5cde444d121b207cc.zip FreeBSD-src-f94d8d190f9352650fb74cd5cde444d121b207cc.tar.gz |
Update the dump code to flush buffers at the end of the dump
to avoid loosing evt cached data.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/ata-disk.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 926f8f6..08e7f34 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -331,28 +331,34 @@ addump(void *arg, void *virtual, vm_offset_t physical, bzero(&request, sizeof(struct ata_request)); request.device = adp->device; - request.data = virtual; - request.bytecount = length; - request.transfersize = min(length, adp->max_iosize); - request.flags = ATA_R_WRITE; - if (adp->max_iosize > DEV_BSIZE) - request.u.ata.command = ATA_WRITE_MUL; - else - request.u.ata.command = ATA_WRITE; - request.u.ata.lba = offset / DEV_BSIZE; - request.u.ata.count = request.bytecount / DEV_BSIZE; + if (length) { + request.data = virtual; + request.bytecount = length; + request.transfersize = min(length, adp->max_iosize); + request.flags = ATA_R_WRITE; + if (adp->max_iosize > DEV_BSIZE) + request.u.ata.command = ATA_WRITE_MUL; + else + request.u.ata.command = ATA_WRITE; + request.u.ata.lba = offset / DEV_BSIZE; + request.u.ata.count = request.bytecount / DEV_BSIZE; + } + else { + request.u.ata.command = ATA_FLUSHCACHE; + request.flags = ATA_R_CONTROL; + } - if (adp->device->channel->hw.transaction(&request) == ATA_OP_FINISHED) - return EIO; - while (request.bytecount > request.donecount) { - DELAY(20); - adp->device->channel->running = &request; - adp->device->channel->hw.interrupt(adp->device->channel); - adp->device->channel->running = NULL; - if (request.status & ATA_S_ERROR) - return EIO; + if (request.device->channel->hw.transaction(&request) == ATA_OP_CONTINUES) { + while (request.device->channel->running == &request && + !(request.status & ATA_S_ERROR)) { + DELAY(20); + request.device->channel->running = &request; + request.device->channel->hw.interrupt(request.device->channel); + } } + if (request.status & ATA_S_ERROR) + return EIO; return 0; } |