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