|
|
1.1 ! root 1: /* ! 2: * Ported to boot 386BSD by Julian Elischer ([email protected]) Sept 1992 ! 3: * ! 4: * Mach Operating System ! 5: * Copyright (c) 1992, 1991 Carnegie Mellon University ! 6: * All Rights Reserved. ! 7: * ! 8: * Permission to use, copy, modify and distribute this software and its ! 9: * documentation is hereby granted, provided that both the copyright ! 10: * notice and this permission notice appear in all copies of the ! 11: * software, derivative works or modified versions, and any portions ! 12: * thereof, and that both notices appear in supporting documentation. ! 13: * ! 14: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 15: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 16: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 17: * ! 18: * Carnegie Mellon requests users of this software to return to ! 19: * ! 20: * Software Distribution Coordinator or [email protected] ! 21: * School of Computer Science ! 22: * Carnegie Mellon University ! 23: * Pittsburgh PA 15213-3890 ! 24: * ! 25: * any improvements or extensions that they make and grant Carnegie Mellon ! 26: * the rights to redistribute these changes. ! 27: */ ! 28: ! 29: /* ! 30: * HISTORY ! 31: * $Log: disk.c,v $ ! 32: * Revision 1.1 1993/03/21 18:08:36 cgd ! 33: * after 0.2.2 "stable" patches applied ! 34: * ! 35: * Revision 2.2 92/04/04 11:35:49 rpd ! 36: * Fabricated from 3.0 bootstrap and 2.5 boot disk.c: ! 37: * with support for scsi ! 38: * [92/03/30 mg32] ! 39: * ! 40: */ ! 41: ! 42: /* ! 43: * 9/20/92 ! 44: * Peng-Toh Sim. [email protected] ! 45: * Added bad144 support under 386bsd for wd's ! 46: * So, bad block remapping is done when loading the kernel. ! 47: */ ! 48: ! 49: #include "boot.h" ! 50: #ifdef DO_BAD144 ! 51: #include <sys/dkbad.h> ! 52: #endif DO_BAD144 ! 53: #include <sys/disklabel.h> ! 54: ! 55: #define BIOS_DEV_FLOPPY 0x0 ! 56: #define BIOS_DEV_WIN 0x80 ! 57: ! 58: #define BPS 512 ! 59: #define SPT(di) ((di)&0xff) ! 60: #define HEADS(di) ((((di)>>8)&0xff)+1) ! 61: ! 62: char *devs[] = {"wd", "hd", "fd", "wt", "sd", 0}; ! 63: ! 64: #ifdef DO_BAD144 ! 65: struct dkbad dkb; ! 66: int do_bad144; ! 67: int bsize; ! 68: #endif DO_BAD144 ! 69: ! 70: int spt, spc; ! 71: ! 72: char *iodest; ! 73: struct fs *fs; ! 74: struct inode inode; ! 75: int dosdev, unit, part, maj, boff, poff, bnum, cnt; ! 76: ! 77: /*#define EMBEDDED_DISKLABEL 1*/ ! 78: extern struct disklabel disklabel; ! 79: /*struct disklabel disklabel;*/ ! 80: ! 81: devopen() ! 82: { ! 83: struct dos_partition *dptr; ! 84: struct disklabel *dl; ! 85: int dosdev = inode.i_dev; ! 86: int i, sector, di; ! 87: ! 88: di = get_diskinfo(dosdev); ! 89: spc = (spt = SPT(di)) * HEADS(di); ! 90: if (dosdev == 2) ! 91: { ! 92: boff = 0; ! 93: part = (spt == 15 ? 3 : 1); ! 94: } ! 95: else ! 96: { ! 97: #ifdef EMBEDDED_DISKLABEL ! 98: dl = &disklabel; ! 99: #else EMBEDDED_DISKLABEL ! 100: Bread(dosdev, 0); ! 101: dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF); ! 102: for (i = 0; i < NDOSPART; i++, dptr++) ! 103: if (dptr->dp_typ == DOSPTYP_386BSD) ! 104: break; ! 105: sector = dptr->dp_start + LABELSECTOR; ! 106: Bread(dosdev, sector++); ! 107: dl=((struct disklabel *)0); ! 108: disklabel = *dl; /* structure copy (maybe useful later)*/ ! 109: #endif EMBEDDED_DISKLABEL ! 110: if (dl->d_magic != DISKMAGIC) { ! 111: printf("bad disklabel"); ! 112: return 1; ! 113: } ! 114: if( (maj == 4) || (maj == 0) || (maj == 1)) ! 115: { ! 116: if (dl->d_type == DTYPE_SCSI) ! 117: { ! 118: maj = 4; /* use scsi as boot dev */ ! 119: } ! 120: else ! 121: { ! 122: maj = 0; /* must be ESDI/IDE */ ! 123: } ! 124: } ! 125: boff = dl->d_partitions[part].p_offset; ! 126: #ifdef DO_BAD144 ! 127: bsize = dl->d_partitions[part].p_size; ! 128: do_bad144 = 0; ! 129: if (dl->d_flags & D_BADSECT) { ! 130: /* this disk uses bad144 */ ! 131: int i; ! 132: int dkbbnum; ! 133: struct dkbad *dkbptr; ! 134: ! 135: /* find the first readable bad144 sector */ ! 136: /* some of this code is copied from ufs/disk_subr.c */ ! 137: /* read a bad sector table */ ! 138: dkbbnum = dl->d_secperunit - dl->d_nsectors; ! 139: if (dl->d_secsize > DEV_BSIZE) ! 140: dkbbnum *= dl->d_secsize / DEV_BSIZE; ! 141: else ! 142: dkbbnum /= DEV_BSIZE / dl->d_secsize; ! 143: i = 0; ! 144: do_bad144 = 0; ! 145: do { ! 146: /* XXX: what if the "DOS sector" < 512 bytes ??? */ ! 147: Bread(dosdev, dkbbnum + i); ! 148: dkbptr = (struct dkbad *) 0; ! 149: /* XXX why is this not in <sys/dkbad.h> ??? */ ! 150: #define DKBAD_MAGIC 0x4321 ! 151: if (dkbptr->bt_mbz == 0 && ! 152: dkbptr->bt_flag == DKBAD_MAGIC) { ! 153: dkb = *dkbptr; /* structure copy */ ! 154: do_bad144 = 1; ! 155: break; ! 156: } ! 157: i += 2; ! 158: } while (i < 10 && i < dl->d_nsectors); ! 159: if (!do_bad144) ! 160: printf("Bad badsect table\n"); ! 161: else ! 162: printf("Using bad144 bad sector at %d\n", dkbbnum+i); ! 163: } ! 164: #endif DO_BAD144 ! 165: } ! 166: return 0; ! 167: } ! 168: ! 169: devread() ! 170: { ! 171: int offset, sector = bnum; ! 172: int dosdev = inode.i_dev; ! 173: for (offset = 0; offset < cnt; offset += BPS) ! 174: { ! 175: Bread(dosdev, badsect(dosdev, sector++)); ! 176: bcopy(0, iodest+offset, BPS); ! 177: } ! 178: } ! 179: ! 180: Bread(dosdev,sector) ! 181: int dosdev,sector; ! 182: { ! 183: int cyl = sector/spc, head = (sector%spc)/spt, secnum = sector%spt; ! 184: while (biosread(dosdev, cyl,head,secnum)) ! 185: { ! 186: printf("Error: C:%d H:%d S:%d\n",cyl,head,secnum); ! 187: } ! 188: } ! 189: ! 190: badsect(dosdev, sector) ! 191: int dosdev, sector; ! 192: { ! 193: int i; ! 194: #ifdef DO_BAD144 ! 195: if (do_bad144) { ! 196: u_short cyl; ! 197: u_short head; ! 198: u_short sec; ! 199: int newsec; ! 200: struct disklabel *dl = &disklabel; ! 201: ! 202: /* XXX */ ! 203: /* from wd.c */ ! 204: /* bt_cyl = cylinder number in sorted order */ ! 205: /* bt_trksec is actually (head << 8) + sec */ ! 206: ! 207: /* only remap sectors in the partition */ ! 208: if (sector < boff || sector >= boff + bsize) { ! 209: goto no_remap; ! 210: } ! 211: ! 212: cyl = sector / dl->d_secpercyl; ! 213: head = (sector % dl->d_secpercyl) / dl->d_nsectors; ! 214: sec = sector % dl->d_nsectors; ! 215: sec = (head<<8) + sec; ! 216: ! 217: /* now, look in the table for a possible bad sector */ ! 218: for (i=0; i<126; i++) { ! 219: if (dkb.bt_bad[i].bt_cyl == cyl) { ! 220: /* found same cylinder */ ! 221: if (dkb.bt_bad[i].bt_trksec == sec) { ! 222: /* FOUND! */ ! 223: break; ! 224: } ! 225: } else if (dkb.bt_bad[i].bt_cyl > cyl) { ! 226: i = 126; ! 227: break; ! 228: } ! 229: } ! 230: if (i == 126) { ! 231: /* didn't find bad sector */ ! 232: goto no_remap; ! 233: } ! 234: /* otherwise find replacement sector */ ! 235: newsec = dl->d_secperunit - dl->d_nsectors - i -1; ! 236: return newsec; ! 237: } ! 238: #endif DO_BAD144 ! 239: no_remap: ! 240: return sector; ! 241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.