diff options
Diffstat (limited to 'sys/dev/ata/ata-disk.c')
-rw-r--r-- | sys/dev/ata/ata-disk.c | 62 |
1 files changed, 17 insertions, 45 deletions
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 8a5ef87..8f21ea1 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -293,50 +293,29 @@ adstrategy(struct bio *bp) ata_start(adp->device->channel); } -int -addump(dev_t dev) +static int +addump(dev_t dev, void *virtual, vm_offset_t physical, off_t offset, size_t length) { struct ad_softc *adp = dev->si_drv1; struct ad_request request; - u_int count, blkno, secsize; - vm_offset_t addr = 0; - long blkcnt; - int dumppages = MAXDUMPPGS; - int error; - int i; - - if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize))) - return error; - + static int once; + if (!adp) return ENXIO; - /* force PIO mode for dumps */ - adp->device->mode = ATA_PIO; - ata_reinit(adp->device->channel); - - blkcnt = howmany(PAGE_SIZE, secsize); - - while (count > 0) { - caddr_t va = NULL; - DELAY(1000); - - if ((count / blkcnt) < dumppages) - dumppages = count / blkcnt; - - for (i = 0; i < dumppages; ++i) { - vm_offset_t a = addr + (i * PAGE_SIZE); - if (is_physical_memory(a)) - va = pmap_kenter_temporary(trunc_page(a), i); - else - va = pmap_kenter_temporary(trunc_page(0), i); - } + if (!once) { + /* force PIO mode for dumps */ + adp->device->mode = ATA_PIO; + ata_reinit(adp->device->channel); + once = 1; + } + if (length > 0) { bzero(&request, sizeof(struct ad_request)); request.softc = adp; - request.blockaddr = blkno; - request.bytecount = PAGE_SIZE * dumppages; - request.data = va; + request.blockaddr = offset / DEV_BSIZE; + request.bytecount = length; + request.data = virtual; while (request.bytecount > 0) { ad_transfer(&request); @@ -346,17 +325,10 @@ addump(dev_t dev) request.bytecount -= request.currentsize; DELAY(20); } - - if (dumpstatus(addr, (off_t)count * DEV_BSIZE) < 0) - return EINTR; - - blkno += blkcnt * dumppages; - count -= blkcnt * dumppages; - addr += PAGE_SIZE * dumppages; + } else { + if (ata_wait(adp->device, ATA_S_READY | ATA_S_DSC) < 0) + ata_prtdev(adp->device, "timeout waiting for final ready\n"); } - - if (ata_wait(adp->device, ATA_S_READY | ATA_S_DSC) < 0) - ata_prtdev(adp->device, "timeout waiting for final ready\n"); return 0; } |