1 /* @(#)xdisk.c 1.33 12/03/16 Copyright 1991-2012 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)xdisk.c 1.33 12/03/16 Copyright 1991-2012 J. Schilling";
6 #endif
7 /*
8 * Routines to handle external disk definitions
9 *
10 * Copyright (c) 1991-2012 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/stdio.h>
27 #include <schily/stdlib.h>
28 #include <schily/standard.h>
29 #include <schily/string.h>
30 #include <schily/utypes.h>
31 #include <schily/schily.h>
32 #ifdef HAVE_STDC_HEADERS
33 # include <stddef.h>
34 # define soff(str, fld) offsetof(struct str, fld)
35 #else
36 # include <struct.h>
37 # define soff(str, fld) fldoff(str, fld)
38 #endif
39 #include <scg/scsireg.h>
40 #include <scg/scsitransp.h>
41
42 #include "fmt.h"
43
44 #ifdef FMT
45 extern int xdebug;
46 extern int debug;
47 extern int save_mp;
48 extern int autoformat;
49 #else
50 int xdebug = 1;
51 #endif
52
53 struct dsk_fnd {
54 struct disk disk;
55 int match;
56 char name[512];
57 };
58
59 LOCAL struct dsk_fnd *expand_df __PR((struct dsk_fnd *, int));
60 LOCAL BOOL fuzzy_capacity __PR((struct disk *, struct dsk_fnd *));
61 EXPORT BOOL pdisk_eql __PR((struct disk *dp1, struct disk *dp2));
62 LOCAL BOOL add_disk __PR((char *, struct disk *, struct dsk_fnd *));
63 LOCAL void check_deflt __PR((struct dsk_fnd *, int *, int));
64 LOCAL void use_disk __PR((struct disk *, struct dsk_fnd *, int));
65 LOCAL void select_disk __PR((SCSI *scgp, struct disk *, struct dsk_fnd *, int, int));
66 EXPORT BOOL get_ext_diskdata __PR((SCSI *scgp, char *name, struct disk *dp));
67 LOCAL int do_disk __PR((char *, struct disk *, BOOL));
68 LOCAL void set_diskitem __PR((struct disk *, char *, char *, char *));
69 LOCAL BOOL set_diskvar __PR((char *, struct disk *));
70 LOCAL void copy_disk __PR((struct disk *, struct disk *));
71 EXPORT int cmp_disk __PR((struct disk *dp1, struct disk *dp2));
72 LOCAL BOOL disk_eql __PR((struct disk *, struct disk *));
73 EXPORT BOOL has_error_rec_params __PR((struct disk *dp));
74 EXPORT BOOL has_disre_params __PR((struct disk *dp));
75 LOCAL void copy_vendor_info __PR((char *, struct scsi_inquiry *));
76 EXPORT void prdisk __PR((FILE *f, struct disk *dp, struct scsi_inquiry *ip));
77 EXPORT int need_params __PR((struct disk *dp, int type));
78 EXPORT int need_label_params __PR((struct disk *dp));
79 EXPORT int need_geom_params __PR((struct disk *dp));
80 EXPORT int need_scsi_params __PR((struct disk *dp));
81 EXPORT int need_error_rec_params __PR((struct disk *dp));
82 EXPORT int need_disre_params __PR((struct disk *dp));
83
84
85 #define K_NONE 0x01 /* This entry is not used but might be in database */
86 #define K_NDB 0x02 /* This entry must not be in the database */
87 #define K_LABEL 0x04 /* This is a label - not a disk - parameter */
88 #define K_IGN 0x08 /* Inore this entry when comparing parameters */
89 #define K_COPY 0x10 /* Copy this parameter even if dest is initialized */
90 #define K_INIT 0x20 /* Copy over only to non initialized parameters */
91 #define K_BOOL 0x40 /* This is a boolean entry */
92
93 #define K_GEOM 0x0100 /* This is a disk geometry parameter */
94 #define K_SCSI 0x0200 /* This is a SCSI parameter */
95 #define K_ERREC 0x0400 /* This is an error recovery parameter */
96 #define K_DISRE 0x0800 /* This is a disconnect/reconnect parameter */
97
98 #define K_N 0x1000 /* We don't need to fill this out */
99
100 #define lfld(ptr, off) ((long *)(((char *)(ptr)) + (off)))
101
102 struct keyw {
103 char *name;
104 int flags;
105 int off;
106 } keyw[] = {
107
108 /* Disk Label geometry */
109 { "lhead", K_INIT|K_LABEL, soff(disk, lhead) },
110 { "lacyl", K_INIT|K_LABEL, soff(disk, lacyl) },
111 { "lpcyl", K_INIT|K_LABEL, soff(disk, lpcyl) },
112 { "lncyl", K_INIT|K_LABEL, soff(disk, lncyl) },
113 { "lspt", K_INIT|K_LABEL, soff(disk, lspt) },
114 { "lapc", K_INIT|K_LABEL|K_N, soff(disk, lapc) },
115
116 /* Disk Geometry */
117 { "nhead", K_INIT|K_GEOM, soff(disk, nhead) },
118 { "pcyl", K_INIT|K_GEOM, soff(disk, pcyl) },
119 { "atrk", K_INIT|K_GEOM, soff(disk, atrk) },
120 { "tpz", K_INIT|K_GEOM, soff(disk, tpz) },
121 { "spt", K_INIT|K_GEOM, soff(disk, spt) },
122 { "mintpz", K_INIT|K_GEOM|K_N|K_NDB, soff(disk, mintpz) },
123 { "maxtpz", K_INIT|K_GEOM|K_N|K_NDB, soff(disk, maxtpz) },
124 { "aspz", K_INIT|K_GEOM, soff(disk, aspz) },
125 { "secsize", K_INIT|K_GEOM, soff(disk, secsize) },
126 { "phys_secsize", K_INIT|K_GEOM|K_N, soff(disk, phys_secsize) },
127 /*
128 * ignore capacity on compares
129 * use fuzzy compare instead
130 */
131 { "capacity", K_INIT|K_N|K_IGN, soff(disk, capacity) },
132 { "min_capacity", K_NONE|K_N, soff(disk, dummy) },
133 { "rpm", K_INIT|K_GEOM, soff(disk, rpm) },
134 { "track_skew", K_INIT|K_GEOM, soff(disk, track_skew) },
135 { "cyl_skew", K_INIT|K_GEOM, soff(disk, cyl_skew) },
136
137 { "reduced_curr", K_INIT|K_GEOM|K_N, soff(disk, reduced_curr) },
138 { "write_precomp", K_INIT|K_GEOM|K_N, soff(disk, write_precomp) },
139 { "step_rate", K_INIT|K_GEOM|K_N, soff(disk, step_rate) },
140
141 { "rot_pos_locking", K_INIT|K_GEOM|K_N, soff(disk, rot_pos_locking) },
142 { "rotational_off", K_INIT|K_GEOM|K_N, soff(disk, rotational_off) },
143
144 { "interleave", K_INIT|K_GEOM, soff(disk, interleave) },
145 { "fmt_pattern", K_INIT|K_GEOM, soff(disk, fmt_pattern) },
146
147 { "fmt_mode", K_INIT|K_GEOM|K_N, soff(disk, fmt_mode) },
148 { "spare_band_size", K_INIT|K_GEOM|K_N, soff(disk, spare_band_size) },
149
150 /* SCSI parameters */
151 { "def_lst_format", K_INIT|K_SCSI, soff(disk, def_lst_format) },
152 { "split_wv_cmd", K_INIT|K_SCSI|K_BOOL, soff(disk, split_wv_cmd) },
153
154 /* Error recovery */
155 { "rd_retry_count", K_INIT|K_ERREC|K_N, soff(disk, rd_retry_count) },
156 { "wr_retry_count", K_INIT|K_ERREC|K_N, soff(disk, wr_retry_count) },
157 { "recov_timelim", K_INIT|K_ERREC|K_N, soff(disk, recov_timelim) },
158
159 /* Disconnect / reconnect */
160 { "buf_full_ratio", K_INIT|K_DISRE|K_N, soff(disk, buf_full_ratio) },
161 { "buf_empt_ratio", K_INIT|K_DISRE|K_N, soff(disk, buf_empt_ratio) },
162 { "bus_inact_limit", K_INIT|K_DISRE|K_N, soff(disk, bus_inact_limit) },
163 { "disc_time_limit", K_INIT|K_DISRE|K_N, soff(disk, disc_time_limit) },
164 { "conn_time_limit", K_INIT|K_DISRE|K_N, soff(disk, conn_time_limit) },
165 { "max_burst_size", K_INIT|K_DISRE|K_N, soff(disk, max_burst_size) },
166 { "data_tr_dis_ctl", K_INIT|K_DISRE|K_N, soff(disk, data_tr_dis_ctl) },
167
168 /* Common device control */
169 { "queue_alg_mod", K_INIT|K_SCSI|K_N, soff(disk, queue_alg_mod) },
170 { "dis_queuing", K_INIT|K_SCSI|K_BOOL|K_N,
171 soff(disk, dis_queuing) },
172
173 { "gap1", K_INIT|K_IGN, soff(disk, gap1) },
174 { "gap2", K_INIT|K_IGN, soff(disk, gap2) },
175 { "int_cyl", K_INIT|K_IGN|K_N, soff(disk, int_cyl) },
176 { "fmt_time", K_INIT|K_IGN, soff(disk, fmt_time) },
177 { "fmt_timeout", K_INIT|K_IGN|K_N, soff(disk, fmt_timeout) },
178 { "veri_time", K_INIT|K_IGN|K_N, soff(disk, veri_time) },
179 { "veri_count", K_INIT|K_IGN|K_N, soff(disk, veri_count) },
180 { "wr_veri_count", K_INIT|K_IGN|K_N, soff(disk, wr_veri_count) },
181 { "veri_loops", K_INIT|K_IGN|K_N, soff(disk, veri_loops) },
182 { "default_data", K_INIT|K_IGN|K_N|K_BOOL, soff(disk, default_data) },
183 { "bridge_controller", K_INIT|K_SCSI|K_IGN|K_N|K_BOOL,
184 soff(disk, bridge_controller) },
185
186 };
187
188 #define NKEYW (sizeof (keyw) / sizeof (keyw[0]))
189
190 struct keyw *keywNKEYW = &keyw[NKEYW];
191
192 #ifdef FMT
193 #else
main(ac,av)194 main(ac, av)
195 int ac;
196 char **av;
197 {
198 char *name;
199 struct disk test_disk;
200
201 if (ac > 1)
202 name = av[1];
203 else {
204 name = "QUANTUM P105S 910-10-94xA.1 ";
205 test_disk.nhead = 6;
206 test_disk.pcyl = 1019;
207 }
208
209 if (!opendatfile("sformat.dat"))
210 return;
211
212 get_ext_diskdata(name, &test_disk);
213
214 closedatfile();
215 }
216 #endif
217
218 LOCAL struct dsk_fnd *
expand_df(df,found)219 expand_df(df, found)
220 struct dsk_fnd *df;
221 int found;
222 {
223 struct dsk_fnd *xdf;
224
225 xdf = (struct dsk_fnd *) realloc(df,
226 sizeof (struct dsk_fnd) * (found+1));
227 disk_null(&xdf[found].disk, 1);
228 return (xdf);
229 }
230
231 LOCAL BOOL
fuzzy_capacity(dp,df)232 fuzzy_capacity(dp, df)
233 struct disk *dp;
234 struct dsk_fnd *df;
235 {
236 double dc; /* current disk */
237 double fc; /* found disk from database */
238
239 /*
240 * if capacity is not known this is a match
241 */
242 if (dp->capacity < 0 || df->disk.capacity < 0)
243 return (TRUE);
244
245 if (dp->secsize < 0)
246 dc = dp->capacity * 512.0;
247 else
248 dc = dp->capacity * (dp->secsize * 1.0);
249 if (df->disk.secsize < 0) {
250 if (dp->secsize > 0)
251 fc = df->disk.capacity * (dp->secsize * 1.0);
252 else
253 fc = df->disk.capacity * 512.0;
254 } else
255 fc = df->disk.capacity * (df->disk.secsize * 1.0);
256
257 if (debug || xdebug) {
258 printf("fuzzy_cap current: %g found: %g (limits: %g, %g)\n",
259 dc, fc, dc/1.3, dc*1.3);
260 }
261
262 /*
263 * XXX NOTE: Some versions of Sunpro C compile 1.3 t0 1.0 if
264 * XXX in german locale.
265 * XXX If fuzzy capacity does not work as expected:
266 * XXX check your C-compiler.
267 */
268 if ((dc * 1.3) < fc || (dc / 1.3) > fc)
269 return (FALSE);
270
271 if (xdebug) printf("fuzzy_cap: TRUE\n");
272 return (TRUE);
273 }
274
275 EXPORT BOOL
pdisk_eql(dp1,dp2)276 pdisk_eql(dp1, dp2)
277 struct disk *dp1;
278 struct disk *dp2;
279 {
280 return ((dp1->nhead <= 0 || dp1->nhead == dp2->nhead) &&
281 (dp1->pcyl <= 0 || dp1->pcyl == dp2->pcyl));
282 }
283
284 LOCAL BOOL
add_disk(name,dp,df)285 add_disk(name, dp, df)
286 char *name;
287 struct disk *dp;
288 struct dsk_fnd *df;
289 {
290 if (pdisk_eql(dp, &df->disk) && fuzzy_capacity(dp, df)) {
291 strcpy(df->name, name);
292 return (TRUE);
293 }
294 return (FALSE);
295 }
296
297 LOCAL void
check_deflt(df,deflt,found)298 check_deflt(df, deflt, found)
299 struct dsk_fnd *df;
300 int *deflt;
301 int found;
302 {
303 if (df->disk.default_data > 0) {
304 if (*deflt >= 0) {
305 if (!autoformat) {
306 datfileerr("second default_data for '%s'",
307 df->name);
308 } else {
309 comerrno(EX_BAD,
310 "Die Datenbasis besitzt mehrere default Diskparameter fuer diese Platte.\n");
311 /* NOTREACHED */
312 }
313 } else {
314 *deflt = found;
315 }
316 }
317 }
318
319 LOCAL void
use_disk(dp,df,this)320 use_disk(dp, df, this)
321 struct disk *dp;
322 struct dsk_fnd *df;
323 int this;
324 {
325 copy_disk(&df[this].disk, dp);
326 if (dp->disk_type)
327 free(dp->disk_type);
328 dp->disk_type = permstring(df[this].name);
329 }
330
331 #define item_equal(a, b) (((a) < 0 && (b) < 0) || ((a) == (b)))
332
333 LOCAL void
select_disk(scgp,dp,df,found,deflt)334 select_disk(scgp, dp, df, found, deflt)
335 SCSI *scgp;
336 struct disk *dp;
337 struct dsk_fnd *df;
338 int found;
339 int deflt;
340 {
341 int i;
342 int this = -1;
343 int match = -1;
344 int max = -1;
345 int ndbentry = found;
346 BOOL selected = FALSE;
347 BOOL bridge = FALSE;
348
349 for (i = 0; i < found; i++) {
350 df[i].match = cmp_disk(dp, &df[i].disk);
351 if (df[i].match > max &&
352 item_equal(dp->secsize, df[i].disk.secsize) &&
353 /*
354 * Sony Format Mode
355 */
356 item_equal(dp->fmt_mode, df[i].disk.fmt_mode)) {
357 max = df[i].match;
358 match = i;
359 }
360 if (disk_eql(dp, &df[i].disk))
361 this = i;
362 }
363 if (this < 0) {
364 /*
365 * This disk is not known in database.
366 * Create an entry for it (name == INQUIRY).
367 */
368 this = i;
369 disk_null(&df[this].disk, 0);
370 copy_disk(dp, &df[this].disk);
371 df[this].disk.flags |= D_DISK_CURRENT;
372 df[this].match = cmp_disk(dp, &df[this].disk);
373 copy_vendor_info(df[this].name, scgp->inq);
374 found++;
375 }
376 /*
377 * If the disk is unformatted or has no label
378 * use default database entry au current selection.
379 * Otherwise use current disk settings.
380 */
381 if (dp->formatted <= 0)
382 this = (deflt < 0) ? this : deflt;
383
384 for (i = 0; i < ndbentry; i++) {
385 if (df[0].disk.bridge_controller > 0)
386 bridge = TRUE;
387 }
388
389 max = 0;
390 if (autoformat) {
391 if (deflt < 0) {
392 /* Paranoia */
393 comerrno(EX_BAD,
394 "Die Datenbasis besitzt keine default Diskparameter fuer diese Platte.\n");
395 /* NOTREACHED */
396 }
397 use_disk(dp, df, this = deflt);
398 } else do {
399 if (xdebug) printf("found: %d deflt: %d this: %d match: %d\n",
400 found, deflt, this, match);
401
402 if ((deflt >= 0) && (deflt != this)) {
403 printf("WARNING: disk settings differ from default\n");
404 selected = TRUE;
405 }
406 if (found > ndbentry) {
407 printf("WARNING: disk settings differ from all database entries\n");
408 if (bridge) {
409 printf("\tThis may because an unknown disk is connected to the controller\n");
410 printf("\tor because the current disk is not formatted as noted in database.\n");
411 printf("\tIf this is an unknown disk, use the current parameters ...\n");
412 printf("\totherwise:\n");
413 }
414 printf("\tCheck if you really want the disk settings to be\n");
415 printf("\tdifferent from the settings in the database entry.\n");
416 selected = TRUE;
417 }
418 if ((found > 1 && deflt < 0) ||
419 (found > 1 && (selected ||
420 yes("Select alternate disk type? ")))) {
421 printf("Available disk types:\n");
422 for (i = 0; i < found; i++) {
423 printf("%s%2d)%s%s(%2d)\t\"%s\"\n",
424 i == this ? "*":" ",
425 i,
426 i == deflt ? "+":" ",
427 i == match ? "~":" ",
428 df[i].match,
429 df[i].name);
430 }
431 if (max++ == 0 && ndbentry == 1 && found > 1 &&
432 !yes("Don't use database entry or view selection? ")) {
433 this = 0; /* The one and only database entry */
434 selected = FALSE;
435 } else {
436 getint("Select disk", &this, 0, found - 1);
437 selected = TRUE;
438 }
439 }
440 use_disk(dp, df, this);
441
442 if (found > 1 && selected)
443 prdisk(stdout, dp, scgp->inq);
444
445 } while (selected && found > 1 && !yes("Use this disk parameters? "));
446
447 if (deflt < 0)
448 deflt = 0;
449 if (this >= ndbentry) {
450 printf("WARNING: using non database entry\n");
451 printf("If you deny the next question there will be no label from data base.\n");
452 if (yes("Use label list from default entry? ")) {
453 dp->disk_type = permstring(df[deflt].name);
454 dp->default_part = df[deflt].disk.default_part;
455 }
456 if (dp->mode_pages == 0 && df[deflt].disk.mode_pages) {
457 printf("If you deny the next question there will be no mode pages from data base.\n");
458 if (yes("Use mode page list from default entry? "))
459 dp->mode_pages = df[deflt].disk.mode_pages;
460 }
461 }
462 }
463
464 EXPORT BOOL
get_ext_diskdata(scgp,name,dp)465 get_ext_diskdata(scgp, name, dp)
466 SCSI *scgp;
467 char *name;
468 struct disk *dp;
469 {
470 int found = 0;
471 int inq_found = 0; /* Vendor & Product */
472 int firmw_found = 0; /* Vendor & Product & Firmware */
473 BOOL ign_firmw = FALSE;
474 int deflt = -1;
475 char nbuf[512];
476 struct dsk_fnd *disks_found;
477
478 again:
479 if (rewinddatfile() < 0)
480 return (FALSE);
481
482 if (xdebug)
483 printf("scan for disk: %.28s\n", name);
484
485 disks_found = (struct dsk_fnd *) malloc(sizeof (struct dsk_fnd));
486 disk_null(&disks_found[found].disk, 1);
487
488 /*
489 * scan for next disk entry
490 */
491 while (scanfortable("disk_type", NULL)) {
492 int i;
493 strcpy(nbuf, curword());
494 /*
495 * parse current disk entry and tell if it matched
496 */
497 switch (i = do_disk(name, &disks_found[found].disk, ign_firmw)) {
498
499 case D_INQ_FOUND|D_FIRMW_FOUND:
500 firmw_found++;
501 disks_found[found].disk.flags |=
502 D_INQ_FOUND|D_FIRMW_FOUND;
503 if (add_disk(nbuf, dp, &disks_found[found])) {
504 check_deflt(&disks_found[found], &deflt, found);
505 disks_found[found].disk.flags |=
506 D_DISK_FOUND;
507 found++;
508 disks_found = expand_df(disks_found, found);
509 }
510 break;
511 case D_INQ_FOUND:
512 inq_found++;
513 /*
514 * Don't increment found here,
515 * we must not use this entry.
516 */
517 break;
518 default:
519 printf("illegal return code %X from do_disk()\n", i);
520 case 0: break;
521 }
522 }
523 if (found) {
524 /*
525 * Wenn nur ein Eintrag vorhanden ist, dann ist er
526 * in jedem Fall der Default Eintrag.
527 */
528 if (found == 1)
529 deflt = 0;
530 printf("Default Disk type: '%s'\n",
531 deflt < 0 ? "none" : disks_found[deflt].name);
532 if (deflt < 0 && autoformat) {
533 comerrno(EX_BAD,
534 "Die Datenbasis besitzt keine default Diskparameter fuer diese Platte.\n");
535 /* NOTREACHED */
536 }
537 if (deflt >= 0 && disks_found[deflt].disk.default_part) {
538 printf("Default partition: '%s'\n",
539 disks_found[deflt].disk.default_part);
540 } else if (autoformat) {
541 comerrno(EX_BAD,
542 "Die Datenbasis besitzt keine default Partition fuer diese Platte.\n");
543 /* NOTREACHED */
544 }
545 if (deflt >= 0 && disks_found[deflt].disk.mode_pages) {
546 printf("Mode Pages: '%s'\n",
547 disks_found[deflt].disk.mode_pages);
548 }
549 if (autoformat ||
550 !yes("Ignore database disk parameters from '%s'? ",
551 datfilename())) {
552 select_disk(scgp, dp, disks_found, found, deflt);
553 free(disks_found);
554 return (TRUE);
555 }
556 } else if (autoformat) {
557 /* EMPTY */ ; /* Checked below */
558 } else if (firmw_found) {
559 errmsgno(EX_BAD,
560 "WARNING: Inquiry OK (%d controller matches) but no disk found.\n", firmw_found);
561 } else if (inq_found) {
562 errmsgno(EX_BAD,
563 "WARNING: Inquiry OK (%d controller matches) but no matching firmware found.\n", inq_found);
564 if (yes("Try to use entry for other firmware? ")) {
565 ign_firmw = TRUE;
566 goto again;
567 } else {
568 /*
569 * Report that we found vendor & product.
570 */
571 dp->flags |= D_INQ_FOUND;
572 }
573 }
574 if (autoformat) {
575 comerrno(EX_BAD,
576 "Diese Platte besitzt keine Produktfreigabe.\n");
577 /* NOTREACHED */
578 }
579 free(disks_found);
580 return (FALSE);
581 }
582
583
584 /*---------------------------------------------------------------------------
585 |
586 | Parst einen Disk Eintrag in der Steuerungsdatei
587 | Returnwert zeigt an, ob dieser Eintrag passend war.
588 |
589 +---------------------------------------------------------------------------*/
590
591 LOCAL int
do_disk(name,dp,ign_firmw)592 do_disk(name, dp, ign_firmw)
593 char *name;
594 struct disk *dp;
595 BOOL ign_firmw;
596 {
597 char inqname[80];
598 char defpart[80];
599 char mpages[80];
600 int ret = 0;
601
602 disk_null(dp, 0);
603 if (xdebug) printf("do_disk: line: %d curword: '%s'\n",
604 getlineno(), curword());
605 (void) garbage(skipwhite(peekword()));
606 if (!nextline())
607 return (FALSE);
608
609 while (scanforline(NULL, NULL) != NULL) {
610 if ((ret & D_FIRMW_FOUND) == 0)
611 inqname[0] = defpart[0] = mpages[0] = 0;
612
613 set_diskitem(dp, inqname, defpart, mpages);
614 if ((ret & D_FIRMW_FOUND) == 0 && *inqname) {
615 if (xdebug) {
616 printf("name: %.28s\n", name);
617 printf("DATA: %.28s\n", inqname);
618 }
619 /*
620 * allow short inquiry entry in database
621 * to match i.e. all firmware
622 */
623 if (strncmp(name, inqname, strlen(inqname)) == 0)
624 ret = D_INQ_FOUND|D_FIRMW_FOUND;
625 else if (strncmp(name, inqname, 24) == 0) {
626 ret = D_INQ_FOUND;
627 if (ign_firmw)
628 ret |= D_FIRMW_FOUND;
629 }
630 }
631 }
632 if (past_df_sig())
633 dp->flags = D_DB_BAD;
634 if (dp->fmt_time > 0)
635 dp->flags |= D_FTIME_FOUND;
636 if (dp->veri_time > 0)
637 dp->flags |= D_VTIME_FOUND;
638
639 if (ret & D_FIRMW_FOUND) {
640 if (xdebug)
641 printf("defpart: '%s' mpages: '%s'\n", defpart, mpages);
642 if (defpart[0])
643 dp->default_part = permstring(defpart);
644 if (mpages[0])
645 dp->mode_pages = permstring(mpages);
646 }
647 return (ret);
648 }
649
650 LOCAL void
set_diskitem(dp,inqname,defpart,mpages)651 set_diskitem(dp, inqname, defpart, mpages)
652 struct disk *dp;
653 char *inqname;
654 char *defpart;
655 char *mpages;
656 {
657 char *word;
658
659 for (word = curword(); *word; word = nextword()) {
660 if (streql(word, ":"))
661 continue;
662 if (streql(word, "inquiry")) {
663 if (!set_stringvar("Inquiry Name", inqname, 28))
664 break;
665 } else if (streql(word, "default_partition")) {
666 if (!set_stringvar("Partition Name", defpart, 79))
667 break;
668 } else if (streql(word, "mode_pages")) {
669 if (!set_stringvar("Modepage Name", mpages, 79))
670 break;
671 } else if (!set_diskvar(word, dp))
672 break;
673 }
674 (void) nextword();
675 }
676
677 LOCAL BOOL
set_diskvar(word,dp)678 set_diskvar(word, dp)
679 char *word;
680 struct disk *dp;
681 {
682 register struct keyw *kp = keyw;
683
684 long *valp = (long *)0;
685 long l;
686
687 if (xdebug) printf("diskvar: '%s' : ", word);
688
689 for (; kp < keywNKEYW; kp++) {
690 if ((kp->name != NULL) &&
691 ((kp->flags & (K_LABEL|K_NDB)) == 0) &&
692 streql(word, kp->name)) {
693 valp = lfld(dp, kp->off);
694 break;
695 }
696 }
697
698 if (kp >= keywNKEYW) {
699 skip_illvar("disk", word);
700 return (FALSE);
701 }
702
703 if (!checkequal())
704 return (FALSE);
705
706 if (!isval(word = nextword()))
707 return (FALSE);
708 if (kp->flags & K_BOOL) {
709 if (streql(word, "TRUE")) {
710 l = TRUE;
711 } else if (streql(word, "FALSE")) {
712 l = FALSE;
713 } else {
714 datfileerr("%s: not a bool '%s'", kp->name, word);
715 return (FALSE);
716 }
717 } else if (*astol(word, &l) != '\0') {
718 datfileerr("%s: not a number '%s'", kp->name, word);
719 return (FALSE);
720 }
721 *valp = l;
722
723 if (xdebug) printf("%ld\n", *valp);
724 return (TRUE);
725 }
726
727 LOCAL void
copy_disk(from,to)728 copy_disk(from, to)
729 register struct disk *from;
730 register struct disk *to;
731 {
732 register struct keyw *kp = keyw;
733
734 for (; kp < keywNKEYW; kp++) {
735 if (kp->flags & K_COPY)
736 *lfld(to, kp->off) = *lfld(from, kp->off);
737 else if (kp->flags & K_INIT) {
738 if (*lfld(from, kp->off) >= 0)
739 *lfld(to, kp->off) = *lfld(from, kp->off);
740 }
741 }
742
743 to->flags |= from->flags;
744
745 if (from->disk_type) {
746 to->disk_type = from->disk_type;
747 }
748 if (from->default_part) {
749 if (to->default_part)
750 free(to->default_part);
751 to->default_part = from->default_part;
752 }
753 if (from->mode_pages) {
754 if (to->mode_pages)
755 free(to->mode_pages);
756 to->mode_pages = from->mode_pages;
757 }
758 if (from->parts) {
759 /*XXX*/
760 to->parts = from->parts;
761 }
762 if (from->bridge_controller > 0) {
763 to->bridge_controller = TRUE;
764 }
765 }
766
767 EXPORT int
cmp_disk(dp1,dp2)768 cmp_disk(dp1, dp2)
769 register struct disk *dp1;
770 register struct disk *dp2;
771 {
772 register struct keyw *kp = keyw;
773 register int n = 0;
774
775 for (; kp < keywNKEYW; kp++) {
776 if ((kp->flags & (K_NONE|K_IGN)) == 0 &&
777 *lfld(dp1, kp->off) >= 0 &&
778 *lfld(dp1, kp->off) == *lfld(dp2, kp->off)) {
779 n++;
780 } else {
781 if (xdebug == 0)
782 continue;
783
784 if (*lfld(dp1, kp->off) == -1)
785 continue;
786 printf("name:%-16s off:%3d flags:%02X 1:%9ld 2:%9ld\n",
787 kp->name, kp->off, kp->flags,
788 *lfld(dp1, kp->off), *lfld(dp2, kp->off));
789 }
790 }
791 return (n);
792 }
793
794 LOCAL BOOL
disk_eql(dp1,dp2)795 disk_eql(dp1, dp2)
796 register struct disk *dp1;
797 register struct disk *dp2;
798 {
799 register struct keyw *kp = keyw;
800 register int diffs = 0;
801
802 /*
803 * Zwei Platten sind gleich, wenn alle in beiden Strukturen definierten
804 * d.h. != -1 Felder gleich sind.
805 */
806 for (; kp < keywNKEYW; kp++) {
807 if ((kp->flags & (K_NONE|K_LABEL|K_IGN)) == 0 &&
808 *lfld(dp1, kp->off) >= 0 &&
809 *lfld(dp2, kp->off) >= 0 &&
810 *lfld(dp1, kp->off) != *lfld(dp2, kp->off)) {
811 if (xdebug)
812 printf("not equal: %-10s %ld != %ld\n",
813 kp->name,
814 *lfld(dp1, kp->off), *lfld(dp2, kp->off));
815 diffs++;
816 }
817 }
818 if (xdebug)
819 printf("total of %d diff%s.\n", diffs, diffs > 1?"s":"");
820 return (diffs == 0);
821 }
822
823 EXPORT BOOL
has_error_rec_params(dp)824 has_error_rec_params(dp)
825 register struct disk *dp;
826 {
827 if (dp->rd_retry_count >= 0 ||
828 dp->wr_retry_count >= 0 ||
829 dp->recov_timelim >= 0) {
830 return (TRUE);
831 }
832 return (FALSE);
833 }
834
835 EXPORT BOOL
has_disre_params(dp)836 has_disre_params(dp)
837 register struct disk *dp;
838 {
839 if (dp->buf_full_ratio >= 0 ||
840 dp->buf_empt_ratio >= 0 ||
841 dp->bus_inact_limit >= 0 ||
842 dp->disc_time_limit >= 0 ||
843 dp->conn_time_limit >= 0 ||
844 dp->max_burst_size >= 0 ||
845 dp->data_tr_dis_ctl >= 0) {
846 return (TRUE);
847 }
848 return (FALSE);
849 }
850
851
852 LOCAL void
copy_vendor_info(s,ip)853 copy_vendor_info(s, ip)
854 char *s;
855 struct scsi_inquiry *ip;
856 {
857 sprintf(s, "CURRENT %.28s", ip->inq_vendor_info);
858 }
859
860 EXPORT void
prdisk(f,dp,ip)861 prdisk(f, dp, ip)
862 register FILE *f;
863 register struct disk *dp;
864 register struct scsi_inquiry *ip;
865 {
866 int neednl = 0;
867
868 fprintf(f, "disk_type = \"%s\"\n", dp->disk_type);
869 fprintf(f, "\tinquiry = \"%.28s\" :\n", ip->inq_vendor_info);
870 if (dp->bridge_controller > 0)
871 fprintf(f, "\tbridge_controller = TRUE :\n");
872 #ifdef nono
873 if (dp->fmt_time <= 0 || dp->veri_time <= 0)
874 estimate_times(dp);
875 #endif
876 if (dp->fmt_time > 0) {
877 fprintf(f, "\tfmt_time = %ld :", dp->fmt_time);
878 neednl++;
879 }
880
881 if (dp->veri_time > 0) {
882 fprintf(f, "%sveri_time = %ld :",
883 neednl?" ":"\t", dp->veri_time);
884 neednl++;
885 }
886 if (neednl)
887 fprintf(f, "\n");
888 neednl = 0;
889
890 fprintf(f, "\tnhead = %ld : ", dp->nhead);
891 fprintf(f, "pcyl = %ld : ", dp->pcyl);
892 fprintf(f, "spt = %ld : ", dp->spt);
893 fprintf(f, "secsize = %ld :\n", dp->secsize);
894
895 if (dp->reduced_curr >= 0 ||
896 dp->write_precomp >= 0 || dp->step_rate >= 0) {
897 fprintf(f, "\treduced_curr = %ld : ", dp->reduced_curr);
898 fprintf(f, "write_precomp = %ld : ", dp->write_precomp);
899 fprintf(f, "step_rate = %ld :\n", dp->step_rate);
900 }
901 if (dp->atrk > 0 || dp->tpz != 1 || dp->aspz > 0) {
902 fprintf(f, "\tatrk = %ld : ", dp->atrk);
903 fprintf(f, "tpz = %ld : ", dp->tpz);
904 fprintf(f, "aspz = %ld : ", dp->aspz);
905 neednl++;
906 }
907 if (dp->phys_secsize > 0 && dp->phys_secsize != dp->secsize) {
908 fprintf(f, "phys_secsize = %ld :", dp->phys_secsize);
909 neednl++;
910 }
911 if (neednl)
912 fprintf(f, "\n");
913 if (dp->cur_capacity > 0) {
914 fprintf(f, "\tcapacity = %ld :\n", dp->cur_capacity);
915 }
916 if (dp->track_skew > 0 || dp->cyl_skew > 0) {
917 fprintf(f, "\ttrack_skew = %ld : ", dp->track_skew);
918 fprintf(f, "cyl_skew = %ld :\n", dp->cyl_skew);
919 }
920 if (dp->fmt_mode >= 0 || dp->spare_band_size >= 0) {
921 fprintf(f, "\tfmt_mode = %ld : ", dp->fmt_mode);
922 fprintf(f, "spare_band_size = %ld :\n", dp->spare_band_size);
923 }
924 if (dp->def_lst_format >= 0 && dp->def_lst_format != SC_DEF_BLOCK) {
925 fprintf(f, "\tdef_lst_format = %ld :\n", dp->def_lst_format);
926 }
927 if (dp->split_wv_cmd > 0) {
928 fprintf(f, "\tsplit_wv_cmd = %s :\n",
929 dp->split_wv_cmd?"TRUE":"FALSE");
930 }
931 neednl = 0;
932 if (dp->queue_alg_mod >= 0) {
933 fprintf(f, "\tqueue_alg_mod = %ld :", dp->queue_alg_mod);
934 neednl++;
935 }
936 if (dp->dis_queuing > 0) {
937 fprintf(f, "%sdis_queuing = TRUE :", neednl?" ":"\t");
938 neednl++;
939 }
940 if (neednl)
941 fprintf(f, "\n");
942
943 fprintf(f, "\tinterleave = %ld : ", dp->interleave);
944 fprintf(f, "rpm = %ld :", dp->rpm);
945 if (dp->fmt_pattern > 0)
946 fprintf(f, " fmt_pattern = %ld :", dp->fmt_pattern);
947 fprintf(f, "\n");
948
949 if (has_error_rec_params(dp)) {
950 int n = 0;
951
952 fprintf(f, "\t");
953 if (dp->rd_retry_count >= 0) {
954 fprintf(f, "rd_retry_count = %ld :",
955 dp->rd_retry_count);
956 n++;
957 }
958 if (dp->wr_retry_count >= 0) {
959 fprintf(f, "%swr_retry_count = %ld :", n ? " " : "",
960 dp->wr_retry_count);
961 n++;
962 }
963 if (dp->recov_timelim >= 0) {
964 fprintf(f, "%srecov_timelim = %ld :", n ? " " : "",
965 dp->recov_timelim);
966 n++;
967 }
968 fprintf(f, "\n");
969 }
970 if (has_disre_params(dp)) {
971 int n = -1;
972
973 fprintf(f, "\t");
974 if (dp->buf_full_ratio >= 0) {
975 n++;
976 fprintf(f, "buf_full_ratio = %ld :",
977 dp->buf_full_ratio);
978 }
979 if (dp->buf_empt_ratio >= 0) {
980 n++;
981 fprintf(f, "%sbuf_empt_ratio = %ld :", n ? " " : "",
982 dp->buf_empt_ratio);
983 }
984 if (dp->bus_inact_limit >= 0) {
985 if (++n >= 3) { fprintf(f, "\n\t"); n = 0; }
986
987 fprintf(f, "%sbus_inact_limit = %ld :", n ? " " : "",
988 dp->bus_inact_limit);
989 }
990 if (dp->disc_time_limit >= 0) {
991 if (++n >= 3) { fprintf(f, "\n\t"); n = 0; }
992
993 fprintf(f, "%sdisc_time_limit = %ld :", n ? " " : "",
994 dp->disc_time_limit);
995 }
996 if (dp->conn_time_limit >= 0) {
997 if (++n >= 3) { fprintf(f, "\n\t"); n = 0; }
998
999 fprintf(f, "%sconn_time_limit = %ld :", n ? " " : "",
1000 dp->conn_time_limit);
1001 }
1002 if (dp->max_burst_size >= 0) {
1003 if (++n >= 3) { fprintf(f, "\n\t"); n = 0; }
1004
1005 fprintf(f, "%smax_burst_size = %ld :", n ? " " : "",
1006 dp->max_burst_size);
1007 }
1008 if (dp->data_tr_dis_ctl >= 0) {
1009 if (++n >= 3) { fprintf(f, "\n\t"); n = 0; }
1010
1011 fprintf(f, "%sdata_tr_dis_ctl = %ld :", n ? " " : "",
1012 dp->data_tr_dis_ctl);
1013 }
1014 fprintf(f, "\n");
1015 }
1016
1017 fprintf(f, "\tdefault_partition = \"%s\" :\n\n", dp->default_part);
1018 }
1019
1020 EXPORT int
need_params(dp,type)1021 need_params(dp, type)
1022 register struct disk *dp;
1023 register int type;
1024 {
1025 register struct keyw *kp = keyw;
1026 register int n = 0;
1027
1028 for (; kp < keywNKEYW; kp++) {
1029 if ((kp->flags & K_N) != 0)
1030 continue;
1031 if ((kp->flags & type) == 0)
1032 continue;
1033
1034 if (*lfld(dp, kp->off) != -1)
1035 continue;
1036 n++;
1037 /* if (xdebug == 0)*/
1038 /* continue;*/
1039
1040 printf("name:%-16s off:%3d flags:%02X == -1\n",
1041 kp->name, kp->off, kp->flags);
1042 }
1043 return (n);
1044 }
1045
1046 EXPORT int
need_label_params(dp)1047 need_label_params(dp)
1048 struct disk *dp;
1049 {
1050 return (need_params(dp, K_LABEL));
1051 }
1052
1053 EXPORT int
need_geom_params(dp)1054 need_geom_params(dp)
1055 struct disk *dp;
1056 {
1057 return (need_params(dp, K_GEOM));
1058 }
1059
1060 EXPORT int
need_scsi_params(dp)1061 need_scsi_params(dp)
1062 struct disk *dp;
1063 {
1064 return (need_params(dp, K_SCSI));
1065 }
1066
1067 /* NOT NEEDED */
1068 EXPORT int
need_error_rec_params(dp)1069 need_error_rec_params(dp)
1070 struct disk *dp;
1071 {
1072 return (need_params(dp, K_ERREC));
1073 }
1074
1075 /* NOT NEEDED */
1076 EXPORT int
need_disre_params(dp)1077 need_disre_params(dp)
1078 struct disk *dp;
1079 {
1080 return (need_params(dp, K_DISRE));
1081 }
1082