diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DEV/SMARTDRV/FLUSH13.C | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/DEV/SMARTDRV/FLUSH13.C')
| -rw-r--r-- | v4.0/src/DEV/SMARTDRV/FLUSH13.C | 686 |
1 files changed, 686 insertions, 0 deletions
diff --git a/v4.0/src/DEV/SMARTDRV/FLUSH13.C b/v4.0/src/DEV/SMARTDRV/FLUSH13.C new file mode 100644 index 0000000..cf01107 --- /dev/null +++ b/v4.0/src/DEV/SMARTDRV/FLUSH13.C | |||
| @@ -0,0 +1,686 @@ | |||
| 1 | /* | ||
| 2 | * FLUSH13 -- Device mod utility for INT13 memory cache | ||
| 3 | * | ||
| 4 | * FLUSH13 [/s|/sx|/sr] [/d|/e] [/l|/u] [/i] [/f] [/wt:on|/wt:off] | ||
| 5 | * [/wc:on|/wc:off] [/t:nnnnn] [/r:on|/r:off] [/c:on|/c:off] | ||
| 6 | * | ||
| 7 | * No arguments - This causes FLUSH13 to flush out any "dirty" | ||
| 8 | * tracks in the INT13 cache. A "dirty" track is one | ||
| 9 | * which has been written into the cache, but not yet | ||
| 10 | * written to the disk. This invokation causes all dirty tracks | ||
| 11 | * to be written out to the disk so that the system can | ||
| 12 | * be re-booted or turned off. NOTE: FAILURE TO FLUSH | ||
| 13 | * THE CACHE BEFORE A RE-BOOT OR POWER OFF CAN CAUSE THE | ||
| 14 | * INFORMATION ON THE HARDFILE TO BE CORRUPTED. | ||
| 15 | * | ||
| 16 | * /f - Flush. Same as the no arguments case, but allows you to | ||
| 17 | * perform the flush and do something else (like /s). | ||
| 18 | * | ||
| 19 | * /i - Flush and invalidate. This is the same as the no argument | ||
| 20 | * case except that all of the information in the cache | ||
| 21 | * is also discarded. This makes the cache EMPTY. | ||
| 22 | * | ||
| 23 | * /d - Disable caching. This causes all dirty cache information | ||
| 24 | * to be flushed and all caching to stop. | ||
| 25 | * | ||
| 26 | * /e - Enable caching. This causes caching to be enabled after | ||
| 27 | * a previous /d disable. When INT13 is started it is enabled. | ||
| 28 | * | ||
| 29 | * /l - Lock the cache. This causes all dirty information to be | ||
| 30 | * flushed, and the cache contents to be locked in the cache. | ||
| 31 | * When in this mode the locked elements will not be discarded | ||
| 32 | * to make room for new tracks. This can be used | ||
| 33 | * to "load" the cache with desired things. For instance if | ||
| 34 | * you use the "foobar" program a lot, you can run foobar, | ||
| 35 | * causing it to be loaded into the cache, then lock the cache. | ||
| 36 | * This causes the foobar program to always be in the cache. | ||
| 37 | * You may lock the cache as many times as you want. Each lock | ||
| 38 | * causes the current information (including any previously | ||
| 39 | * locked information) to be locked. | ||
| 40 | * NOTE: Information in a locked cache is READ ONLY!! Any write | ||
| 41 | * operation on information in a locked cache causes the | ||
| 42 | * information to be unlocked. | ||
| 43 | * | ||
| 44 | * /u - Unlock the cache. This undoes a previous /l and returns | ||
| 45 | * the cache to normal operation. | ||
| 46 | * | ||
| 47 | * /s - Print status. This displays the settings of the setable | ||
| 48 | * device parameters. | ||
| 49 | * /sx - Print extended status. Same as /s, only additional | ||
| 50 | * Statistical information is also given. | ||
| 51 | * /sr - Reset statistics. Same as /sx, only the additional | ||
| 52 | * Statistical information is reset to 0. | ||
| 53 | * | ||
| 54 | * /wt:on off - Enable or Disable write through. When INT13 is caching | ||
| 55 | * write information, it is a good idea to imply a flush of | ||
| 56 | * the cache on some operations so that in case of a crash or | ||
| 57 | * power failure the information in the cache which is not on | ||
| 58 | * the disk will not be lost. /wt:on enables write through on full | ||
| 59 | * track INT 13s which are to tracks not currently in the cache. | ||
| 60 | * /wt:off disables it. INT13 is faster with write through | ||
| 61 | * off, at the expense of there being a bigger risk of | ||
| 62 | * loosing data. /wt:on IS NOT a substitute for flushing before | ||
| 63 | * a re-boot!!!! This write through mechanism is far from perfect, | ||
| 64 | * all it is is a risk REDUCER, not a risk eliminator. /wt:off | ||
| 65 | * is the setting when INT13 is started. | ||
| 66 | * | ||
| 67 | * /wc:on off - Enable or Disable write caching. There is risk when | ||
| 68 | * caching "dirty" information that the system will crash, | ||
| 69 | * or be re-booted, or be turned off before this information | ||
| 70 | * can be written to the disk. This may corrupt the disk. | ||
| 71 | * This risk can be ELIMINATED, at the expense of cache | ||
| 72 | * performance, by NOT caching any dirty information. | ||
| 73 | * /wc:off disables the caching of dirty information, | ||
| 74 | * eliminating the risk. /wc:on enables the caching of dirty | ||
| 75 | * information. /wc:on is the default when INT13 is started. | ||
| 76 | * | ||
| 77 | * WARNING: You must be careful to flush the cache before | ||
| 78 | * re-booting the system, or turning it off if /wc:on is selected. | ||
| 79 | * You should also be careful to disable the cache (/d), or do | ||
| 80 | * /wc:off before running any program under development which | ||
| 81 | * has a chance of crashing due to bugs. | ||
| 82 | * | ||
| 83 | * NOTE: When /wc:off is selected, write info CAN get into | ||
| 84 | * the cache (when the write is to a track which is currently | ||
| 85 | * in the cache). The difference is that this "dirty" information | ||
| 86 | * is IMMEDIATELY written out to the disk instead of being | ||
| 87 | * held in the cache in the "dirty" state. When the write is | ||
| 88 | * to a track that is not in the cache, it will be passed | ||
| 89 | * through to the disk without being cached. | ||
| 90 | * | ||
| 91 | * /t:nnnnn - Set the auto flush interval. INT13 listens on the system | ||
| 92 | * timer to note the passage of time and "age" the dirty | ||
| 93 | * information in the cache. Every nnnnn ticks, the cache is | ||
| 94 | * flushed. The timer ticks 18.2 times a second. | ||
| 95 | * | ||
| 96 | * nnnnn | | ||
| 97 | * =========================================== | ||
| 98 | * 18 | Flush every second | ||
| 99 | * 1092 | Flush every minute | ||
| 100 | * 5460 | Flush every 5 minutes | ||
| 101 | * 10920 | Flush every 10 minutes | ||
| 102 | * 21840 | Flush every 20 minutes | ||
| 103 | * 32760 | Flush every 30 minutes | ||
| 104 | * 65520 | Flush every hour | ||
| 105 | * | ||
| 106 | * The default setting of nnnnn is 1092 or every minute. | ||
| 107 | * NOTE: There is no way to "disable" this tick aging. Setting | ||
| 108 | * nnnnn = 0 causes a wait for 65536 ticks which is a | ||
| 109 | * little over an hour. The max value for nnnnn is 65535. | ||
| 110 | * Disabling the cache (/d), or turning write caching | ||
| 111 | * off (/wc:off) effectively prevents the aging from | ||
| 112 | * doing anything as there is never anything to flush | ||
| 113 | * in these cases. Setting very low values of nnnnn | ||
| 114 | * should be avoided as it places a lot of overhead into | ||
| 115 | * the timer interrupt service. Rather than set low values, | ||
| 116 | * it is better to just turn off write caching (/wc:off). | ||
| 117 | * NOTE: As stated above, the max value for nnnnn is 65535. It | ||
| 118 | * should be noted however that FLUSH13 DOES NOT object if | ||
| 119 | * you specify a number larger than this! It will simply | ||
| 120 | * use only the low 16 bits of the number. | ||
| 121 | * | ||
| 122 | * /r:on off - En/Disable reboot flush. | ||
| 123 | * INT13 has a provision for detecting Ctrl-Alt-Del user | ||
| 124 | * reboots. /r:on enables a flush of the cache at this time | ||
| 125 | * to prevent the disks from being corrupted. The default | ||
| 126 | * setting is /r:off. NOTE WARNING DANGER!!!!! Enabling | ||
| 127 | * this feature can prevent disks from being damaged BUT | ||
| 128 | * the mechanism has flaws. For one, you will have to hit | ||
| 129 | * Ctrl-Alt-Del a second time to get the system to reboot. | ||
| 130 | * YOU MUST NOT POUND ON THE KEY. You will crash the system if | ||
| 131 | * you do. Hit the key ONCE, if the system re-boots, fine. If | ||
| 132 | * there is info to flush out of the cache, the drive light | ||
| 133 | * will come on and the system will probably NOT reboot. WAIT | ||
| 134 | * until the drive light is OFF before hitting Ctrl-Alt-Del | ||
| 135 | * again. This feature of INT13 MAY NOT WORK with other | ||
| 136 | * software in the system. USER BEWARE!!!!!!!!!!!!!!!!!!! | ||
| 137 | * | ||
| 138 | * /c:on off - En/Disable all cache on reads. | ||
| 139 | * Normally INT13 does not cache EVERY I/O. Whenever | ||
| 140 | * it sees a full track I/O which is not currently in | ||
| 141 | * the cache, it DOES NOT cache that track. This is | ||
| 142 | * an optimization for "typical" operation, and actually | ||
| 143 | * increases performance. This is the default setting | ||
| 144 | * (/c:off). There may be some cases where it is desirable | ||
| 145 | * that ALL reads be cached. One example is that you are | ||
| 146 | * "loading" the cache prior to locking it with FLUSH13 /l. | ||
| 147 | * With /c:off, some pieces of what you're trying to load | ||
| 148 | * may not get into the cache. Another example is that | ||
| 149 | * you continually access in a sequential manner (like | ||
| 150 | * program load) some large file which happens to be | ||
| 151 | * contiguous on the disk. Again, there may be some "piece" | ||
| 152 | * of the file which does not get into the cache with | ||
| 153 | * /c:off. /c:on enables the caching of ALL reads. | ||
| 154 | * NOTE: The same "don't bother caching operations which | ||
| 155 | * are full track and not in the cache" applies | ||
| 156 | * to writes as well. /c has NO EFFECT on this | ||
| 157 | * behavior however. /c only effects read operations. | ||
| 158 | * | ||
| 159 | * MODIFICATION HISTORY | ||
| 160 | * | ||
| 161 | * 1.10 5/26/86 ARR First version in assembler | ||
| 162 | * 1.20 5/27/86 ARR Lock cache function added. | ||
| 163 | * 1.22 5/30/86 ARR /r reboot flush code added | ||
| 164 | * 1.23 6/03/86 ARR Cache statistics added | ||
| 165 | * 1.24 6/05/86 ARR Added /a "all cache" code | ||
| 166 | * 1.25 6/10/86 ARR Added total used, total locked to status | ||
| 167 | * RECODED in 'C'. | ||
| 168 | * /f switch added. | ||
| 169 | * 1.26 6/12/86 ARR /wb changed to /wc. Some status report wording | ||
| 170 | * changed. This was to align the behavior with the | ||
| 171 | * documentation a little better. | ||
| 172 | * 1.27 1/22/87 ARR Change to format of status information. | ||
| 173 | */ | ||
| 174 | |||
| 175 | #include <stdio.h> | ||
| 176 | |||
| 177 | /* | ||
| 178 | * Messages in flmes.asm | ||
| 179 | */ | ||
| 180 | extern char NO_DEV_MESS[], IOCTL_BAD_MESS[], STATUS_MES2[], SWTCH_CONF[]; | ||
| 181 | extern char BAD_PARM[], STATUS_MES1[], DISSTRING[], ENSTRING[]; | ||
| 182 | extern char LOCKSTRING[], UNLSTRING[], REBOOT_MES[]; | ||
| 183 | extern char STATUS_3R[], STATUS_3W[], STATUS_3T[]; | ||
| 184 | extern char CACHE_MES[], WT_MES[], WB_MES[], L_MES[], C_MES[], T_MES[]; | ||
| 185 | extern char STATUS_4[], ONSTRING[], OFFSTRING[], STATUS_5[]; | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Structure of the data returned by the status call to INT13 | ||
| 189 | */ | ||
| 190 | typedef struct { | ||
| 191 | unsigned char write_through; | ||
| 192 | unsigned char write_buff; | ||
| 193 | unsigned char enable_13; | ||
| 194 | unsigned char nuldev; | ||
| 195 | unsigned int ticksetting; | ||
| 196 | unsigned char lock_cache; | ||
| 197 | unsigned char reboot_flush; | ||
| 198 | unsigned char all_cache; | ||
| 199 | unsigned char pad; | ||
| 200 | unsigned long total_writes; | ||
| 201 | unsigned long write_hits; | ||
| 202 | unsigned long total_reads; | ||
| 203 | unsigned long read_hits; | ||
| 204 | unsigned int ttracks; | ||
| 205 | unsigned int total_used; | ||
| 206 | unsigned int total_locked; | ||
| 207 | unsigned int total_dirty; | ||
| 208 | unsigned int current_size; | ||
| 209 | unsigned int initial_size; | ||
| 210 | unsigned int minimum_size; | ||
| 211 | } status; | ||
| 212 | |||
| 213 | /* | ||
| 214 | * Assembler routines in fl13.asm | ||
| 215 | */ | ||
| 216 | extern int IOCTLOpen(char *); | ||
| 217 | extern int IOCTLWrite(int,char *,int); | ||
| 218 | extern int IOCTLRead(int,status *,int); | ||
| 219 | extern int IOCTLClose(int); | ||
| 220 | |||
| 221 | /* | ||
| 222 | * GetNum - Read an unsigned 16 bit decimal number | ||
| 223 | * | ||
| 224 | * ENTRY: cptr points to string where decimal number is | ||
| 225 | * iptr points to unsigned int where number goes | ||
| 226 | * | ||
| 227 | * NOTES: Calls Fatal (which doesn't return) if no number is present. | ||
| 228 | * No error if number is > 16 bits, only low 16 bits are returned. | ||
| 229 | * | ||
| 230 | * EXIT: returns cptr advanced past number | ||
| 231 | * iptr contains number found | ||
| 232 | * | ||
| 233 | */ | ||
| 234 | char *GetNum(cptr,iptr) | ||
| 235 | unsigned char *cptr; | ||
| 236 | unsigned int *iptr; | ||
| 237 | { | ||
| 238 | *iptr = 0; | ||
| 239 | if((*cptr < '0') || (*cptr > '9')) | ||
| 240 | Fatal(BAD_PARM); | ||
| 241 | while((*cptr >= '0') && (*cptr <= '9')) | ||
| 242 | *iptr = (*iptr * 10) + ((unsigned int) (*cptr++ - '0')); | ||
| 243 | return(cptr); | ||
| 244 | } | ||
| 245 | |||
| 246 | /* | ||
| 247 | * GetOnOff - Check for :on or :off string | ||
| 248 | * | ||
| 249 | * ENTRY: cptr points to string where :on or :off is supposed to be | ||
| 250 | * iptr points to unsigned int which is a boolean | ||
| 251 | * | ||
| 252 | * NOTES: Calls Fatal (which doesn't return) if :on or :off is not found. | ||
| 253 | * Case insensitive. | ||
| 254 | * | ||
| 255 | * EXIT: returns cptr advanced past :on or :off | ||
| 256 | * iptr contains 1 if :on was found | ||
| 257 | * iptr contains 0 if :off was found | ||
| 258 | * | ||
| 259 | */ | ||
| 260 | char *GetOnOff(cptr,iptr) | ||
| 261 | char *cptr; | ||
| 262 | int *iptr; | ||
| 263 | { | ||
| 264 | if(*cptr++ != ':') | ||
| 265 | Fatal(BAD_PARM); | ||
| 266 | *cptr |= 0x20; | ||
| 267 | if(*cptr++ != 'o') | ||
| 268 | Fatal(BAD_PARM); | ||
| 269 | *cptr |= 0x20; | ||
| 270 | if(*cptr == 'n') { | ||
| 271 | cptr++; | ||
| 272 | *iptr = 1; | ||
| 273 | } | ||
| 274 | else if(*cptr == 'f'){ | ||
| 275 | cptr++; | ||
| 276 | *cptr |= 0x20; | ||
| 277 | if(*cptr++ != 'f') | ||
| 278 | Fatal(BAD_PARM); | ||
| 279 | *iptr = 0; | ||
| 280 | } | ||
| 281 | else | ||
| 282 | Fatal(BAD_PARM); | ||
| 283 | return(cptr); | ||
| 284 | } | ||
| 285 | |||
| 286 | |||
| 287 | /* | ||
| 288 | * Flush13 | ||
| 289 | * | ||
| 290 | * ENTRY: Std | ||
| 291 | * | ||
| 292 | * NOTES: | ||
| 293 | * | ||
| 294 | * EXIT: exit(0) if OK, exit(-1) if error. | ||
| 295 | * | ||
| 296 | */ | ||
| 297 | main(argc, argv, envp) | ||
| 298 | int argc; | ||
| 299 | char **argv; | ||
| 300 | char **envp; | ||
| 301 | |||
| 302 | { | ||
| 303 | |||
| 304 | int handle,boolval; | ||
| 305 | char *cptr; | ||
| 306 | unsigned long total_hits,total_ops; | ||
| 307 | unsigned int minutes,seconds; | ||
| 308 | struct { | ||
| 309 | unsigned SWITCH_S : 1; | ||
| 310 | unsigned SWITCH_I : 1; | ||
| 311 | unsigned SWITCH_D : 1; | ||
| 312 | unsigned SWITCH_E : 1; | ||
| 313 | unsigned SWITCH_L : 1; | ||
| 314 | unsigned SWITCH_U : 1; | ||
| 315 | unsigned SWITCH_T : 1; | ||
| 316 | unsigned SWITCH_WCON : 1; | ||
| 317 | unsigned SWITCH_WCOFF : 1; | ||
| 318 | unsigned SWITCH_WTON : 1; | ||
| 319 | unsigned SWITCH_WTOFF : 1; | ||
| 320 | unsigned SWITCH_ROFF : 1; | ||
| 321 | unsigned SWITCH_RON : 1; | ||
| 322 | unsigned SWITCH_SX : 1; | ||
| 323 | unsigned SWITCH_SR : 1; | ||
| 324 | unsigned SWITCH_CON : 1; | ||
| 325 | unsigned SWITCH_COFF : 1; | ||
| 326 | unsigned SWITCH_F : 1; | ||
| 327 | } switches; | ||
| 328 | struct { | ||
| 329 | unsigned char Tchar; | ||
| 330 | unsigned char tickvall; /* this is actually an unsigned int */ | ||
| 331 | unsigned char tickvalh; /* but we have to declare it this way */ | ||
| 332 | } tickpacket; /* so that the compiler doesn't word align */ | ||
| 333 | status config; | ||
| 334 | |||
| 335 | /* Check for no arguments case and process if found */ | ||
| 336 | |||
| 337 | handle = -1; | ||
| 338 | if (argc == 1) { /* no arguments */ | ||
| 339 | if((handle = IOCTLOpen("SMARTAAR")) == -1) | ||
| 340 | Fatal(NO_DEV_MESS); | ||
| 341 | if(IOCTLWrite(handle,"\x00",1) == -1) | ||
| 342 | Fatal(IOCTL_BAD_MESS); | ||
| 343 | IOCTLClose(handle); | ||
| 344 | exit(0); | ||
| 345 | } | ||
| 346 | |||
| 347 | /* Initialize data associated with the argument parse */ | ||
| 348 | |||
| 349 | switches.SWITCH_S = switches.SWITCH_I = switches.SWITCH_D = 0; | ||
| 350 | switches.SWITCH_E = switches.SWITCH_L = switches.SWITCH_U = 0; | ||
| 351 | switches.SWITCH_T = switches.SWITCH_WCON = switches.SWITCH_WCOFF = 0; | ||
| 352 | switches.SWITCH_WTON = switches.SWITCH_WTOFF = switches.SWITCH_ROFF = 0; | ||
| 353 | switches.SWITCH_RON = switches.SWITCH_SX = switches.SWITCH_SR = 0; | ||
| 354 | switches.SWITCH_CON = switches.SWITCH_COFF = switches.SWITCH_F = 0; | ||
| 355 | |||
| 356 | /* Parse the arguments */ | ||
| 357 | |||
| 358 | ++argv; /* Skip argv[0] */ | ||
| 359 | while(--argc) { /* While arguments */ | ||
| 360 | cptr = *argv; | ||
| 361 | if(*cptr++ != '/') /* all arguments are switches */ | ||
| 362 | Fatal(BAD_PARM); | ||
| 363 | if(*cptr == '\0') /* trailing / error? */ | ||
| 364 | Fatal(BAD_PARM); | ||
| 365 | *cptr |= 0x20; /* lower case */ | ||
| 366 | switch (*cptr++) { | ||
| 367 | |||
| 368 | /* Status */ | ||
| 369 | case 's': | ||
| 370 | if(switches.SWITCH_S || switches.SWITCH_SX || switches.SWITCH_SR) | ||
| 371 | Fatal(SWTCH_CONF); | ||
| 372 | if(*cptr == '\0') | ||
| 373 | switches.SWITCH_S = 1; | ||
| 374 | else { | ||
| 375 | *cptr |= 0x20; | ||
| 376 | if(*cptr == 'r') | ||
| 377 | switches.SWITCH_SR = 1; | ||
| 378 | else if(*cptr == 'x') | ||
| 379 | switches.SWITCH_SX = 1; | ||
| 380 | else | ||
| 381 | Fatal(BAD_PARM); | ||
| 382 | cptr++; | ||
| 383 | } | ||
| 384 | break; | ||
| 385 | |||
| 386 | /* c on or off */ | ||
| 387 | case 'c': | ||
| 388 | if(switches.SWITCH_CON || switches.SWITCH_COFF) | ||
| 389 | Fatal(SWTCH_CONF); | ||
| 390 | cptr = GetOnOff(cptr,&boolval); | ||
| 391 | if(boolval) | ||
| 392 | switches.SWITCH_CON = 1; | ||
| 393 | else | ||
| 394 | switches.SWITCH_COFF = 1; | ||
| 395 | break; | ||
| 396 | |||
| 397 | /* t set tick value */ | ||
| 398 | case 't': | ||
| 399 | if(switches.SWITCH_T) | ||
| 400 | Fatal(SWTCH_CONF); | ||
| 401 | if(*cptr++ != ':') | ||
| 402 | Fatal(BAD_PARM); | ||
| 403 | cptr = GetNum(cptr,&tickpacket.tickvall); | ||
| 404 | tickpacket.Tchar = '\x0B'; /* set tick is call 5 */ | ||
| 405 | switches.SWITCH_T = 1; | ||
| 406 | break; | ||
| 407 | |||
| 408 | /* wt or wb on or off */ | ||
| 409 | case 'w': | ||
| 410 | *cptr |= 0x20; | ||
| 411 | if(*cptr == 'c') { | ||
| 412 | cptr++; | ||
| 413 | if(switches.SWITCH_WCOFF || switches.SWITCH_WCON) | ||
| 414 | Fatal(SWTCH_CONF); | ||
| 415 | cptr = GetOnOff(cptr,&boolval); | ||
| 416 | if(boolval) | ||
| 417 | switches.SWITCH_WCON = 1; | ||
| 418 | else | ||
| 419 | switches.SWITCH_WCOFF = 1; | ||
| 420 | } | ||
| 421 | else if(*cptr == 't') { | ||
| 422 | cptr++; | ||
| 423 | if(switches.SWITCH_WTOFF || switches.SWITCH_WTON) | ||
| 424 | Fatal(SWTCH_CONF); | ||
| 425 | cptr = GetOnOff(cptr,&boolval); | ||
| 426 | if(boolval) | ||
| 427 | switches.SWITCH_WTON = 1; | ||
| 428 | else | ||
| 429 | switches.SWITCH_WTOFF = 1; | ||
| 430 | } | ||
| 431 | else | ||
| 432 | Fatal(BAD_PARM); | ||
| 433 | break; | ||
| 434 | |||
| 435 | /* d disable */ | ||
| 436 | case 'd': | ||
| 437 | if(switches.SWITCH_D || switches.SWITCH_E) | ||
| 438 | Fatal(SWTCH_CONF); | ||
| 439 | switches.SWITCH_D = 1; | ||
| 440 | break; | ||
| 441 | |||
| 442 | /* e enable */ | ||
| 443 | case 'e': | ||
| 444 | if(switches.SWITCH_D || switches.SWITCH_E) | ||
| 445 | Fatal(SWTCH_CONF); | ||
| 446 | switches.SWITCH_E = 1; | ||
| 447 | break; | ||
| 448 | |||
| 449 | /* l lock */ | ||
| 450 | case 'l': | ||
| 451 | if(switches.SWITCH_L || switches.SWITCH_U) | ||
| 452 | Fatal(SWTCH_CONF); | ||
| 453 | switches.SWITCH_L = 1; | ||
| 454 | break; | ||
| 455 | |||
| 456 | /* u unlock */ | ||
| 457 | case 'u': | ||
| 458 | if(switches.SWITCH_L || switches.SWITCH_U) | ||
| 459 | Fatal(SWTCH_CONF); | ||
| 460 | switches.SWITCH_U = 1; | ||
| 461 | break; | ||
| 462 | |||
| 463 | /* i invalidate */ | ||
| 464 | case 'i': | ||
| 465 | if(switches.SWITCH_I) | ||
| 466 | Fatal(SWTCH_CONF); | ||
| 467 | switches.SWITCH_I = 1; | ||
| 468 | break; | ||
| 469 | |||
| 470 | /* f flush */ | ||
| 471 | case 'f': | ||
| 472 | if(switches.SWITCH_F) | ||
| 473 | Fatal(SWTCH_CONF); | ||
| 474 | switches.SWITCH_F = 1; | ||
| 475 | break; | ||
| 476 | |||
| 477 | /* r on or off */ | ||
| 478 | case 'r': | ||
| 479 | if(switches.SWITCH_RON || switches.SWITCH_ROFF) | ||
| 480 | Fatal(SWTCH_CONF); | ||
| 481 | cptr = GetOnOff(cptr,&boolval); | ||
| 482 | if(boolval) | ||
| 483 | switches.SWITCH_RON = 1; | ||
| 484 | else | ||
| 485 | switches.SWITCH_ROFF = 1; | ||
| 486 | break; | ||
| 487 | |||
| 488 | default: | ||
| 489 | Fatal(BAD_PARM); | ||
| 490 | |||
| 491 | } | ||
| 492 | if(*cptr != '\0') /* must be at end of argument */ | ||
| 493 | Fatal(BAD_PARM); | ||
| 494 | ++argv; /* next argument */ | ||
| 495 | } | ||
| 496 | |||
| 497 | /* Open the device */ | ||
| 498 | |||
| 499 | if((handle = IOCTLOpen("SMARTAAR")) == -1) | ||
| 500 | Fatal(NO_DEV_MESS); | ||
| 501 | |||
| 502 | /* Perform the actions indicated by the arguments */ | ||
| 503 | |||
| 504 | if(switches.SWITCH_I) { | ||
| 505 | if(IOCTLWrite(handle,"\x01",1) == -1) | ||
| 506 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 507 | } | ||
| 508 | |||
| 509 | if(switches.SWITCH_F) { | ||
| 510 | if(IOCTLWrite(handle,"\x00",1) == -1) | ||
| 511 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 512 | } | ||
| 513 | |||
| 514 | if(switches.SWITCH_WTON) { | ||
| 515 | if(IOCTLWrite(handle,"\x04\x01",2) == -1) | ||
| 516 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 517 | } | ||
| 518 | else if(switches.SWITCH_WTOFF) { | ||
| 519 | if(IOCTLWrite(handle,"\x04\x00",2) == -1) | ||
| 520 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 521 | } | ||
| 522 | |||
| 523 | if(switches.SWITCH_WCON) { | ||
| 524 | if(IOCTLWrite(handle,"\x04\x03",2) == -1) | ||
| 525 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 526 | } | ||
| 527 | else if(switches.SWITCH_WCOFF) { | ||
| 528 | if(IOCTLWrite(handle,"\x04\x02",2) == -1) | ||
| 529 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 530 | } | ||
| 531 | |||
| 532 | if(switches.SWITCH_L) { | ||
| 533 | if(IOCTLWrite(handle,"\x06",1) == -1) | ||
| 534 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 535 | } | ||
| 536 | else if(switches.SWITCH_U) { | ||
| 537 | if(IOCTLWrite(handle,"\x07",1) == -1) | ||
| 538 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 539 | } | ||
| 540 | |||
| 541 | if(switches.SWITCH_T) { | ||
| 542 | if(IOCTLWrite(handle,&tickpacket.Tchar,3) == -1) | ||
| 543 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 544 | } | ||
| 545 | |||
| 546 | if(switches.SWITCH_RON) { | ||
| 547 | if(IOCTLWrite(handle,"\x08\x01",2) == -1) | ||
| 548 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 549 | } | ||
| 550 | else if(switches.SWITCH_ROFF) { | ||
| 551 | if(IOCTLWrite(handle,"\x08\x00",2) == -1) | ||
| 552 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 553 | } | ||
| 554 | |||
| 555 | if(switches.SWITCH_CON) { | ||
| 556 | if(IOCTLWrite(handle,"\x0A\x01",2) == -1) | ||
| 557 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 558 | } | ||
| 559 | else if(switches.SWITCH_COFF) { | ||
| 560 | if(IOCTLWrite(handle,"\x0A\x00",2) == -1) | ||
| 561 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 562 | } | ||
| 563 | |||
| 564 | if(switches.SWITCH_E) { | ||
| 565 | if(IOCTLWrite(handle,"\x03",1) == -1) | ||
| 566 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 567 | } | ||
| 568 | else if(switches.SWITCH_D) { | ||
| 569 | if(IOCTLWrite(handle,"\x02",1) == -1) | ||
| 570 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 571 | } | ||
| 572 | |||
| 573 | if(switches.SWITCH_S || switches.SWITCH_SR || switches.SWITCH_SX) { | ||
| 574 | if(IOCTLRead(handle,&config,sizeof(config)) == -1) | ||
| 575 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 576 | if(config.nuldev != 0) | ||
| 577 | printf(STATUS_MES1); | ||
| 578 | else { | ||
| 579 | printf(STATUS_MES2); | ||
| 580 | if(config.enable_13 != 0) | ||
| 581 | printf(CACHE_MES,ENSTRING); | ||
| 582 | else | ||
| 583 | printf(CACHE_MES,DISSTRING); | ||
| 584 | if(config.lock_cache != 0) | ||
| 585 | printf(L_MES,LOCKSTRING); | ||
| 586 | else | ||
| 587 | printf(L_MES,UNLSTRING); | ||
| 588 | |||
| 589 | if(config.write_buff != 0) | ||
| 590 | printf(WB_MES,ONSTRING); | ||
| 591 | else | ||
| 592 | printf(WB_MES,OFFSTRING); | ||
| 593 | if(config.reboot_flush != 0) | ||
| 594 | printf(REBOOT_MES,ONSTRING); | ||
| 595 | else | ||
| 596 | printf(REBOOT_MES,OFFSTRING); | ||
| 597 | |||
| 598 | if(config.all_cache != 0) | ||
| 599 | printf(C_MES,ONSTRING); | ||
| 600 | else | ||
| 601 | printf(C_MES,OFFSTRING); | ||
| 602 | if(config.write_through != 0) | ||
| 603 | printf(WT_MES,ONSTRING); | ||
| 604 | else | ||
| 605 | printf(WT_MES,OFFSTRING); | ||
| 606 | |||
| 607 | if(config.ticksetting == 0) { | ||
| 608 | minutes = 60; | ||
| 609 | seconds = 1; | ||
| 610 | } | ||
| 611 | else { | ||
| 612 | seconds = ((unsigned long)config.ticksetting * 10) / 182; | ||
| 613 | minutes = seconds / 60; | ||
| 614 | seconds = seconds % 60; | ||
| 615 | } | ||
| 616 | printf(T_MES,minutes,seconds,config.ticksetting); | ||
| 617 | |||
| 618 | if(switches.SWITCH_SR) { | ||
| 619 | if(IOCTLWrite(handle,"\x09",1) == -1) | ||
| 620 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 621 | /* get the status again so that the extended status has the reset */ | ||
| 622 | if(IOCTLRead(handle,&config,sizeof(config)) == -1) | ||
| 623 | FatalC(handle,IOCTL_BAD_MESS); | ||
| 624 | } | ||
| 625 | if(switches.SWITCH_SX || switches.SWITCH_SR) { | ||
| 626 | if(config.total_writes == 0) | ||
| 627 | printf(STATUS_3W,config.write_hits,config.total_writes,(unsigned int) 0); | ||
| 628 | else | ||
| 629 | printf(STATUS_3W,config.write_hits,config.total_writes,(unsigned int)(config.write_hits*100/config.total_writes)); | ||
| 630 | if(config.total_reads == 0) | ||
| 631 | printf(STATUS_3R,config.read_hits,config.total_reads,(unsigned int) 0); | ||
| 632 | else | ||
| 633 | printf(STATUS_3R,config.read_hits,config.total_reads,(unsigned int)(config.read_hits*100/config.total_reads)); | ||
| 634 | total_ops = config.total_reads + config.total_writes; | ||
| 635 | total_hits = config.read_hits + config.write_hits; | ||
| 636 | if(total_ops == 0) | ||
| 637 | printf(STATUS_3T,total_hits,total_ops,(unsigned int) 0); | ||
| 638 | else | ||
| 639 | printf(STATUS_3T,total_hits,total_ops,(unsigned int)(total_hits*100/total_ops)); | ||
| 640 | printf(STATUS_4,config.ttracks,config.total_used,config.total_locked,config.total_dirty); | ||
| 641 | printf(STATUS_5,config.current_size,config.initial_size,config.minimum_size); | ||
| 642 | } | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | /* Close the device, and done */ | ||
| 647 | |||
| 648 | IOCTLClose(handle); | ||
| 649 | exit(0); | ||
| 650 | } | ||
| 651 | |||
| 652 | /* | ||
| 653 | * Fatal -- Fatal (to flush13) error | ||
| 654 | * | ||
| 655 | * ENTRY: p is pointer to error message to print | ||
| 656 | * | ||
| 657 | * NOTES: | ||
| 658 | * | ||
| 659 | * EXIT: exit(-1) | ||
| 660 | * | ||
| 661 | */ | ||
| 662 | Fatal(p) | ||
| 663 | char *p; | ||
| 664 | { | ||
| 665 | fprintf(stderr,"\n%s\n",p); | ||
| 666 | exit(-1); | ||
| 667 | } | ||
| 668 | |||
| 669 | /* | ||
| 670 | * FatalC -- Fatal (to flush13) error, and close open handle | ||
| 671 | * | ||
| 672 | * ENTRY: p is pointer to error message to print | ||
| 673 | * hand is handle number of open device channel to close | ||
| 674 | * | ||
| 675 | * NOTES: | ||
| 676 | * | ||
| 677 | * EXIT: To Fatal | ||
| 678 | * | ||
| 679 | */ | ||
| 680 | FatalC(hand,p) | ||
| 681 | int hand; | ||
| 682 | char *p; | ||
| 683 | { | ||
| 684 | IOCTLClose(hand); | ||
| 685 | Fatal(p); | ||
| 686 | } | ||