|
|
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.