|
|
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.