Add dump support to the DEVFS/slice code.

now we can actually catch our crashes :-)

Submitted by: Luoqi Chen <luoqi@chen.ml.org> (the man who's everywhere)
This commit is contained in:
Julian Elischer 1998-05-06 22:14:48 +00:00
parent 5a9eee48b6
commit 7f2f1b784e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=35812
13 changed files with 371 additions and 32 deletions

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $Id: autoconf.c,v 1.94 1998/04/20 03:57:23 julian Exp $
* $Id: autoconf.c,v 1.95 1998/04/20 21:53:07 julian Exp $
*/
/*
@ -398,6 +398,7 @@ setdumpdev(dev)
{
int maj, psize;
long newdumplo;
struct partinfo pi;
if (dev == NODEV) {
dumpdev = dev;
@ -418,7 +419,9 @@ setdumpdev(dev)
* and nuke dodump sysctl (too many knobs), and move this to
* kern_shutdown.c...
*/
if (dkpart(dev) != SWAP_PART)
if (bdevsw[maj]->d_ioctl(dev, DIOCGPART, (caddr_t)&pi, 0, NULL) != 0)
return (ENODEV);
if (pi.part->p_fstype != FS_SWAP)
return (ENODEV);
newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE;
if (newdumplo < 0)

View File

@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
* $Id: fd.c,v 1.109 1998/04/19 23:31:41 julian Exp $
* $Id: fd.c,v 1.110 1998/04/22 10:25:15 julian Exp $
*
*/
@ -2196,9 +2196,9 @@ fdsopen(void *private, int flags, int mode, struct proc *p)
sd = private;
if((flags & (FREAD|FWRITE)) != 0) {
return(Fdopen(makedev(0,sd->minor), 0 , 0, p));
return(Fdopen(makedev(0,sd->minor), flags , mode, p));
} else {
return(fdclose(makedev(0,sd->minor), 0 , 0, p));
return(fdclose(makedev(0,sd->minor), 0 , mode, p));
}
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: disklabel.c,v 1.2 1998/04/22 10:25:09 julian Exp $
* $Id: disklabel.c,v 1.3 1998/04/22 19:27:51 julian Exp $
*/
#define BAD144
@ -74,6 +74,7 @@ static sl_h_claim_t dkl_claim; /* upwards travelling claim */
static sl_h_revoke_t dkl_revoke;/* upwards travelling revokation */
static sl_h_verify_t dkl_verify;/* things changed, are we stil valid? */
static sl_h_upconfig_t dkl_upconfig;/* config requests from below */
static sl_h_dump_t dkl_dump; /* core dump req downward */
static struct slice_handler slicetype = {
"disklabel",
@ -88,7 +89,8 @@ static struct slice_handler slicetype = {
&dkl_revoke, /* revoke */
&dkl_claim, /* claim */
&dkl_verify, /* verify */
&dkl_upconfig /* subslice manipulation */
&dkl_upconfig, /* subslice manipulation */
&dkl_dump
};
static void
@ -828,6 +830,7 @@ dkl_upconfig(struct slice *slice, int cmd, caddr_t addr, int flag, struct proc *
case SLCIOCRESET:
return (0);
#ifdef BAD144
case SLCIOCTRANSBAD:
{
struct private_data *pd;
@ -838,6 +841,7 @@ dkl_upconfig(struct slice *slice, int cmd, caddr_t addr, int flag, struct proc *
*(daddr_t*)addr = dkl_transbad144(pd, *(daddr_t*)addr);
return (0);
}
#endif
/* These don't really make sense. keep the headers for a reminder */
default:
@ -916,3 +920,17 @@ dkcksum(lp)
}
#endif /* 0 */
static int
dkl_dump(void *private, int32_t blkoff, int32_t blkcnt)
{
struct private_data *pd;
struct subdev *sdp;
register struct slice *slice;
RR;
sdp = private;
pd = sdp->pd;
slice = pd->slice_down;
blkoff += sdp->offset;
return (*slice->handler_down->dump)(slice->private_down, blkoff, blkcnt);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mbr.c,v 1.2 1998/04/22 10:25:09 julian Exp $
* $Id: mbr.c,v 1.3 1998/04/22 19:27:51 julian Exp $
*/
#include <sys/param.h>
@ -85,6 +85,7 @@ static sl_h_claim_t mbr_claim; /* upwards travelling claim */
static sl_h_revoke_t mbr_revoke;/* upwards travelling revokation */
static sl_h_verify_t mbr_verify;/* things changed, are we stil valid? */
static sl_h_upconfig_t mbr_upconfig;/* config request from below */
static sl_h_dump_t mbr_dump; /* core dump req downward */
static struct slice_handler slicetype = {
"MBR",
@ -99,7 +100,8 @@ static struct slice_handler slicetype = {
&mbr_revoke, /* revoke */
&mbr_claim, /* claim */
&mbr_verify, /* verify */
&mbr_upconfig /* config from below */
&mbr_upconfig, /* config from below */
&mbr_dump
};
static void
@ -839,6 +841,8 @@ mbr_upconfig(struct slice *slice, int cmd, caddr_t addr,
daddr_t blkno;
int part;
if (!slice->handler_up)
return (0);
blkno = *(daddr_t *)addr;
pd = slice->private_up;
sdp = pd->subdevs;
@ -868,3 +872,17 @@ mbr_upconfig(struct slice *slice, int cmd, caddr_t addr,
return (0);
}
static int
mbr_dump(void *private, int32_t blkoff, int32_t blkcnt)
{
struct private_data *pd;
struct subdev *sdp;
register struct slice *slice;
RR;
sdp = private;
pd = sdp->pd;
slice = pd->slice_down;
blkoff += sdp->offset;
return (*slice->handler_down->dump)(slice->private_down, blkoff, blkcnt);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: $
* $Id: slice.h,v 1.1 1998/04/19 23:31:10 julian Exp $
*/
typedef struct slice_handler *sh_p;
@ -125,6 +125,7 @@ typedef int sl_h_claim_t(struct slice * slice, struct slice * lower,
typedef int sl_h_verify_t(struct slice *slice);
typedef int sl_h_upconfig_t(struct slice *slice, int cmd, caddr_t data,
int fflag, struct proc *p);
typedef int sl_h_dump_t(void *private, int32_t blkoff, int32_t blkcnt);
struct slice_handler {
char *name;
@ -140,6 +141,7 @@ struct slice_handler {
sl_h_claim_t *claim; /* claim a new slice */
sl_h_verify_t *verify; /* verify that a slice as it was before */
sl_h_upconfig_t *upconf; /* config requests from slice below */
sl_h_dump_t *dump; /* dump the core */
};
/*

View File

@ -23,9 +23,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: slice_device.c,v 1.3 1998/04/22 19:27:52 julian Exp $
* $Id: slice_device.c,v 1.4 1998/04/24 07:53:55 julian Exp $
*/
#define DIAGNOSTIC 1
#include "opt_hw_wdog.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -39,7 +40,9 @@
#include <sys/devfsext.h> /* DEVFS defintitions */
#include <dev/slice/slice.h> /* temporary location */
#include <vm/vm_param.h>
#include <machine/md_var.h>
#include <i386/i386/cons.h>
/* Function prototypes (these should all be static except for slicenew()) */
static d_open_t slcdevopen;
@ -369,8 +372,26 @@ static int
slcdevdump(dev_t dev)
{
sl_p slice = minor_to_slice(minor(dev));
static int slcdoingdump = 0;
int32_t num, nblocks, lo;
RR;
if (slice == NULL)
if (!slice || !(slice->flags & SLF_OPEN_DEV_WR) ||
!slice->handler_down->dump)
return (ENXIO);
return (0);
/* Toss any characters present prior to dump. */
while (cncheckc() != -1)
;
if (slcdoingdump)
return (EFAULT);
num = (int32_t)(Maxmem * PAGE_SIZE / slice->limits.blksize);
nblocks = (int32_t)(slice->limits.slicesize / slice->limits.blksize);
lo = dumplo * DEV_BSIZE / slice->limits.blksize;
if (lo < 0 || lo + num > nblocks)
return (EINVAL);
slcdoingdump = 1;
return (*slice->handler_down->dump)(slice->private_down, lo, num);
}

View File

@ -38,7 +38,7 @@
* from: Utah Hdr: vn.c 1.13 94/04/02
*
* from: @(#)vn.c 8.6 (Berkeley) 4/1/94
* $Id: vn.c,v 1.57 1998/04/22 10:25:12 julian Exp $
* $Id: vn.c,v 1.58 1998/04/24 07:53:59 julian Exp $
*/
/*
@ -114,6 +114,7 @@ static sl_h_IO_req_t nvsIOreq; /* IO req downward (to device) */
static sl_h_ioctl_t nvsioctl; /* ioctl req downward (to device) */
static sl_h_open_t nvsopen; /* downwards travelling open */
/*static sl_h_close_t nvsclose; */ /* downwards travelling close */
static sl_h_dump_t nvsdump; /* core dump req downward */
static struct slice_handler slicetype = {
"vn",
@ -128,7 +129,8 @@ static struct slice_handler slicetype = {
NULL, /* revoke */
NULL, /* claim */
NULL, /* verify */
NULL /* upconfig */
NULL, /* upconfig */
&nvsdump
};
#endif
@ -448,6 +450,14 @@ nvsIOreq(void *private ,struct buf *bp)
bn = bp->b_pblkno;
bp->b_resid = bp->b_bcount;/* XXX best place to set this? */
sz = howmany(bp->b_bcount, DEV_BSIZE);
if (bn < 0 || bn + sz > vn->sc_size) {
if (bn != vn->sc_size) {
bp->b_error = EINVAL;
bp->b_flags |= B_ERROR;
}
biodone(bp);
return;
}
if( (bp->b_flags & B_PAGING) == 0) {
aiov.iov_base = bp->b_data;
@ -936,5 +946,10 @@ nvsioctl( void *private, int cmd, caddr_t addr, int flag, struct proc *p)
return(vnioctl(makedev(0,vn->mynor), cmd, addr, flag, p));
}
static int
nvsdump(void *private, int32_t blkoff, int32_t blkcnt)
{
return (ENODEV);
}
#endif
#endif

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
* $Id: autoconf.c,v 1.94 1998/04/20 03:57:23 julian Exp $
* $Id: autoconf.c,v 1.95 1998/04/20 21:53:07 julian Exp $
*/
/*
@ -398,6 +398,7 @@ setdumpdev(dev)
{
int maj, psize;
long newdumplo;
struct partinfo pi;
if (dev == NODEV) {
dumpdev = dev;
@ -418,7 +419,9 @@ setdumpdev(dev)
* and nuke dodump sysctl (too many knobs), and move this to
* kern_shutdown.c...
*/
if (dkpart(dev) != SWAP_PART)
if (bdevsw[maj]->d_ioctl(dev, DIOCGPART, (caddr_t)&pi, 0, NULL) != 0)
return (ENODEV);
if (pi.part->p_fstype != FS_SWAP)
return (ENODEV);
newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE;
if (newdumplo < 0)

View File

@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
* $Id: fd.c,v 1.109 1998/04/19 23:31:41 julian Exp $
* $Id: fd.c,v 1.110 1998/04/22 10:25:15 julian Exp $
*
*/
@ -2196,9 +2196,9 @@ fdsopen(void *private, int flags, int mode, struct proc *p)
sd = private;
if((flags & (FREAD|FWRITE)) != 0) {
return(Fdopen(makedev(0,sd->minor), 0 , 0, p));
return(Fdopen(makedev(0,sd->minor), flags , mode, p));
} else {
return(fdclose(makedev(0,sd->minor), 0 , 0, p));
return(fdclose(makedev(0,sd->minor), 0 , mode, p));
}
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
* $Id: wd.c,v 1.163 1998/04/24 07:54:00 julian Exp $
* $Id: wd.c,v 1.164 1998/05/05 14:27:26 sos Exp $
*/
/* TODO:
@ -263,6 +263,7 @@ static sl_h_IO_req_t wdsIOreq; /* IO req downward (to device) */
static sl_h_ioctl_t wdsioctl; /* ioctl req downward (to device) */
static sl_h_open_t wdsopen; /* downwards travelling open */
/*static sl_h_close_t wdsclose; */ /* downwards travelling close */
static sl_h_dump_t wdsdump; /* core dump req downward */
static void wds_init(void*);
static struct slice_handler slicetype = {
@ -278,7 +279,8 @@ static struct slice_handler slicetype = {
NULL, /* revoke */
NULL, /* claim */
NULL, /* verify */
NULL /* upconfig */
NULL, /* upconfig */
&wdsdump
};
#endif
@ -970,7 +972,7 @@ wdstart(int ctrlr)
blknum - ds_offset) + ds_offset;
}
#else
if (du->dk_flags & DKFL_SINGLE) {
if (du->dk_flags & DKFL_SINGLE && du->slice->handler_up) {
(void) (*du->slice->handler_up->upconf)(du->slice,
SLCIOCTRANSBAD, (caddr_t)&blknum, 0, 0);
}
@ -2782,5 +2784,158 @@ wdsioctl( void *private, int cmd, caddr_t addr, int flag, struct proc *p)
}
}
static int
wdsdump(void *private, int32_t start, int32_t num)
{
register struct disk *du;
long blknum, blkchk, blkcnt, blknext;
long cylin, head, sector;
long secpertrk, secpercyl, nblocks;
char *addr;
du = private;
if (du->dk_state < OPEN)
return (ENXIO);
secpertrk = du->dk_dd.d_nsectors;
secpercyl = du->dk_dd.d_secpercyl;
/* Recalibrate the drive. */
DELAY(5); /* ATA spec XXX NOT */
if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
|| wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0
|| wdsetctlr(du) != 0) {
wderror((struct buf *)NULL, du, "wddump: recalibrate failed");
return (EIO);
}
du->dk_flags |= DKFL_SINGLE;
addr = (char *) 0;
blknum = start;
while (num > 0) {
blkcnt = num;
if (blkcnt > MAXTRANSFER)
blkcnt = MAXTRANSFER;
/* Keep transfer within current cylinder. */
if ((blknum + blkcnt - 1) / secpercyl != blknum / secpercyl)
blkcnt = secpercyl - (blknum % secpercyl);
blknext = blknum + blkcnt;
/*
* See if one of the sectors is in the bad sector list
* (if we have one). If the first sector is bad, then
* reduce the transfer to this one bad sector; if another
* sector is bad, then reduce reduce the transfer to
* avoid any bad sectors.
*/
if (du->dk_flags & DKFL_SINGLE && du->slice->handler_up) {
for (blkchk = blknum; blkchk < blknum + blkcnt; blkchk++) {
daddr_t blknew = blkchk;
(void) (*du->slice->handler_up->upconf)(du->slice,
SLCIOCTRANSBAD, (caddr_t)&blknew, 0, 0);
if (blknew != blkchk) {
/* Found bad block. */
blkcnt = blkchk - blknum;
if (blkcnt > 0) {
blknext = blknum + blkcnt;
goto out;
}
blkcnt = 1;
blknext = blknum + blkcnt;
#if 1 || defined(WDDEBUG)
printf("bad block %lu -> %lu\n",
blknum, blknew);
#endif
break;
}
}
}
out:
/* Compute disk address. */
cylin = blknum / secpercyl;
head = (blknum % secpercyl) / secpertrk;
sector = blknum % secpertrk;
#if 0
/* Let's just talk about this first... */
pg("cylin l%d head %ld sector %ld addr 0x%x count %ld",
cylin, head, sector, addr, blkcnt);
#endif
/* Do the write. */
if (wdcommand(du, cylin, head, sector, blkcnt, WDCC_WRITE)
!= 0) {
wderror((struct buf *)NULL, du,
"wdsdump: timeout waiting to to give command");
return (EIO);
}
while (blkcnt != 0) {
if (is_physical_memory((vm_offset_t)addr))
pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
trunc_page(addr), VM_PROT_READ, TRUE);
else
pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
trunc_page(0), VM_PROT_READ, TRUE);
/* Ready to send data? */
DELAY(5); /* ATA spec */
if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT)
< 0) {
wderror((struct buf *)NULL, du,
"wdsdump: timeout waiting for DRQ");
return (EIO);
}
if (du->dk_flags & DKFL_32BIT)
outsl(du->dk_port + wd_data,
CADDR1 + ((int)addr & PAGE_MASK),
DEV_BSIZE / sizeof(long));
else
outsw(du->dk_port + wd_data,
CADDR1 + ((int)addr & PAGE_MASK),
DEV_BSIZE / sizeof(short));
addr += DEV_BSIZE;
/*
* If we are dumping core, it may take a while.
* So reassure the user and hold off any watchdogs.
*/
if ((unsigned)addr % (1024 * 1024) == 0) {
#ifdef HW_WDOG
if (wdog_tickler)
(*wdog_tickler)();
#endif /* HW_WDOG */
printf("%ld ", num / (1024 * 1024 / DEV_BSIZE));
}
num--;
blkcnt--;
}
/* Wait for completion. */
DELAY(5); /* ATA spec XXX NOT */
if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) < 0) {
wderror((struct buf *)NULL, du,
"wdsdump: timeout waiting for status");
return (EIO);
}
/* Check final status. */
if (du->dk_status
& (WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ | WDCS_ERR)
!= (WDCS_READY | WDCS_SEEKCMPLT)) {
wderror((struct buf *)NULL, du,
"wdsdump: extra DRQ, or error");
return (EIO);
}
/* Update block count. */
blknum = blknext;
/* Operator aborting dump? */
if (cncheckc() != -1)
return (EINTR);
}
return (0);
}
#endif /* SLICE */
#endif /* NWDC > 0 */

View File

@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
* $Id: fd.c,v 1.109 1998/04/19 23:31:41 julian Exp $
* $Id: fd.c,v 1.110 1998/04/22 10:25:15 julian Exp $
*
*/
@ -2196,9 +2196,9 @@ fdsopen(void *private, int flags, int mode, struct proc *p)
sd = private;
if((flags & (FREAD|FWRITE)) != 0) {
return(Fdopen(makedev(0,sd->minor), 0 , 0, p));
return(Fdopen(makedev(0,sd->minor), flags , mode, p));
} else {
return(fdclose(makedev(0,sd->minor), 0 , 0, p));
return(fdclose(makedev(0,sd->minor), 0 , mode, p));
}
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_shutdown.c 8.3 (Berkeley) 1/21/94
* $Id: kern_shutdown.c,v 1.28 1998/02/16 23:57:44 eivind Exp $
* $Id: kern_shutdown.c,v 1.29 1998/03/08 09:56:54 julian Exp $
*/
#include "opt_ddb.h"
@ -55,6 +55,7 @@
#include <sys/sysctl.h>
#include <sys/conf.h>
#include <sys/sysproto.h>
#include <sys/disklabel.h>
#include <machine/pcb.h>
#include <machine/clock.h>
@ -358,17 +359,21 @@ SYSINIT(dump_conf, SI_SUB_DUMP_CONF, SI_ORDER_FIRST, dump_conf, NULL)
static void
dumpsys(void)
{
struct partinfo pi;
if (!dodump)
return;
if (dumpdev == NODEV)
return;
if ((minor(dumpdev)&07) != 1)
return;
if (!(bdevsw[major(dumpdev)]))
return;
if (!(bdevsw[major(dumpdev)]->d_dump))
return;
if ((*bdevsw[major(dumpdev)]->d_ioctl)(dumpdev, DIOCGPART,
(caddr_t)&pi, 0, NULL))
return;
if (pi.part->p_fstype != FS_SWAP)
return;
dumpsize = Maxmem;
printf("\ndumping to dev %lx, offset %ld\n", dumpdev, dumplo);
printf("dump ");

View File

@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
* $Id: sd.c,v 1.125 1998/04/22 10:25:27 julian Exp $
* $Id: sd.c,v 1.126 1998/04/27 11:36:06 des Exp $
*/
#include "opt_bounce.h"
@ -144,6 +144,7 @@ static sl_h_ioctl_t sdsioctl; /* ioctl req downward (to device) */
static sl_h_open_t sdsopen; /* downwards travelling open */
/*static sl_h_close_t sdsclose; */ /* downwards travelling close */
static void sds_init (void *arg);
static sl_h_dump_t sdsdump; /* core dump req downward */
static struct slice_handler slicetype = {
"scsidisk",
@ -158,7 +159,8 @@ static struct slice_handler slicetype = {
NULL, /* revoke */
NULL, /* claim */
NULL, /* verify */
NULL /* upconfig */
NULL, /* upconfig */
&sdsdump
};
#endif
@ -1313,4 +1315,101 @@ sdsioctl( void *private, int cmd, caddr_t addr, int flag, struct proc *p)
return(sdioctl(makedev(0,sd->mynor), cmd, addr, flag, p));
}
static int
sdsdump(void *private, int32_t start, int32_t num)
{ /* dump core after a system crash */
register struct scsi_data *sd; /* disk unit to do the IO */
struct scsi_link *sc_link;
int32_t blkoff, blknum, blkcnt = MAXTRANSFER;
char *addr;
struct scsi_rw_big cmd;
struct scsi_xfer *xs = &sx;
errval retval;
addr = (char *) 0; /* starting address */
sd = private;
sc_link = sd->sc_link;
/* was it ever initialized etc. ? */
if (!(sd->flags & SDINIT))
return (ENXIO);
if ((sc_link->flags & SDEV_MEDIA_LOADED) != SDEV_MEDIA_LOADED)
return (ENXIO);
blknum = start;
while (num > 0) {
if (is_physical_memory((vm_offset_t)addr))
pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
trunc_page(addr), VM_PROT_READ, TRUE);
else
pmap_enter(kernel_pmap, (vm_offset_t)CADDR1,
trunc_page(0), VM_PROT_READ, TRUE);
/*
* Fill out the scsi command
*/
bzero(&cmd, sizeof(cmd));
cmd.op_code = WRITE_BIG;
cmd.addr_3 = (blknum & 0xff000000) >> 24;
cmd.addr_2 = (blknum & 0xff0000) >> 16;
cmd.addr_1 = (blknum & 0xff00) >> 8;
cmd.addr_0 = blknum & 0xff;
cmd.length2 = (blkcnt & 0xff00) >> 8;
cmd.length1 = (blkcnt & 0xff);
/*
* Fill out the scsi_xfer structure
* Note: we cannot sleep as we may be an interrupt
* don't use scsi_scsi_cmd() as it may want
* to wait for an xs.
*/
bzero(xs, sizeof(sx));
xs->flags |= SCSI_NOMASK | SCSI_NOSLEEP | INUSE | SCSI_DATA_OUT;
xs->sc_link = sc_link;
xs->retries = SD_RETRIES;
xs->timeout = 10000; /* 10000 millisecs for a disk ! */
xs->cmd = (struct scsi_generic *) &cmd;
xs->cmdlen = sizeof(cmd);
xs->resid = 0;
xs->error = XS_NOERROR;
xs->bp = 0;
xs->data = (u_char *) CADDR1; /* XXX use pmap_enter() */
xs->datalen = blkcnt * sd->params.secsiz;
/*
* Pass all this info to the scsi driver.
*/
retval = (*(sc_link->adapter->scsi_cmd)) (xs);
switch (retval) {
case SUCCESSFULLY_QUEUED:
case HAD_ERROR:
return (ENXIO); /* we said not to sleep! */
case COMPLETE:
break;
default:
return (ENXIO); /* we said not to sleep! */
}
/*
* If we are dumping core, it may take a while.
* So reassure the user and hold off any watchdogs.
*/
if ((unsigned)addr % (1024 * 1024) == 0) {
#ifdef HW_WDOG
if (wdog_tickler)
(*wdog_tickler)();
#endif /* HW_WDOG */
printf("%ld ", num / 2048);
}
/* update block count */
num -= blkcnt;
blknum += blkcnt;
(int) addr += blkcnt * sd->params.secsiz;
/* operator aborting dump? */
if (cncheckc() != -1)
return (EINTR);
}
return (0);
}
#endif