1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: 16: 17: 18: 19:
20:
21: #include "hwdepend.h"
22: #include <device/disk.h>
23:
24: 25: 26:
27: #define GMW(vp) ( (UW)((UB*)vp)[0] \
28: | (UW)((UB*)vp)[1] << 8 \
29: | (UW)((UB*)vp)[2] << 16 \
30: | (UW)((UB*)vp)[3] << 24 )
31: #define GMH(vp) ( (UH)((UB*)vp)[0] \
32: | (UH)((UB*)vp)[1] << 8 )
33:
34: 35: 36: 37: 38:
39: #define N_DISKCB 3
40: LOCAL struct dcblist {
41: const CFGDISK *cfg;
42: DISKCB dcb;
43: } dcbList[N_DISKCB];
44:
45: LOCAL W last_dcb = 0;
46:
47: 48: 49:
50: LOCAL DISKCB* getDISKCB( const CFGDISK *cfg )
51: {
52: W i, n;
53: DISKCB *dcb;
54:
55:
56: n = last_dcb;
57: do {
58: i = n;
59: if ( dcbList[i].cfg == cfg ) break;
60: if ( ++n >= N_DISKCB ) n = 0;
61: } while ( n != last_dcb );
62: dcb = &dcbList[i].dcb;
63: last_dcb = i;
64: if ( dcbList[i].cfg != cfg ) {
65:
66: memset(dcb, 0, sizeof(DISKCB));
67: dcbList[i].cfg = cfg;
68: }
69:
70: return dcb;
71: }
72:
73: 74: 75: 76: 77:
78: LOCAL W searchDevice( const UB *devnm, const CFGDISK **cfg_p )
79: {
80: UB name[L_DEVNM + 1];
81: W i, pno, c;
82:
83:
84: strncpy(name, devnm, L_DEVNM + 1);
85: if ( name[L_DEVNM] != '\0' ) return E_PAR;
86: i = strlen(name);
87: if ( i <= 0 ) return E_PAR;
88:
89:
90: pno = 0;
91: c = name[i - 1];
92: if ( c >= '0' && c <='3' ) {
93: if ( --i <= 0 ) return E_PAR;
94: name[i] = '\0';
95: pno = c - '0' + 1;
96: }
97:
98:
99: for ( i = 0; i < N_ConfigDisk; i++ ) {
100: if ( strncmp(name, ConfigDisk[i].name, L_DEVNM) == 0 ) break;
101: }
102: if ( i >= N_ConfigDisk ) return E_NOEXS;
103:
104: *cfg_p = &ConfigDisk[i];
105: return pno;
106: }
107:
108: 109: 110:
111: LOCAL ER readPart( DISKCB *dcb )
112: {
113: DiskBlock0 buf;
114: W i, pno;
115: ER err;
116:
117: dcb->boot = 0;
118:
119:
120: if ( dcb->blksz != sizeof(buf) ) return E_NOSPT;
121:
122:
123: err = (*dcb->rwdisk)(dcb, 0, 1, &buf, FALSE);
124: if ( err < E_OK ) return err;
125:
126:
127: if ( GMH(&buf.signature) != 0xaa55 ) return E_OK;
128:
129:
130: for ( i = 0; i < MAX_PARTITION; i++ ) {
131: pno = i + 1;
132: dcb->part[pno].sblk = GMW(buf.part[i].StartBlock);
133: dcb->part[pno].nblk = GMW(buf.part[i].BlockCnt);
134:
135: if ( buf.part[i].BootInd == 0x80
136: && dcb->part[pno].nblk > 0
137: && dcb->boot == 0 ) dcb->boot = pno;
138: }
139:
140: return E_OK;
141: }
142:
143: 144: 145: 146: 147: 148: 149: 150: 151:
152: EXPORT W openDisk( const UB *devnm, DISKCB **dcb_p )
153: {
154: const CFGDISK *cfg;
155: DISKCB *dcb;
156: W pno;
157: ER err;
158:
159:
160: pno = searchDevice(devnm, &cfg);
161: if ( pno < E_OK ) return pno;
162:
163:
164: dcb = getDISKCB(cfg);
165:
166:
167: err = (*cfg->initdisk)(dcb, cfg);
168: if ( err < E_OK ) return err;
169: if ( dcb->blksz == 0 ) return E_NOMDA;
170:
171: if ( dcb->boot == 0xff ) {
172:
173: err = readPart(dcb);
174: if ( err < E_OK ) return err;
175: }
176:
177: *dcb_p = dcb;
178: return pno;
179: }
180:
181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193:
194: EXPORT ER rwDisk( const UB *devnm, W blk, W nblk, void *buf, BOOL wrt )
195: {
196: DISKCB *dcb;
197: W pno, nb;
198: ER err;
199:
200:
201: pno = openDisk(devnm, &dcb);
202: if ( pno < E_OK ) return pno;
203:
204: nb = dcb->part[pno].nblk;
205:
206:
207: if ( blk < 0 || blk >= nb
208: || nblk <= 0 || nblk > nb - blk ) return E_PAR;
209:
210:
211: blk += dcb->part[pno].sblk;
212:
213:
214: err = (*dcb->rwdisk)(dcb, blk, nblk, buf, wrt);
215: if ( err < E_OK ) return err;
216:
217: return E_OK;
218: }
219:
220: 221: 222: 223: 224: 225: 226: 227: 228:
229: EXPORT ER infoDisk( const UB *devnm, W *blksz, W *tblks )
230: {
231: DISKCB *dcb;
232: W pno, buf, n;
233:
234:
235: pno = openDisk(devnm, &dcb);
236: if ( pno < E_OK ) return pno;
237:
238: 239: 240:
241: buf = dcb->part[pno].nblk;
242: n = writeMem((UW)tblks, &buf, sizeof(W), sizeof(W));
243: if ( n < sizeof(W) ) return E_MACV;
244:
245: buf = dcb->blksz;
246: n = writeMem((UW)blksz, &buf, sizeof(W), sizeof(W));
247: if ( n < sizeof(W) ) return E_MACV;
248:
249: return E_OK;
250: }