implement new-style block device dump routine if __BDEVSW_DUMP_OLD_TYPE
not defined, otherwise use an "not implemented" stub.
This commit is contained in:
parent
d093e5d8b8
commit
2a8d6461a8
181
sys/dev/ata/wd.c
181
sys/dev/ata/wd.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wd.c,v 1.139 1995/04/17 12:09:31 cgd Exp $ */
|
||||
/* $NetBSD: wd.c,v 1.140 1995/06/26 05:18:28 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||
|
@ -1407,76 +1407,103 @@ wdsize(dev)
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __BDEVSW_DUMP_OLD_TYPE
|
||||
/* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
|
||||
static int wddoingadump;
|
||||
static int wddumprecalibrated;
|
||||
|
||||
/*
|
||||
* Dump core after a system crash.
|
||||
*/
|
||||
int
|
||||
wddump(dev)
|
||||
dev_t dev;
|
||||
wddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
struct wd_softc *wd; /* disk unit to do the IO */
|
||||
struct wdc_softc *wdc;
|
||||
struct disklabel *lp;
|
||||
int unit, part;
|
||||
long rblkno, nblks;
|
||||
char *addr;
|
||||
static wddoingadump = 0;
|
||||
extern caddr_t CADDR1;
|
||||
extern pt_entry_t *CMAP1;
|
||||
|
||||
struct wd_softc *wd; /* disk unit to do the I/O */
|
||||
struct wdc_softc *wdc; /* disk controller to do the I/O */
|
||||
struct disklabel *lp; /* disk's disklabel */
|
||||
int unit, part;
|
||||
int sectorsize; /* size of a disk sector */
|
||||
int nsects; /* number of sectors in partition */
|
||||
int sectoff; /* sector offset of partition */
|
||||
int totwrt; /* total number of sectors left to write */
|
||||
int nwrt; /* current number of sectors to write */
|
||||
int retval;
|
||||
|
||||
/* Check if recursive dump; if so, punt. */
|
||||
if (wddoingadump)
|
||||
return EFAULT;
|
||||
|
||||
/* Mark as active early. */
|
||||
wddoingadump = 1;
|
||||
|
||||
unit = WDUNIT(dev);
|
||||
/* Check for acceptable drive number. */
|
||||
if (unit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wdcd.cd_devs[unit];
|
||||
/* Was it ever initialized? */
|
||||
if (wd == 0 || wd->sc_state < OPEN)
|
||||
return ENXIO;
|
||||
|
||||
wdc = (void *)wd->sc_dev.dv_parent;
|
||||
addr = (char *)0; /* starting address */
|
||||
lp = &wd->sc_dk.dk_label;
|
||||
unit = WDUNIT(dev); /* decompose unit & partition */
|
||||
part = WDPART(dev);
|
||||
|
||||
/* Convert to disk sectors. */
|
||||
rblkno = lp->d_partitions[part].p_offset + dumplo;
|
||||
nblks = min(ctob(physmem) / lp->d_secsize,
|
||||
lp->d_partitions[part].p_size - dumplo);
|
||||
/* Check for acceptable drive number. */
|
||||
if (unit >= wdcd.cd_ndevs || (wd = wdcd.cd_devs[unit]) == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* Make sure it was initialized. */
|
||||
if (wd->sc_state < OPEN)
|
||||
return ENXIO;
|
||||
|
||||
/* Remember the controller device, and sanity check */
|
||||
if ((wdc = (void *)wd->sc_dev.dv_parent) == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* Convert to disk sectors. Request must be a multiple of size. */
|
||||
lp = &wd->sc_dk.dk_label;
|
||||
sectorsize = lp->d_secsize;
|
||||
if ((size % sectorsize) != 0)
|
||||
return EFAULT;
|
||||
totwrt = size / sectorsize;
|
||||
blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */
|
||||
|
||||
nsects = lp->d_partitions[part].p_size;
|
||||
sectoff = lp->d_partitions[part].p_offset;
|
||||
|
||||
/* Check transfer bounds against partition size. */
|
||||
if (dumplo < 0 || nblks <= 0)
|
||||
return EINVAL;
|
||||
if ((blkno < 0) || ((blkno + totwrt) > nsects))
|
||||
return EINVAL;
|
||||
|
||||
/* Recalibrate. */
|
||||
if (wdcommandshort(wdc, wd->sc_drive, WDCC_RECAL) != 0 ||
|
||||
wait_for_ready(wdc) != 0 || wdsetctlr(wd) != 0 ||
|
||||
wait_for_ready(wdc) != 0) {
|
||||
wderror(wd, NULL, "wddump: recal failed");
|
||||
return EIO;
|
||||
/* Offset block number to start of partition. */
|
||||
blkno += sectoff;
|
||||
|
||||
/* Recalibrate, if first dump transfer. */
|
||||
if (wddumprecalibrated == 0) {
|
||||
wddumprecalibrated = 1;
|
||||
if (wdcommandshort(wdc, wd->sc_drive, WDCC_RECAL) != 0 ||
|
||||
wait_for_ready(wdc) != 0 || wdsetctlr(wd) != 0 ||
|
||||
wait_for_ready(wdc) != 0) {
|
||||
wderror(wd, NULL, "wddump: recal failed");
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
while (nblks > 0) {
|
||||
long blkno;
|
||||
|
||||
while (totwrt > 0) {
|
||||
long cylin, head, sector;
|
||||
daddr_t xlt_blkno;
|
||||
|
||||
blkno = rblkno;
|
||||
nwrt = 1; /* ouch XXX */
|
||||
xlt_blkno = blkno;
|
||||
|
||||
if ((lp->d_flags & D_BADSECT) != 0) {
|
||||
long blkdiff;
|
||||
int i;
|
||||
|
||||
for (i = 0; (blkdiff = wd->sc_badsect[i]) != -1; i++) {
|
||||
blkdiff -= blkno;
|
||||
blkdiff -= xlt_blkno;
|
||||
if (blkdiff < 0)
|
||||
continue;
|
||||
if (blkdiff == 0) {
|
||||
/* Replace current block of transfer. */
|
||||
blkno =
|
||||
lp->d_secperunit - lp->d_nsectors - i - 1;
|
||||
xlt_blkno = lp->d_secperunit -
|
||||
lp->d_nsectors - i - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1484,40 +1511,28 @@ wddump(dev)
|
|||
}
|
||||
|
||||
if ((wd->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
|
||||
sector = (blkno >> 0) & 0xff;
|
||||
cylin = (blkno >> 8) & 0xffff;
|
||||
head = (blkno >> 24) & 0xf;
|
||||
sector = (xlt_blkno >> 0) & 0xff;
|
||||
cylin = (xlt_blkno >> 8) & 0xffff;
|
||||
head = (xlt_blkno >> 24) & 0xf;
|
||||
head |= WDSD_LBA;
|
||||
} else {
|
||||
sector = blkno % lp->d_nsectors;
|
||||
sector = xlt_blkno % lp->d_nsectors;
|
||||
sector++; /* Sectors begin with 1, not 0. */
|
||||
blkno /= lp->d_nsectors;
|
||||
head = blkno % lp->d_ntracks;
|
||||
blkno /= lp->d_ntracks;
|
||||
cylin = blkno;
|
||||
xlt_blkno /= lp->d_nsectors;
|
||||
head = xlt_blkno % lp->d_ntracks;
|
||||
xlt_blkno /= lp->d_ntracks;
|
||||
cylin = xlt_blkno;
|
||||
head |= WDSD_CHS;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/* Let's just talk about this first. */
|
||||
printf("cylin %d, head %d, sector %d, addr 0x%x", cylin, head,
|
||||
sector, addr);
|
||||
#endif
|
||||
|
||||
#ifndef WD_DUMP_NOT_TRUSTED
|
||||
if (wdcommand(wd, WDCC_WRITE, cylin, head, sector, 1) != 0 ||
|
||||
wait_for_drq(wdc) != 0) {
|
||||
wderror(wd, NULL, "wddump: write failed");
|
||||
return EIO;
|
||||
}
|
||||
|
||||
#ifdef notdef /* Cannot use this since this address was mapped differently. */
|
||||
pmap_enter(pmap_kernel(), CADDR1, trunc_page(addr), VM_PROT_READ, TRUE);
|
||||
#else
|
||||
*CMAP1 = PG_V | PG_KW | ctob((long)addr);
|
||||
tlbflush();
|
||||
#endif
|
||||
|
||||
outsw(wdc->sc_iobase+wd_data, CADDR1 + ((int)addr & PGOFSET),
|
||||
DEV_BSIZE / sizeof(short));
|
||||
outsw(wdc->sc_iobase+wd_data, va, sectorsize / sizeof(short));
|
||||
|
||||
/* Check data request (should be done). */
|
||||
if (wait_for_ready(wdc) != 0) {
|
||||
|
@ -1528,18 +1543,34 @@ wddump(dev)
|
|||
wderror(wd, NULL, "wddump: extra drq");
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if ((unsigned)addr % 1048576 == 0)
|
||||
printf("%d ", nblks / (1048576 / DEV_BSIZE));
|
||||
#else /* WD_DUMP_NOT_TRUSTED */
|
||||
/* Let's just talk about this first... */
|
||||
printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
|
||||
unit, va, cylin, head, sector);
|
||||
delay(500 * 1000); /* half a second */
|
||||
#endif
|
||||
|
||||
/* Update block count. */
|
||||
nblks--;
|
||||
rblkno++;
|
||||
(int)addr += DEV_BSIZE;
|
||||
/* update block count */
|
||||
totwrt -= nwrt;
|
||||
blkno += nwrt;
|
||||
va += sectorsize * nwrt;
|
||||
}
|
||||
|
||||
wddoingadump = 0;
|
||||
return 0;
|
||||
}
|
||||
#else /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
int
|
||||
wddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
|
||||
/* Not implemented. */
|
||||
return ENXIO;
|
||||
}
|
||||
#endif /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
|
||||
/*
|
||||
* Internalize the bad sector table.
|
||||
|
|
181
sys/dev/isa/wd.c
181
sys/dev/isa/wd.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wd.c,v 1.139 1995/04/17 12:09:31 cgd Exp $ */
|
||||
/* $NetBSD: wd.c,v 1.140 1995/06/26 05:18:28 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||
|
@ -1407,76 +1407,103 @@ wdsize(dev)
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __BDEVSW_DUMP_OLD_TYPE
|
||||
/* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
|
||||
static int wddoingadump;
|
||||
static int wddumprecalibrated;
|
||||
|
||||
/*
|
||||
* Dump core after a system crash.
|
||||
*/
|
||||
int
|
||||
wddump(dev)
|
||||
dev_t dev;
|
||||
wddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
struct wd_softc *wd; /* disk unit to do the IO */
|
||||
struct wdc_softc *wdc;
|
||||
struct disklabel *lp;
|
||||
int unit, part;
|
||||
long rblkno, nblks;
|
||||
char *addr;
|
||||
static wddoingadump = 0;
|
||||
extern caddr_t CADDR1;
|
||||
extern pt_entry_t *CMAP1;
|
||||
|
||||
struct wd_softc *wd; /* disk unit to do the I/O */
|
||||
struct wdc_softc *wdc; /* disk controller to do the I/O */
|
||||
struct disklabel *lp; /* disk's disklabel */
|
||||
int unit, part;
|
||||
int sectorsize; /* size of a disk sector */
|
||||
int nsects; /* number of sectors in partition */
|
||||
int sectoff; /* sector offset of partition */
|
||||
int totwrt; /* total number of sectors left to write */
|
||||
int nwrt; /* current number of sectors to write */
|
||||
int retval;
|
||||
|
||||
/* Check if recursive dump; if so, punt. */
|
||||
if (wddoingadump)
|
||||
return EFAULT;
|
||||
|
||||
/* Mark as active early. */
|
||||
wddoingadump = 1;
|
||||
|
||||
unit = WDUNIT(dev);
|
||||
/* Check for acceptable drive number. */
|
||||
if (unit >= wdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
wd = wdcd.cd_devs[unit];
|
||||
/* Was it ever initialized? */
|
||||
if (wd == 0 || wd->sc_state < OPEN)
|
||||
return ENXIO;
|
||||
|
||||
wdc = (void *)wd->sc_dev.dv_parent;
|
||||
addr = (char *)0; /* starting address */
|
||||
lp = &wd->sc_dk.dk_label;
|
||||
unit = WDUNIT(dev); /* decompose unit & partition */
|
||||
part = WDPART(dev);
|
||||
|
||||
/* Convert to disk sectors. */
|
||||
rblkno = lp->d_partitions[part].p_offset + dumplo;
|
||||
nblks = min(ctob(physmem) / lp->d_secsize,
|
||||
lp->d_partitions[part].p_size - dumplo);
|
||||
/* Check for acceptable drive number. */
|
||||
if (unit >= wdcd.cd_ndevs || (wd = wdcd.cd_devs[unit]) == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* Make sure it was initialized. */
|
||||
if (wd->sc_state < OPEN)
|
||||
return ENXIO;
|
||||
|
||||
/* Remember the controller device, and sanity check */
|
||||
if ((wdc = (void *)wd->sc_dev.dv_parent) == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* Convert to disk sectors. Request must be a multiple of size. */
|
||||
lp = &wd->sc_dk.dk_label;
|
||||
sectorsize = lp->d_secsize;
|
||||
if ((size % sectorsize) != 0)
|
||||
return EFAULT;
|
||||
totwrt = size / sectorsize;
|
||||
blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */
|
||||
|
||||
nsects = lp->d_partitions[part].p_size;
|
||||
sectoff = lp->d_partitions[part].p_offset;
|
||||
|
||||
/* Check transfer bounds against partition size. */
|
||||
if (dumplo < 0 || nblks <= 0)
|
||||
return EINVAL;
|
||||
if ((blkno < 0) || ((blkno + totwrt) > nsects))
|
||||
return EINVAL;
|
||||
|
||||
/* Recalibrate. */
|
||||
if (wdcommandshort(wdc, wd->sc_drive, WDCC_RECAL) != 0 ||
|
||||
wait_for_ready(wdc) != 0 || wdsetctlr(wd) != 0 ||
|
||||
wait_for_ready(wdc) != 0) {
|
||||
wderror(wd, NULL, "wddump: recal failed");
|
||||
return EIO;
|
||||
/* Offset block number to start of partition. */
|
||||
blkno += sectoff;
|
||||
|
||||
/* Recalibrate, if first dump transfer. */
|
||||
if (wddumprecalibrated == 0) {
|
||||
wddumprecalibrated = 1;
|
||||
if (wdcommandshort(wdc, wd->sc_drive, WDCC_RECAL) != 0 ||
|
||||
wait_for_ready(wdc) != 0 || wdsetctlr(wd) != 0 ||
|
||||
wait_for_ready(wdc) != 0) {
|
||||
wderror(wd, NULL, "wddump: recal failed");
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
while (nblks > 0) {
|
||||
long blkno;
|
||||
|
||||
while (totwrt > 0) {
|
||||
long cylin, head, sector;
|
||||
daddr_t xlt_blkno;
|
||||
|
||||
blkno = rblkno;
|
||||
nwrt = 1; /* ouch XXX */
|
||||
xlt_blkno = blkno;
|
||||
|
||||
if ((lp->d_flags & D_BADSECT) != 0) {
|
||||
long blkdiff;
|
||||
int i;
|
||||
|
||||
for (i = 0; (blkdiff = wd->sc_badsect[i]) != -1; i++) {
|
||||
blkdiff -= blkno;
|
||||
blkdiff -= xlt_blkno;
|
||||
if (blkdiff < 0)
|
||||
continue;
|
||||
if (blkdiff == 0) {
|
||||
/* Replace current block of transfer. */
|
||||
blkno =
|
||||
lp->d_secperunit - lp->d_nsectors - i - 1;
|
||||
xlt_blkno = lp->d_secperunit -
|
||||
lp->d_nsectors - i - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1484,40 +1511,28 @@ wddump(dev)
|
|||
}
|
||||
|
||||
if ((wd->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
|
||||
sector = (blkno >> 0) & 0xff;
|
||||
cylin = (blkno >> 8) & 0xffff;
|
||||
head = (blkno >> 24) & 0xf;
|
||||
sector = (xlt_blkno >> 0) & 0xff;
|
||||
cylin = (xlt_blkno >> 8) & 0xffff;
|
||||
head = (xlt_blkno >> 24) & 0xf;
|
||||
head |= WDSD_LBA;
|
||||
} else {
|
||||
sector = blkno % lp->d_nsectors;
|
||||
sector = xlt_blkno % lp->d_nsectors;
|
||||
sector++; /* Sectors begin with 1, not 0. */
|
||||
blkno /= lp->d_nsectors;
|
||||
head = blkno % lp->d_ntracks;
|
||||
blkno /= lp->d_ntracks;
|
||||
cylin = blkno;
|
||||
xlt_blkno /= lp->d_nsectors;
|
||||
head = xlt_blkno % lp->d_ntracks;
|
||||
xlt_blkno /= lp->d_ntracks;
|
||||
cylin = xlt_blkno;
|
||||
head |= WDSD_CHS;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/* Let's just talk about this first. */
|
||||
printf("cylin %d, head %d, sector %d, addr 0x%x", cylin, head,
|
||||
sector, addr);
|
||||
#endif
|
||||
|
||||
#ifndef WD_DUMP_NOT_TRUSTED
|
||||
if (wdcommand(wd, WDCC_WRITE, cylin, head, sector, 1) != 0 ||
|
||||
wait_for_drq(wdc) != 0) {
|
||||
wderror(wd, NULL, "wddump: write failed");
|
||||
return EIO;
|
||||
}
|
||||
|
||||
#ifdef notdef /* Cannot use this since this address was mapped differently. */
|
||||
pmap_enter(pmap_kernel(), CADDR1, trunc_page(addr), VM_PROT_READ, TRUE);
|
||||
#else
|
||||
*CMAP1 = PG_V | PG_KW | ctob((long)addr);
|
||||
tlbflush();
|
||||
#endif
|
||||
|
||||
outsw(wdc->sc_iobase+wd_data, CADDR1 + ((int)addr & PGOFSET),
|
||||
DEV_BSIZE / sizeof(short));
|
||||
outsw(wdc->sc_iobase+wd_data, va, sectorsize / sizeof(short));
|
||||
|
||||
/* Check data request (should be done). */
|
||||
if (wait_for_ready(wdc) != 0) {
|
||||
|
@ -1528,18 +1543,34 @@ wddump(dev)
|
|||
wderror(wd, NULL, "wddump: extra drq");
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if ((unsigned)addr % 1048576 == 0)
|
||||
printf("%d ", nblks / (1048576 / DEV_BSIZE));
|
||||
#else /* WD_DUMP_NOT_TRUSTED */
|
||||
/* Let's just talk about this first... */
|
||||
printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
|
||||
unit, va, cylin, head, sector);
|
||||
delay(500 * 1000); /* half a second */
|
||||
#endif
|
||||
|
||||
/* Update block count. */
|
||||
nblks--;
|
||||
rblkno++;
|
||||
(int)addr += DEV_BSIZE;
|
||||
/* update block count */
|
||||
totwrt -= nwrt;
|
||||
blkno += nwrt;
|
||||
va += sectorsize * nwrt;
|
||||
}
|
||||
|
||||
wddoingadump = 0;
|
||||
return 0;
|
||||
}
|
||||
#else /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
int
|
||||
wddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
|
||||
/* Not implemented. */
|
||||
return ENXIO;
|
||||
}
|
||||
#endif /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
|
||||
/*
|
||||
* Internalize the bad sector table.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sd.c,v 1.70 1995/05/03 21:38:57 cgd Exp $ */
|
||||
/* $NetBSD: sd.c,v 1.71 1995/06/26 05:16:55 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||
|
@ -858,82 +858,75 @@ sdsize(dev)
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
#define SCSIDUMP 1
|
||||
#undef SCSIDUMP
|
||||
#define NOT_TRUSTED 1
|
||||
|
||||
#ifdef SCSIDUMP
|
||||
#include <vm/vm.h>
|
||||
|
||||
#ifndef __BDEVSW_DUMP_OLD_TYPE
|
||||
/* #define SD_DUMP_NOT_TRUSTED if you just want to watch */
|
||||
static struct scsi_xfer sx;
|
||||
#define MAXTRANSFER 8 /* 1 page at a time */
|
||||
static int sddoingadump;
|
||||
|
||||
/*
|
||||
* dump all of physical memory into the partition specified, starting
|
||||
* at offset 'dumplo' into the partition.
|
||||
*/
|
||||
int
|
||||
sddump(dev_t dev)
|
||||
{ /* dump core after a system crash */
|
||||
register struct sd_softc *sd; /* disk unit to do the IO */
|
||||
int32 num; /* number of sectors to write */
|
||||
u_int32 unit, part;
|
||||
int32 blkoff, blkno, nblks = MAXTRANSFER;
|
||||
int32 nblocks;
|
||||
char *addr;
|
||||
struct scsi_rw_big cmd;
|
||||
extern int Maxmem;
|
||||
static int sddoingadump = 0;
|
||||
#define MAPTO CADDR1
|
||||
extern caddr_t MAPTO; /* map the page we are about to write, here */
|
||||
struct scsi_xfer *xs = &sx;
|
||||
sddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
struct sd_softc *sd; /* disk unit to do the I/O */
|
||||
struct disklabel *lp; /* disk's disklabel */
|
||||
int unit, part;
|
||||
int sectorsize; /* size of a disk sector */
|
||||
int nsects; /* number of sectors in partition */
|
||||
int sectoff; /* sector offset of partition */
|
||||
int totwrt; /* total number of sectors left to write */
|
||||
int nwrt; /* current number of sectors to write */
|
||||
struct scsi_rw_big cmd; /* write command */
|
||||
struct scsi_xfer *xs; /* ... convenience */
|
||||
int retval;
|
||||
int c;
|
||||
|
||||
addr = (char *) 0; /* starting address */
|
||||
|
||||
/* toss any characters present prior to dump */
|
||||
while ((c = sgetc(1)) && (c != 0x100)); /*syscons and pccons differ */
|
||||
|
||||
/* size of memory to dump */
|
||||
num = Maxmem;
|
||||
unit = SDUNIT(dev); /* eventually support floppies? */
|
||||
part = SDPART(dev); /* file system */
|
||||
/* check for acceptable drive number */
|
||||
if (unit >= sdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
|
||||
sd = sd_softc[unit];
|
||||
if (!sd)
|
||||
return ENXIO;
|
||||
if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED)
|
||||
return ENXIO;
|
||||
|
||||
/* Convert to disk sectors */
|
||||
num = (u_int32)num * NBPG / sd->sc_dk.dk_label.d_secsize;
|
||||
|
||||
/* check if controller active */
|
||||
/* Check if recursive dump; if so, punt. */
|
||||
if (sddoingadump)
|
||||
return EFAULT;
|
||||
|
||||
nblocks = sd->sc_dk.dk_label.d_partitions[part].p_size;
|
||||
blkoff = sd->sc_dk.dk_label.d_partitions[part].p_offset;
|
||||
|
||||
/* check transfer bounds against partition size */
|
||||
if ((dumplo < 0) || ((dumplo + num) > nblocks))
|
||||
return EINVAL;
|
||||
|
||||
/* Mark as active early. */
|
||||
sddoingadump = 1;
|
||||
|
||||
blkno = dumplo + blkoff;
|
||||
while (num > 0) {
|
||||
pmap_enter(pmap_kernel(),
|
||||
MAPTO,
|
||||
trunc_page(addr),
|
||||
VM_PROT_READ,
|
||||
TRUE);
|
||||
#ifndef NOT_TRUSTED
|
||||
unit = SDUNIT(dev); /* Decompose unit & partition. */
|
||||
part = SDPART(dev);
|
||||
|
||||
/* Check for acceptable drive number. */
|
||||
if (unit >= sdcd.cd_ndevs || (sd = sdcd.cd_devs[unit]) == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* Make sure it was initialized. */
|
||||
if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED)
|
||||
return ENXIO;
|
||||
|
||||
/* Convert to disk sectors. Request must be a multiple of size. */
|
||||
lp = &sd->sc_dk.dk_label;
|
||||
sectorsize = lp->d_secsize;
|
||||
if ((size % sectorsize) != 0)
|
||||
return EFAULT;
|
||||
totwrt = size / sectorsize;
|
||||
blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */
|
||||
|
||||
nsects = lp->d_partitions[part].p_size;
|
||||
sectoff = lp->d_partitions[part].p_offset;
|
||||
|
||||
/* Check transfer bounds against partition size. */
|
||||
if ((blkno < 0) || ((blkno + totwrt) > nsects))
|
||||
return EINVAL;
|
||||
|
||||
/* Offset block number to start of partition. */
|
||||
blkno += sectoff;
|
||||
|
||||
xs = &sx;
|
||||
|
||||
while (totwrt > 0) {
|
||||
nwrt = totwrt; /* XXX */
|
||||
#ifndef SD_DUMP_NOT_TRUSTED
|
||||
/*
|
||||
* Fill out the scsi command
|
||||
*/
|
||||
|
@ -943,8 +936,8 @@ sddump(dev_t dev)
|
|||
cmd.addr_2 = (blkno >> 16) & 0xff;
|
||||
cmd.addr_1 = (blkno >> 8) & 0xff;
|
||||
cmd.addr_0 = blkno & 0xff;
|
||||
cmd.length2 = (nblks >> 8) & 0xff;
|
||||
cmd.length1 = nblks & 0xff;
|
||||
cmd.length2 = (nwrt >> 8) & 0xff;
|
||||
cmd.length1 = nwrt & 0xff;
|
||||
/*
|
||||
* Fill out the scsi_xfer structure
|
||||
* Note: we cannot sleep as we may be an interrupt
|
||||
|
@ -958,11 +951,11 @@ sddump(dev_t dev)
|
|||
xs->timeout = 10000; /* 10000 millisecs for a disk ! */
|
||||
xs->cmd = (struct scsi_generic *)&cmd;
|
||||
xs->cmdlen = sizeof(cmd);
|
||||
xs->resid = nblks * 512;
|
||||
xs->resid = nwrt * sectorsize;
|
||||
xs->error = XS_NOERROR;
|
||||
xs->bp = 0;
|
||||
xs->data = (u_char *) MAPTO;
|
||||
xs->datalen = nblks * 512;
|
||||
xs->data = va;
|
||||
xs->datalen = nwrt * sectorsize;
|
||||
|
||||
/*
|
||||
* Pass all this info to the scsi driver.
|
||||
|
@ -970,30 +963,30 @@ sddump(dev_t dev)
|
|||
retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs);
|
||||
if (retval != COMPLETE)
|
||||
return ENXIO;
|
||||
#else /* NOT_TRUSTED */
|
||||
/* lets just talk about this first... */
|
||||
printf("sd%d: dump addr 0x%x, blk %d\n", unit, addr, blkno);
|
||||
#endif /* NOT_TRUSTED */
|
||||
#else /* SD_DUMP_NOT_TRUSTED */
|
||||
/* Let's just talk about this first... */
|
||||
printf("sd%d: dump addr 0x%x, blk %d\n", unit, va, blkno);
|
||||
delay(500 * 1000); /* half a second */
|
||||
#endif /* SD_DUMP_NOT_TRUSTED */
|
||||
|
||||
if ((unsigned)addr % (1024 * 1024) == 0)
|
||||
printf("%d ", num / 2048);
|
||||
/* update block count */
|
||||
num -= nblks;
|
||||
blkno += nblks;
|
||||
(int)addr += 512 * nblks;
|
||||
|
||||
/* operator aborting dump? */
|
||||
if ((c = sgetc(1)) && (c != 0x100))
|
||||
return EINTR;
|
||||
totwrt -= nwrt;
|
||||
blkno += nwrt;
|
||||
va += sectorsize * nwrt;
|
||||
}
|
||||
sddoingadump = 0;
|
||||
return 0;
|
||||
}
|
||||
#else /* SCSIDUMP */
|
||||
#else /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
int
|
||||
sddump()
|
||||
sddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
printf("\nsddump() -- not implemented\n");
|
||||
delay(6000000); /* 6 seconds */
|
||||
return -1;
|
||||
|
||||
/* Not implemented. */
|
||||
return ENXIO;
|
||||
}
|
||||
#endif /* SCSIDUMP */
|
||||
#endif /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
|
|
167
sys/scsi/sd.c
167
sys/scsi/sd.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sd.c,v 1.70 1995/05/03 21:38:57 cgd Exp $ */
|
||||
/* $NetBSD: sd.c,v 1.71 1995/06/26 05:16:55 cgd Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
|
||||
|
@ -858,82 +858,75 @@ sdsize(dev)
|
|||
return size;
|
||||
}
|
||||
|
||||
|
||||
#define SCSIDUMP 1
|
||||
#undef SCSIDUMP
|
||||
#define NOT_TRUSTED 1
|
||||
|
||||
#ifdef SCSIDUMP
|
||||
#include <vm/vm.h>
|
||||
|
||||
#ifndef __BDEVSW_DUMP_OLD_TYPE
|
||||
/* #define SD_DUMP_NOT_TRUSTED if you just want to watch */
|
||||
static struct scsi_xfer sx;
|
||||
#define MAXTRANSFER 8 /* 1 page at a time */
|
||||
static int sddoingadump;
|
||||
|
||||
/*
|
||||
* dump all of physical memory into the partition specified, starting
|
||||
* at offset 'dumplo' into the partition.
|
||||
*/
|
||||
int
|
||||
sddump(dev_t dev)
|
||||
{ /* dump core after a system crash */
|
||||
register struct sd_softc *sd; /* disk unit to do the IO */
|
||||
int32 num; /* number of sectors to write */
|
||||
u_int32 unit, part;
|
||||
int32 blkoff, blkno, nblks = MAXTRANSFER;
|
||||
int32 nblocks;
|
||||
char *addr;
|
||||
struct scsi_rw_big cmd;
|
||||
extern int Maxmem;
|
||||
static int sddoingadump = 0;
|
||||
#define MAPTO CADDR1
|
||||
extern caddr_t MAPTO; /* map the page we are about to write, here */
|
||||
struct scsi_xfer *xs = &sx;
|
||||
sddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
struct sd_softc *sd; /* disk unit to do the I/O */
|
||||
struct disklabel *lp; /* disk's disklabel */
|
||||
int unit, part;
|
||||
int sectorsize; /* size of a disk sector */
|
||||
int nsects; /* number of sectors in partition */
|
||||
int sectoff; /* sector offset of partition */
|
||||
int totwrt; /* total number of sectors left to write */
|
||||
int nwrt; /* current number of sectors to write */
|
||||
struct scsi_rw_big cmd; /* write command */
|
||||
struct scsi_xfer *xs; /* ... convenience */
|
||||
int retval;
|
||||
int c;
|
||||
|
||||
addr = (char *) 0; /* starting address */
|
||||
|
||||
/* toss any characters present prior to dump */
|
||||
while ((c = sgetc(1)) && (c != 0x100)); /*syscons and pccons differ */
|
||||
|
||||
/* size of memory to dump */
|
||||
num = Maxmem;
|
||||
unit = SDUNIT(dev); /* eventually support floppies? */
|
||||
part = SDPART(dev); /* file system */
|
||||
/* check for acceptable drive number */
|
||||
if (unit >= sdcd.cd_ndevs)
|
||||
return ENXIO;
|
||||
|
||||
sd = sd_softc[unit];
|
||||
if (!sd)
|
||||
return ENXIO;
|
||||
if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED)
|
||||
return ENXIO;
|
||||
|
||||
/* Convert to disk sectors */
|
||||
num = (u_int32)num * NBPG / sd->sc_dk.dk_label.d_secsize;
|
||||
|
||||
/* check if controller active */
|
||||
/* Check if recursive dump; if so, punt. */
|
||||
if (sddoingadump)
|
||||
return EFAULT;
|
||||
|
||||
nblocks = sd->sc_dk.dk_label.d_partitions[part].p_size;
|
||||
blkoff = sd->sc_dk.dk_label.d_partitions[part].p_offset;
|
||||
|
||||
/* check transfer bounds against partition size */
|
||||
if ((dumplo < 0) || ((dumplo + num) > nblocks))
|
||||
return EINVAL;
|
||||
|
||||
/* Mark as active early. */
|
||||
sddoingadump = 1;
|
||||
|
||||
blkno = dumplo + blkoff;
|
||||
while (num > 0) {
|
||||
pmap_enter(pmap_kernel(),
|
||||
MAPTO,
|
||||
trunc_page(addr),
|
||||
VM_PROT_READ,
|
||||
TRUE);
|
||||
#ifndef NOT_TRUSTED
|
||||
unit = SDUNIT(dev); /* Decompose unit & partition. */
|
||||
part = SDPART(dev);
|
||||
|
||||
/* Check for acceptable drive number. */
|
||||
if (unit >= sdcd.cd_ndevs || (sd = sdcd.cd_devs[unit]) == NULL)
|
||||
return ENXIO;
|
||||
|
||||
/* Make sure it was initialized. */
|
||||
if (sd->sc_link->flags & SDEV_MEDIA_LOADED != SDEV_MEDIA_LOADED)
|
||||
return ENXIO;
|
||||
|
||||
/* Convert to disk sectors. Request must be a multiple of size. */
|
||||
lp = &sd->sc_dk.dk_label;
|
||||
sectorsize = lp->d_secsize;
|
||||
if ((size % sectorsize) != 0)
|
||||
return EFAULT;
|
||||
totwrt = size / sectorsize;
|
||||
blkno = dbtob(blkno) / sectorsize; /* blkno in DEV_BSIZE units */
|
||||
|
||||
nsects = lp->d_partitions[part].p_size;
|
||||
sectoff = lp->d_partitions[part].p_offset;
|
||||
|
||||
/* Check transfer bounds against partition size. */
|
||||
if ((blkno < 0) || ((blkno + totwrt) > nsects))
|
||||
return EINVAL;
|
||||
|
||||
/* Offset block number to start of partition. */
|
||||
blkno += sectoff;
|
||||
|
||||
xs = &sx;
|
||||
|
||||
while (totwrt > 0) {
|
||||
nwrt = totwrt; /* XXX */
|
||||
#ifndef SD_DUMP_NOT_TRUSTED
|
||||
/*
|
||||
* Fill out the scsi command
|
||||
*/
|
||||
|
@ -943,8 +936,8 @@ sddump(dev_t dev)
|
|||
cmd.addr_2 = (blkno >> 16) & 0xff;
|
||||
cmd.addr_1 = (blkno >> 8) & 0xff;
|
||||
cmd.addr_0 = blkno & 0xff;
|
||||
cmd.length2 = (nblks >> 8) & 0xff;
|
||||
cmd.length1 = nblks & 0xff;
|
||||
cmd.length2 = (nwrt >> 8) & 0xff;
|
||||
cmd.length1 = nwrt & 0xff;
|
||||
/*
|
||||
* Fill out the scsi_xfer structure
|
||||
* Note: we cannot sleep as we may be an interrupt
|
||||
|
@ -958,11 +951,11 @@ sddump(dev_t dev)
|
|||
xs->timeout = 10000; /* 10000 millisecs for a disk ! */
|
||||
xs->cmd = (struct scsi_generic *)&cmd;
|
||||
xs->cmdlen = sizeof(cmd);
|
||||
xs->resid = nblks * 512;
|
||||
xs->resid = nwrt * sectorsize;
|
||||
xs->error = XS_NOERROR;
|
||||
xs->bp = 0;
|
||||
xs->data = (u_char *) MAPTO;
|
||||
xs->datalen = nblks * 512;
|
||||
xs->data = va;
|
||||
xs->datalen = nwrt * sectorsize;
|
||||
|
||||
/*
|
||||
* Pass all this info to the scsi driver.
|
||||
|
@ -970,30 +963,30 @@ sddump(dev_t dev)
|
|||
retval = (*(sd->sc_link->adapter->scsi_cmd)) (xs);
|
||||
if (retval != COMPLETE)
|
||||
return ENXIO;
|
||||
#else /* NOT_TRUSTED */
|
||||
/* lets just talk about this first... */
|
||||
printf("sd%d: dump addr 0x%x, blk %d\n", unit, addr, blkno);
|
||||
#endif /* NOT_TRUSTED */
|
||||
#else /* SD_DUMP_NOT_TRUSTED */
|
||||
/* Let's just talk about this first... */
|
||||
printf("sd%d: dump addr 0x%x, blk %d\n", unit, va, blkno);
|
||||
delay(500 * 1000); /* half a second */
|
||||
#endif /* SD_DUMP_NOT_TRUSTED */
|
||||
|
||||
if ((unsigned)addr % (1024 * 1024) == 0)
|
||||
printf("%d ", num / 2048);
|
||||
/* update block count */
|
||||
num -= nblks;
|
||||
blkno += nblks;
|
||||
(int)addr += 512 * nblks;
|
||||
|
||||
/* operator aborting dump? */
|
||||
if ((c = sgetc(1)) && (c != 0x100))
|
||||
return EINTR;
|
||||
totwrt -= nwrt;
|
||||
blkno += nwrt;
|
||||
va += sectorsize * nwrt;
|
||||
}
|
||||
sddoingadump = 0;
|
||||
return 0;
|
||||
}
|
||||
#else /* SCSIDUMP */
|
||||
#else /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
int
|
||||
sddump()
|
||||
sddump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
printf("\nsddump() -- not implemented\n");
|
||||
delay(6000000); /* 6 seconds */
|
||||
return -1;
|
||||
|
||||
/* Not implemented. */
|
||||
return ENXIO;
|
||||
}
|
||||
#endif /* SCSIDUMP */
|
||||
#endif /* __BDEVSW_DUMP_NEW_TYPE */
|
||||
|
|
Loading…
Reference in New Issue