1994-12-12 00:20:34 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 1994 Bruce D. Evans.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Copyright (c) 1990 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to Berkeley by
|
|
|
|
* William Jolitz.
|
|
|
|
*
|
|
|
|
* Copyright (c) 1982, 1986, 1988 Regents of the University of California.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
* California, Berkeley and its contributors.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
|
|
|
|
* from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $
|
|
|
|
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
|
|
|
|
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
|
1999-06-26 02:47:16 +00:00
|
|
|
* $Id: subr_dkbad.c,v 1.9 1999/05/11 19:54:31 phk Exp $
|
1994-12-12 00:20:34 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
Divorce "dev_t" from the "major|minor" bitmap, which is now called
udev_t in the kernel but still called dev_t in userland.
Provide functions to manipulate both types:
major() umajor()
minor() uminor()
makedev() umakedev()
dev2udev() udev2dev()
For now they're functions, they will become in-line functions
after one of the next two steps in this process.
Return major/minor/makedev to macro-hood for userland.
Register a name in cdevsw[] for the "filedescriptor" driver.
In the kernel the udev_t appears in places where we have the
major/minor number combination, (ie: a potential device: we
may not have the driver nor the device), like in inodes, vattr,
cdevsw registration and so on, whereas the dev_t appears where
we carry around a reference to a actual device.
In the future the cdevsw and the aliased-from vnode will be hung
directly from the dev_t, along with up to two softc pointers for
the device driver and a few houskeeping bits. This will essentially
replace the current "alias" check code (same buck, bigger bang).
A little stunt has been provided to try to catch places where the
wrong type is being used (dev_t vs udev_t), if you see something
not working, #undef DEVT_FASCIST in kern/kern_conf.c and see if
it makes a difference. If it does, please try to track it down
(many hands make light work) or at least try to reproduce it
as simply as possible, and describe how to do that.
Without DEVT_FASCIST I belive this patch is a no-op.
Stylistic/posixoid comments about the userland view of the <sys/*.h>
files welcome now, from userland they now contain the end result.
Next planned step: make all dev_t's refer to the same devsw[] which
means convert BLK's to CHR's at the perimeter of the vnodes and
other places where they enter the game (bootdev, mknod, sysctl).
1999-05-11 19:55:07 +00:00
|
|
|
#include <sys/systm.h>
|
1994-12-12 00:20:34 +00:00
|
|
|
#include <sys/buf.h>
|
1996-09-20 17:39:44 +00:00
|
|
|
#include <sys/conf.h>
|
1994-12-12 00:20:34 +00:00
|
|
|
#include <sys/disklabel.h>
|
|
|
|
#include <sys/dkbad.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Internalize the bad sector table.
|
|
|
|
* TODO:
|
|
|
|
* o Fix types.
|
|
|
|
* Type long should be daddr_t since we compare with blkno's.
|
|
|
|
* Sentinel -1 should be ((daddr_t)-1).
|
|
|
|
* o Can remove explicit test for sentinel if it is a positive
|
|
|
|
* (unsigned or not) value larger than all possible blkno's.
|
|
|
|
* o Check that the table is sorted.
|
|
|
|
* o Use faster searches.
|
|
|
|
* o Use the internal table in wddump().
|
|
|
|
* o Don't duplicate so much code.
|
|
|
|
* o Do all bad block handing in a driver-independent file.
|
|
|
|
* o Remove limit of 126 spare sectors.
|
|
|
|
*/
|
|
|
|
struct dkbad_intern *
|
|
|
|
internbad144(btp, lp)
|
|
|
|
struct dkbad *btp;
|
|
|
|
struct disklabel *lp;
|
|
|
|
{
|
|
|
|
struct dkbad_intern *bip;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
bip = malloc(sizeof *bip, M_DEVBUF, M_WAITOK);
|
|
|
|
/*
|
|
|
|
* Spare sectors are allocated beginning with the last sector of
|
|
|
|
* the second last track of the disk (the last track is used for
|
|
|
|
* the bad sector list).
|
|
|
|
*/
|
|
|
|
bip->bi_maxspare = lp->d_secperunit - lp->d_nsectors - 1;
|
|
|
|
bip->bi_nbad = DKBAD_MAXBAD;
|
|
|
|
i = 0;
|
|
|
|
for (; i < DKBAD_MAXBAD && btp->bt_bad[i].bt_cyl != DKBAD_NOCYL; i++)
|
|
|
|
bip->bi_bad[i] = btp->bt_bad[i].bt_cyl * lp->d_secpercyl
|
|
|
|
+ (btp->bt_bad[i].bt_trksec >> 8)
|
|
|
|
* lp->d_nsectors
|
|
|
|
+ (btp->bt_bad[i].bt_trksec & 0x00ff);
|
|
|
|
bip->bi_bad[i] = -1;
|
|
|
|
return (bip);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
readbad144(dev, strat, lp, bdp)
|
|
|
|
dev_t dev;
|
|
|
|
d_strategy_t *strat;
|
|
|
|
struct disklabel *lp;
|
|
|
|
struct dkbad *bdp;
|
|
|
|
{
|
|
|
|
struct buf *bp;
|
|
|
|
struct dkbad *db;
|
|
|
|
int i;
|
|
|
|
char *msg;
|
|
|
|
|
|
|
|
bp = geteblk((int)lp->d_secsize);
|
|
|
|
i = 0;
|
|
|
|
do {
|
|
|
|
/* Read a bad sector table. */
|
|
|
|
bp->b_dev = dev;
|
|
|
|
bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i;
|
|
|
|
if (lp->d_secsize > DEV_BSIZE)
|
|
|
|
bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
|
|
|
|
else
|
|
|
|
bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
|
|
|
|
bp->b_bcount = lp->d_secsize;
|
1999-06-26 02:47:16 +00:00
|
|
|
bp->b_flags |= B_READ;
|
1997-11-24 04:14:21 +00:00
|
|
|
bp->b_flags &= ~B_ERROR;
|
1994-12-12 00:20:34 +00:00
|
|
|
(*strat)(bp);
|
|
|
|
|
|
|
|
/* If successful, validate, otherwise try another. */
|
|
|
|
if (biowait(bp) == 0) {
|
1997-12-02 21:07:20 +00:00
|
|
|
db = (struct dkbad *)(bp->b_data);
|
1994-12-12 00:20:34 +00:00
|
|
|
if (db->bt_mbz == 0 && db->bt_flag == DKBAD_MAGIC) {
|
|
|
|
msg = NULL;
|
|
|
|
*bdp = *db;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
msg = "bad sector table corrupted";
|
|
|
|
} else
|
|
|
|
msg = "bad sector table I/O error";
|
|
|
|
} while ((bp->b_flags & B_ERROR) && (i += 2) < 10 &&
|
|
|
|
i < lp->d_nsectors);
|
1996-03-01 19:01:04 +00:00
|
|
|
bp->b_flags |= B_INVAL | B_AGE;
|
1994-12-12 00:20:34 +00:00
|
|
|
brelse(bp);
|
|
|
|
return (msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
daddr_t
|
|
|
|
transbad144(bip, blkno)
|
|
|
|
struct dkbad_intern *bip;
|
|
|
|
daddr_t blkno;
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* List is sorted, so the search can terminate when it is past our
|
|
|
|
* sector.
|
|
|
|
*/
|
|
|
|
for (i = 0; bip->bi_bad[i] != -1 && bip->bi_bad[i] <= blkno; i++)
|
|
|
|
if (bip->bi_bad[i] == blkno)
|
|
|
|
/*
|
|
|
|
* Spare sectors are allocated in decreasing order.
|
|
|
|
*/
|
|
|
|
return (bip->bi_maxspare - i);
|
|
|
|
return (blkno);
|
|
|
|
}
|