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