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:
parent
5a9eee48b6
commit
7f2f1b784e
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ");
|
||||
|
103
sys/scsi/sd.c
103
sys/scsi/sd.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user