1: /*
2: * SCCSID: @(#)dkbad.c 3.0 4/21/86
3: */
4: /*
5: * LICENSED FROM DIGITAL EQUIPMENT CORPORATION
6: * COPYRIGHT (c)
7: * DIGITAL EQUIPMENT CORPORATION
8: * MAYNARD, MASSACHUSETTS
9: * 1985, 1986, 1987
10: * ALL RIGHTS RESERVED
11: *
12: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
13: * NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
14: * EQUIPMENT CORPORATION. DIGITAL MAKES NO REPRESENTATIONS ABOUT
15: * THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS
16: * SUPPLIED "AS IS" WITHOUT EXPRESSED OR IMPLIED WARRANTY.
17: *
18: * IF THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES
19: * MODIFY THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT
20: * RIGHTS, APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE
21: * DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE.
22: */
23:
24: /*
25: * ULTRIX-11 Standalone Common Bad Sector Code
26: *
27: * Jerry Brenner 12/20/82
28: * Fred Canter 7/4/84 (modified for multiple dk_bad structures)
29: */
30:
31: #include <sys/param.h>
32: #include <sys/bads.h>
33: #include <sys/inode.h>
34: #include "saio.h"
35:
36: struct dkres dkr[2];
37: /*
38: * Search the bad sector table looking for
39: * the specified sector. Return index if found.
40: * Return -1 if not found.
41: */
42:
43: isbad(bt, cyl, trk, sec)
44: register struct dkbad *bt;
45: {
46: register int i;
47: register long blk, bblk;
48:
49: blk = ((long)cyl << 16) + (trk << 8) + sec;
50: for (i = 0; i < 126; i++) {
51: bblk=((long)bt->bt_badb[i].bt_cyl<<16)+bt->bt_badb[i].bt_trksec;
52: if (blk == bblk)
53: return (i);
54: if (blk < bblk || bblk < 0)
55: break;
56: }
57: return (-1);
58: }
59:
60: fixbad(io, wcnt, flag, dkn)
61: struct iob *io;
62: unsigned wcnt;
63: int flag, dkn;
64: {
65: int scnt, rcnt, tcnt;
66: long tadr;
67:
68: tcnt = -(io->i_cc>>1);
69: scnt = (wcnt - tcnt)<<1;
70: scnt = (scnt/512)*512;
71: rcnt = io->i_cc - scnt;
72: tadr = (((long)segflag)<<16) + io->i_ma;
73: tadr += scnt;
74: if(flag){
75: dkr[dkn].r_vma = tadr&0177777;
76: dkr[dkn].r_vxm = tadr >> 16;
77: if(rcnt > 512){
78: dkr[dkn].r_cc = rcnt - 512;
79: dkr[dkn].r_vcc = 512;
80: tadr += 512;
81: dkr[dkn].r_ma = tadr&0177777;
82: dkr[dkn].r_xm = tadr >> 16;
83: dkr[dkn].r_bn = io->i_bn +(scnt/512)+1;
84: } else {
85: dkr[dkn].r_vcc = rcnt<=0?512:rcnt;
86: dkr[dkn].r_cc = 0;
87: dkr[dkn].r_ma = 0;
88: }
89: }else{
90: dkr[dkn].r_ma = tadr&0177777;
91: dkr[dkn].r_xm = tadr >> 16;
92: dkr[dkn].r_cc = rcnt;
93: dkr[dkn].r_vcc = scnt;
94: dkr[dkn].r_bn = io->i_bn + (scnt/512);
95: }
96: }
97:
98: /*
99: * Allocate a bads structure for the disk,
100: * or return index into dk_badf[] if one
101: * allready allocated.
102: */
103: extern int dk_badf[];
104:
105: dkn_set(io)
106: struct iob *io;
107: {
108: register int i;
109:
110: /* form sort of a major/minor device number */
111: i = (io->i_ino.i_dev << 8) | io->i_unit;
112: if(dk_badf[0] == i)
113: return(0);
114: else if(dk_badf[1] == i)
115: return(1);
116: else if(dk_badf[0] == 0) {
117: dk_badf[0] = i;
118: return(0);
119: } else if(dk_badf[1] == 0) {
120: dk_badf[1] = i;
121: return(1);
122: } else
123: return(-1);
124: }
125:
126: /*
127: * This routine is called by the HP and HK drivers
128: * to do ECC error correction on data in the user's buffer.
129: * The problem is that the buffer is not mapped into the same
130: * 64KB segment is the driver (most of the time).
131: * Snarf KISA5 to map to the buffer. Everything is single threded,
132: * so that should be safe.
133: *
134: * segflag, defines the 64KB segment where I/O buffer located.
135: * addr - address within the 64KB segment
136: * xor - data to exclusive or with the data in the buffer
137: */
138:
139: #define KISA5 ((physadr)0172352)
140:
141: fixecc(addr, xor)
142: unsigned addr;
143: unsigned xor;
144: {
145: register int okisa5;
146: register int i;
147: register char *p;
148:
149: okisa5 = KISA5->r[0];
150: i = segflag << 10;
151: i |= ((addr >> 6) & 01600);
152: KISA5->r[0] = i;
153: p = (addr & 017777) | 0120000;
154: *((int *)p) ^= xor;
155: KISA5->r[0] = okisa5;
156: }
157:
158: /*
159: * This routine performs the same function as fixecc(), but is
160: * only used by the HK driver. Instead of fixing the ECC in the user's
161: * buffer, it fixes the sector headers read into the user's buffer
162: * when revectoring bad blocks.
163: */
164:
165: fixhdr(addr, data)
166: unsigned addr;
167: unsigned data;
168: {
169: register int okisa5;
170: register int i;
171: register char *p;
172:
173: okisa5 = KISA5->r[0];
174: i = segflag << 10;
175: i |= ((addr >> 6) & 01600);
176: KISA5->r[0] = i;
177: p = (addr & 017777) | 0120000;
178: *((int *)p) = data;
179: KISA5->r[0] = okisa5;
180: }
Defined functions
isbad
defined in line
43;
never used
Defined variables
dkr
defined in line
36; used 15 times
Defined macros