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