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