summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-disk.c
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2003-11-11 07:49:45 +0000
committersos <sos@FreeBSD.org>2003-11-11 07:49:45 +0000
commitf94d8d190f9352650fb74cd5cde444d121b207cc (patch)
treea3e6f9f613211f79706723ab06f8f466d0f9cbea /sys/dev/ata/ata-disk.c
parent850659706db5b428ff2c27204b346bdf0d6c8f84 (diff)
downloadFreeBSD-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/ata/ata-disk.c')
-rw-r--r--sys/dev/ata/ata-disk.c44
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;
}
OpenPOWER on IntegriCloud