|
|
1.1 root 1: /*
2: * File: hdparms.c
3: *
4: * Purpose: display and modify hard drive parameters
5: *
6: * Called by "mkdev" command or usable as stand-alone.
7: * Non-build version expects driver in /tmp/drv, which is where mkdev
8: * leaves it.
9: *
10: * Usage: hdparms [-bfrs] devname ...
11: *
12: * Options:
13: * -b Use special processing when invoked from /etc/build
14: * -f Future Domain SCSI
15: * -r Specified device controls root partition (implies -b)
16: * -s Seagate SCSI
17: *
18: * $Log: hdparms.c,v $
19: * Revision 1.4 92/01/17 11:31:11 bin
20: * another hal update... looks like the final 321 ship version
21: *
22: * Revision 1.2 91/06/28 07:29:47 bin
23: * updated by hal
24: *
25: * Revision 1.4 91/06/27 13:38:07 hal
26: * Steve-style printf call for long messages.
27: * Drop calculated default parameters.
28: *
29: * Revision 1.3 91/06/27 13:21:24 hal
30: * Fix exit value if parameters are NOT changed.
31: * Use "success" not "exitval".
32: *
33: * Revision 1.2 91/06/03 04:32:58 hal
34: * Patch drv_parm_ table for ss driver.
35: *
36: * Revision 1.1 91/06/02 13:26:01 hal
37: * Initial revision
38: *
39: */
40:
41: /*
42: * Includes.
43: */
44: #include <stdio.h>
45: #include <sys/fdisk.h>
46: #include <sys/hdioctl.h>
47: #include <sys/stat.h>
48: #include "build0.h"
49:
50: /*
51: * Definitions.
52: * Constants.
53: * Macros with argument lists.
54: * Typedefs.
55: * Enums.
56: */
57: #define USAGEMSG "Usage:\t/etc/hdparms [ -bfrs ] device...\n"
58: #define OPENMODE 2 /* Default open mode: read/write. */
59: #define BUFLEN 40
60: #define DEV_SCSI_ID(dev) ((dev >> 4) & 0x0007)
61: #define VERSION "V1.4" /* version number */
62:
63: typedef unsigned int uint;
64: typedef unsigned char uchar;
65: typedef unsigned long ulong;
66:
67: /*
68: * Functions.
69: * Import Functions.
70: * Export Functions.
71: * Local Functions.
72: */
73: #if DEFAULT_PARMS
74: static void cam_parms();
75: static void fd_parms();
76: #endif
77: static void getuint();
78: static int hdparms();
79:
80: /*
81: * Global Data.
82: * Import Variables.
83: * Export Variables.
84: * Local Variables.
85: */
86: static int bflag; /* 1 for call via /etc/build */
87: static int fflag; /* 1 for Future Domain SCSI */
88: static int rflag; /* 1 for rootdev */
89: static int sflag; /* 1 for Seagate SCSI */
90:
91: /*
92: * main()
93: */
94: main(argc, argv)
95: int argc;
96: char *argv[];
97: {
98: uchar *s;
99: int success = 1;
100:
101: argv0 = argv[0];
102: usagemsg = USAGEMSG;
103: if (argc > 1 && argv[1][0] == '-') {
104: for (s = &argv[1][1]; *s; ++s) {
105: switch(*s) {
106: case 'b':
107: ++bflag;
108: break;
109: case 'f':
110: ++fflag;
111: break;
112: case 'r':
113: ++rflag;
114: ++bflag;
115: break;
116: case 's':
117: ++sflag;
118: break;
119: default:
120: usage();
121: }
122: }
123: --argc;
124: ++argv;
125: }
126:
127: while (--argc > 0) {
128: success &= hdparms(argv[1]);
129: ++argv;
130: }
131:
132: /*
133: * Exit with nonzero value if any call to hdparms() failed.
134: */
135: exit(success == 0);
136: }
137:
138: /*
139: * hdparms()
140: *
141: * Return 0 if error occurred, else 1.
142: */
143: static int hdparms(devname)
144: uchar *devname;
145: {
146: int fd;
147: hdparm_t parms;
148: int ret = 0;
149: struct stat dvstat;
150: int s_id; /* SCSI id */
151: uint pl; /* offset of device entry in drv_parm_ */
152: uchar ss_patch[60];
153: uchar * drv = "/drv/ss";
154: uchar cmd[80];
155: FILE * fp;
156:
157: if ((fd = open(devname, OPENMODE)) < 0) {
158: printf("Can't open %s.\n", devname);
159: goto noclose_fd;
160: }
161:
162: if (sflag || fflag)
163: if (stat(devname, &dvstat) != 0) {
164: printf("Can't stat %s.\n", devname);
165: goto close_fd;
166: } else {
167: s_id = DEV_SCSI_ID(dvstat.st_rdev);
168: pl = 4 * s_id; /* 4 bytes per device */
169: }
170:
171: if (ioctl(fd, HDGETA, (char *)(&parms)) == -1)
172: printf("Can't get parameters for %s.\n", devname);
173: else {
174: uint ncyls, nheads, nspt;
175: ulong nsectors;
176:
177: ncyls = (parms.ncyl[1] << 8) | parms.ncyl[0];
178: nheads = parms.nhead;
179: nspt = parms.nspt;
180: nsectors = (ulong)ncyls * (ulong)nheads * (ulong)nspt;
181:
182: printf("\nHere are the current parameters for SCSI device %d:\n", s_id);
183: printf("Number of cylinders = %d\n", ncyls);
184: printf("Number of heads = %d\n", nheads);
185: printf("Number of sectors per track = %d\n", nspt);
186:
187: printf(
188: "\nIf the values above do not agree with those used by your host adapter's BIOS"
189: "\nprogramming, you will not be able to boot COHERENT from this hard drive.\n");
190:
191: if (ncyls > 1024) {
192: printf(
193: "\nThis device has more than 1024 cylinders. In order to use the entire drive"
194: "\nfrom COHERENT, and possibly to be compatible with other operating systems,"
195: "\nyou will need to enter a set of translation-mode parameters. Enter the"
196: "\nparameters your BIOS uses. You can accept the default values shown by"
197: "\npressing <Enter> at each prompt.\n\n");
198: #if DEFAULT_PARMS
199: if (fflag)
200: fd_parms(&ncyls, &nheads, &nspt);
201: else
202: cam_parms(&ncyls, &nheads, &nspt);
203: #endif
204: }
205:
206: if (yes_no("Do you want to modify drive parameters")) {
207: getuint(&ncyls, "Number of cylinders");
208: getuint(&nheads, "Number of heads");
209: getuint(&nspt, "Number of sectors per track");
210:
211: parms.ncyl[1] = ncyls >> 8;
212: parms.ncyl[0] = ncyls & 0xFF;
213: parms.nhead = nheads;
214: parms.nspt = nspt;
215:
216: if (ioctl(fd, HDSETA, (char *)(&parms)) == -1)
217: printf("Couldn't write new parameters for %s.\n", devname);
218: else {
219: printf("New parameters written for %s.\n", devname);
220: ret = 1;
221: }
222:
223: /* Prepare to patch "ss" driver. */
224: if (sflag || fflag) {
225: sprintf(ss_patch,
226: "drv_parm_+%d=%d drv_parm_+%d=0x%04x",
227: pl, ncyls, pl+2, (nspt<<8) + nheads);
228: /* Write PATCHFILE which is run by build. */
229: if (bflag) {
230: fp = fopen(PATCHFILE, "a");
231: fprintf(fp, "/conf/patch /mnt%s %s\n", drv, ss_patch);
232: if (rflag)
233: fprintf(fp, "/conf/patch /mnt/coherent %s\n", ss_patch);
234: fclose(fp);
235:
236: } else { /* patch driver */
237: fprintf(cmd, "/conf/patch /tmp/drv/ss %s\n", ss_patch);
238: sys(cmd, S_FATAL);
239: printf("Parameters patched in /tmp/drv/ss\n");
240: }
241: }
242:
243: } else
244: ret = 1;
245: }
246:
247: close_fd:
248: close(fd);
249:
250: noclose_fd:
251: return ret;
252: }
253:
254: /*
255: * getuint()
256: *
257: * get unsigned integer value - display prompt with default value
258: */
259: static void getuint(np, prompt)
260: uint * np;
261: uchar * prompt;
262: {
263: uchar buf[BUFLEN];
264:
265: printf("%s [%d]: ", prompt, *np);
266: fgets(buf, BUFLEN, stdin);
267: sscanf(buf, "%d", np);
268: }
269:
270: #if DEFAULT_PARMS
271: /*
272: * cam_parms()
273: *
274: * Use CAM algorithm to compute new drive parameters which will keep
275: * number of cylinders under 1024.
276: */
277: static void cam_parms(p_ncyls, p_nheads, p_nspt)
278: uint * p_ncyls, * p_nheads, * p_nspt;
279: {
280: ulong capacity, ncyls, nheads, nspt;
281: ulong ntracks, nsph, nspc;
282:
283: capacity = (ulong)*p_ncyls * (ulong)*p_nheads * (ulong)*p_nspt;
284: if (capacity == 0L)
285: goto frotz;
286: ncyls = 1024L;
287: nspt = 62L;
288: nsph = ncyls * nspt;
289: nheads = capacity / nsph;
290:
291: if (capacity % nsph) {
292: nheads++;
293: ntracks = ncyls * nheads;
294: nspt = capacity / ntracks;
295:
296: if (capacity % ntracks) {
297: nspt++;
298: nspc = nheads * nspt;
299: ncyls = capacity / nspc;
300: }
301: }
302:
303: *p_ncyls = ncyls;
304: *p_nheads = nheads;
305: *p_nspt = nspt;
306: frotz:
307: return;
308: }
309:
310: /*
311: * fd_parms()
312: *
313: * Use Future Domain algorithm to compute new drive parameters which will
314: * keep number of cylinders under 1024.
315: */
316: static void fd_parms(p_ncyls, p_nheads, p_nspt)
317: uint * p_ncyls, * p_nheads, * p_nspt;
318: {
319: ulong capacity, ncyls, nheads, nspt;
320: ulong ntracks, foo, nspc;
321:
322: capacity = (ulong)*p_ncyls * (ulong)*p_nheads * (ulong)*p_nspt;
323: if (capacity == 0L)
324: goto frotz;
325: nspt = 17; /* first try 17 spt */
326: while (1) {
327: foo = capacity / 1024;
328: nheads = (foo / nspt) + 1;
329: nspc = nheads * nspt;
330: ncyls = capacity / nspc;
331: ntracks = nheads * ncyls;
332: if (ntracks < 32768L)
333: break;
334: if (nspt == 17)
335: nspt = 34; /* after 17, try 34 spt */
336: else if (nspt == 34)
337: nspt = 63; /* after 34, try 63 spt */
338: else
339: break;
340: }
341:
342: *p_ncyls = ncyls;
343: *p_nheads = nheads;
344: *p_nspt = nspt;
345: frotz:
346: return;
347: }
348: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.