summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/SMARTDRV/FLUSH13.C
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DEV/SMARTDRV/FLUSH13.C
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/DEV/SMARTDRV/FLUSH13.C')
-rw-r--r--v4.0/src/DEV/SMARTDRV/FLUSH13.C686
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 */
180extern char NO_DEV_MESS[], IOCTL_BAD_MESS[], STATUS_MES2[], SWTCH_CONF[];
181extern char BAD_PARM[], STATUS_MES1[], DISSTRING[], ENSTRING[];
182extern char LOCKSTRING[], UNLSTRING[], REBOOT_MES[];
183extern char STATUS_3R[], STATUS_3W[], STATUS_3T[];
184extern char CACHE_MES[], WT_MES[], WB_MES[], L_MES[], C_MES[], T_MES[];
185extern char STATUS_4[], ONSTRING[], OFFSTRING[], STATUS_5[];
186
187/*
188 * Structure of the data returned by the status call to INT13
189 */
190typedef 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 */
216extern int IOCTLOpen(char *);
217extern int IOCTLWrite(int,char *,int);
218extern int IOCTLRead(int,status *,int);
219extern 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 */
234char *GetNum(cptr,iptr)
235unsigned char *cptr;
236unsigned 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 */
260char *GetOnOff(cptr,iptr)
261char *cptr;
262int *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 */
297main(argc, argv, envp)
298int argc;
299char **argv;
300char **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 */
662Fatal(p)
663char *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 */
680FatalC(hand,p)
681int hand;
682char *p;
683{
684 IOCTLClose(hand);
685 Fatal(p);
686}