* Copyright (c) 1992, 1991 Carnegie Mellon University
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
* Carnegie Mellon requests users of this software to return to
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
* from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
#include <sys/disklabel.h>
#define BIOS_DEV_FLOPPY 0x0
#define BIOS_DEV_WIN 0x80
#define SPT(di) ((di)&0xff)
#define HEADS(di) ((((di)>>8)&0xff)+1)
char *devs
[] = {"wd", "hd", "fd", "wt", "sd", 0};
int dosdev
, unit
, part
, maj
, boff
, poff
, bnum
, cnt
;
/*#define EMBEDDED_DISKLABEL 1*/
extern struct disklabel disklabel
;
/*struct disklabel disklabel;*/
struct dos_partition
*dptr
;
int dosdev
= inode
.i_dev
;
di
= get_diskinfo(dosdev
);
spc
= (spt
= SPT(di
)) * HEADS(di
);
part
= (spt
== 15 ? 3 : 1);
#ifdef EMBEDDED_DISKLABEL
dptr
= (struct dos_partition
*)(((char *)0)+DOSPARTOFF
);
for (i
= 0; i
< NDOSPART
; i
++, dptr
++)
if (dptr
->dp_typ
== DOSPTYP_386BSD
)
sector
= dptr
->dp_start
+ LABELSECTOR
;
dl
=((struct disklabel
*)0);
disklabel
= *dl
; /* structure copy (maybe useful later)*/
#endif EMBEDDED_DISKLABEL
if (dl
->d_magic
!= DISKMAGIC
) {
if( (maj
== 4) || (maj
== 0) || (maj
== 1))
if (dl
->d_type
== DTYPE_SCSI
)
maj
= 4; /* use scsi as boot dev */
maj
= 0; /* must be ESDI/IDE */
boff
= dl
->d_partitions
[part
].p_offset
;
bsize
= dl
->d_partitions
[part
].p_size
;
if (dl
->d_flags
& D_BADSECT
) {
/* this disk uses bad144 */
/* find the first readable bad144 sector */
/* some of this code is copied from ufs/disk_subr.c */
/* read a bad sector table */
dkbbnum
= dl
->d_secperunit
- dl
->d_nsectors
;
if (dl
->d_secsize
> DEV_BSIZE
)
dkbbnum
*= dl
->d_secsize
/ DEV_BSIZE
;
dkbbnum
/= DEV_BSIZE
/ dl
->d_secsize
;
/* XXX: what if the "DOS sector" < 512 bytes ??? */
Bread(dosdev
, dkbbnum
+ i
);
dkbptr
= (struct dkbad
*) 0;
/* XXX why is this not in <sys/dkbad.h> ??? */
#define DKBAD_MAGIC 0x4321
if (dkbptr
->bt_mbz
== 0 &&
dkbptr
->bt_flag
== DKBAD_MAGIC
) {
dkb
= *dkbptr
; /* structure copy */
} while (i
< 10 && i
< dl
->d_nsectors
);
printf("Bad badsect table\n");
printf("Using bad144 bad sector at %d\n", dkbbnum
+i
);
int offset
, sector
= bnum
;
int dosdev
= inode
.i_dev
;
for (offset
= 0; offset
< cnt
; offset
+= BPS
)
Bread(dosdev
, badsect(dosdev
, sector
++));
bcopy(0, iodest
+offset
, BPS
);
#define I_ADDR ((void *) 0) /* XXX where all reads go */
/* Read ahead buffer large enough for one track on a 1440K floppy. For
* reading from floppies, the bootstrap has to be loaded on a 64K boundary
* to ensure that this buffer doesn't cross a 64K DMA boundary.
static char ra_buf
[RA_SECTORS
* BPS
];
if (sector
< ra_first
|| sector
>= ra_end
)
int cyl
, head
, sec
, nsec
;
head
= (sector
% spc
) / spt
;
if (biosread(dosdev
, cyl
, head
, sec
, nsec
, ra_buf
) != 0)
while (biosread(dosdev
, cyl
, head
, sec
, nsec
, ra_buf
) != 0) {
printf("Error: C:%d H:%d S:%d\n", cyl
, head
, sec
);
bcopy(ra_buf
+ (sector
- ra_first
) * BPS
, I_ADDR
, BPS
);
struct disklabel
*dl
= &disklabel
;
/* bt_cyl = cylinder number in sorted order */
/* bt_trksec is actually (head << 8) + sec */
/* only remap sectors in the partition */
if (sector
< boff
|| sector
>= boff
+ bsize
) {
cyl
= sector
/ dl
->d_secpercyl
;
head
= (sector
% dl
->d_secpercyl
) / dl
->d_nsectors
;
sec
= sector
% dl
->d_nsectors
;
/* now, look in the table for a possible bad sector */
if (dkb
.bt_bad
[i
].bt_cyl
== cyl
) {
/* found same cylinder */
if (dkb
.bt_bad
[i
].bt_trksec
== sec
) {
} else if (dkb
.bt_bad
[i
].bt_cyl
> cyl
) {
/* didn't find bad sector */
/* otherwise find replacement sector */
newsec
= dl
->d_secperunit
- dl
->d_nsectors
- i
-1;