]> git.proxmox.com Git - mirror_smartmontools-debian.git/blob - knowndrives.cpp
Imported smartmontools-5.37.cvs20061111
[mirror_smartmontools-debian.git] / knowndrives.cpp
1 /*
2 * knowndrives.cpp
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 * Address of support mailing list: smartmontools-support@lists.sourceforge.net
6 *
7 * Copyright (C) 2003-6 Philip Williams, Bruce Allen
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * You should have received a copy of the GNU General Public License
15 * (for example COPYING); if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20 #include "config.h"
21 #include "int64.h"
22 #include <stdio.h>
23 #include "atacmds.h"
24 #include "ataprint.h"
25 #include "extern.h"
26 #include "knowndrives.h"
27 #include "utility.h" // includes <regex.h>
28
29 const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.156 2006/10/30 22:35:28 pjwilliams Exp $"
30 ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
31
32 #define MODEL_STRING_LENGTH 40
33 #define FIRMWARE_STRING_LENGTH 8
34 #define TABLEPRINTWIDTH 19
35
36 // See vendorattributeargs[] array in atacmds.cpp for definitions.
37 #define PRESET_9_MINUTES { 9, 1 }
38 #define PRESET_9_TEMP { 9, 2 }
39 #define PRESET_9_SECONDS { 9, 3 }
40 #define PRESET_9_HALFMINUTES { 9, 4 }
41 #define PRESET_192_EMERGENCYRETRACTCYCLECT { 192, 1 }
42 #define PRESET_193_LOADUNLOAD { 193, 1 }
43 #define PRESET_194_10XCELSIUS { 194, 1 }
44 #define PRESET_194_UNKNOWN { 194, 2 }
45 #define PRESET_198_OFFLINESCANUNCSECTORCT { 198, 1 }
46 #define PRESET_200_WRITEERRORCOUNT { 200, 1 }
47 #define PRESET_201_DETECTEDTACOUNT { 201, 1 }
48 #define PRESET_220_TEMP { 220, 1 }
49
50 /* Arrays of preset vendor-specific attribute options for use in
51 * knowndrives[]. */
52
53 extern int64_t bytes;
54
55 // to hold onto exit code for atexit routine
56 extern int exitstatus;
57
58 // These three are common to several models.
59 const unsigned char vendoropts_9_minutes[][2] = {
60 PRESET_9_MINUTES,
61 {0,0}
62 };
63 const unsigned char vendoropts_9_halfminutes[][2] = {
64 PRESET_9_HALFMINUTES,
65 {0,0}
66 };
67 const unsigned char vendoropts_9_seconds[][2] = {
68 PRESET_9_SECONDS,
69 {0,0}
70 };
71
72 const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
73 PRESET_9_MINUTES,
74 PRESET_194_UNKNOWN,
75 {0,0}
76 };
77
78 const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
79 PRESET_9_SECONDS,
80 PRESET_192_EMERGENCYRETRACTCYCLECT,
81 PRESET_198_OFFLINESCANUNCSECTORCT,
82 PRESET_200_WRITEERRORCOUNT,
83 PRESET_201_DETECTEDTACOUNT,
84 {0,0}
85 };
86
87 const unsigned char vendoropts_Fujitsu_MHR2040AT[][2] = {
88 PRESET_9_SECONDS,
89 PRESET_192_EMERGENCYRETRACTCYCLECT,
90 PRESET_198_OFFLINESCANUNCSECTORCT,
91 PRESET_200_WRITEERRORCOUNT,
92 {0,0}
93 };
94
95 const unsigned char vendoropts_Samsung_SV4012H[][2] = {
96 PRESET_9_HALFMINUTES,
97 {0,0}
98 };
99
100 const unsigned char vendoropts_Samsung_SV1204H[][2] = {
101 PRESET_9_HALFMINUTES,
102 PRESET_194_10XCELSIUS,
103 {0,0}
104 };
105
106 const unsigned char vendoropts_Hitachi_DK23XX[][2] = {
107 PRESET_9_MINUTES,
108 PRESET_193_LOADUNLOAD,
109 {0,0}
110 };
111
112 const char same_as_minus_F[]="Fixes byte order in some SMART data (same as -F samsung)";
113 const char same_as_minus_F2[]="Fixes byte order in some SMART data (same as -F samsung2)";
114
115 const char may_need_minus_F_disabled[] ="May need -F samsung disabled; see manual for details.";
116 const char may_need_minus_F2_disabled[]="May need -F samsung2 disabled; see manual for details.";
117 const char may_need_minus_F2_enabled[] ="May need -F samsung2 enabled; see manual for details.";
118 const char may_need_minus_F_enabled[] ="May need -F samsung or -F samsung2 enabled; see manual for details.";
119
120 /* Special-purpose functions for use in knowndrives[]. */
121 void specialpurpose_reverse_samsung(smartmonctrl *con)
122 {
123 if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
124 con->fixfirmwarebug = FIX_SAMSUNG;
125 }
126 void specialpurpose_reverse_samsung2(smartmonctrl *con)
127 {
128 if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
129 con->fixfirmwarebug = FIX_SAMSUNG2;
130 }
131
132 /* Table of settings for known drives terminated by an element containing all
133 * zeros. The drivesettings structure is described in knowndrives.h. Note
134 * that lookupdrive() will search knowndrives[] from the start to end or
135 * until it finds the first match, so the order in knowndrives[] is important
136 * for distinct entries that could match the same drive. */
137
138 // Note that the table just below uses EXTENDED REGULAR EXPRESSIONS.
139 // A good on-line reference for these is:
140 // http://www.zeus.com/extra/docsystem/docroot/apps/web/docs/modules/access/regex.html
141
142 const drivesettings knowndrives[] = {
143 { "IBM Deskstar 60GXP series", // ER60A46A firmware
144 "(IBM-|Hitachi )?IC35L0[12346]0AVER07",
145 "^ER60A46A$",
146 NULL, NULL, NULL, NULL
147 },
148 { "IBM Deskstar 60GXP series", // All other firmware
149 "(IBM-|Hitachi )?IC35L0[12346]0AVER07",
150 ".*",
151 "IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
152 "Please see http://www.geocities.com/dtla_update/index.html#rel and\n"
153 "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
154 "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
155 NULL, NULL, NULL
156 },
157 { "IBM Deskstar 40GV & 75GXP series (A5AA/A6AA firmware)",
158 "(IBM-)?DTLA-30[57]0[123467][05]",
159 "^T[WX][123468AG][OF]A[56]AA$",
160 NULL, NULL, NULL, NULL
161 },
162 { "IBM Deskstar 40GV & 75GXP series (all other firmware)",
163 "(IBM-)?DTLA-30[57]0[123467][05]",
164 ".*",
165 "IBM Deskstar 40GV and 75GXP drives may need upgraded SMART firmware.\n"
166 "Please see http://www.geocities.com/dtla_update/ and\n"
167 "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
168 "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
169 NULL, NULL, NULL
170 },
171 { NULL, // ExcelStor J240, J340, J360, J680, and J880
172 "^ExcelStor Technology J(24|34|36|68|88)0$",
173 ".*",
174 NULL, NULL, NULL, NULL
175 },
176 { NULL, // Fujitsu M1623TAU
177 "^FUJITSU M1623TAU$",
178 ".*",
179 NULL,
180 vendoropts_9_seconds,
181 NULL, NULL
182 },
183 { "Fujitsu MHG series",
184 "^FUJITSU MHG2...ATU?",
185 ".*",
186 NULL,
187 vendoropts_9_seconds,
188 NULL, NULL
189 },
190 { "Fujitsu MHH series",
191 "^FUJITSU MHH2...ATU?",
192 ".*",
193 NULL,
194 vendoropts_9_seconds,
195 NULL, NULL
196 },
197 { "Fujitsu MHJ series",
198 "^FUJITSU MHJ2...ATU?",
199 ".*",
200 NULL,
201 vendoropts_9_seconds,
202 NULL, NULL
203 },
204 { "Fujitsu MHK series",
205 "^FUJITSU MHK2...ATU?",
206 ".*",
207 NULL,
208 vendoropts_9_seconds,
209 NULL, NULL
210 },
211 { NULL, // Fujitsu MHL2300AT
212 "^FUJITSU MHL2300AT$",
213 ".*",
214 "This drive's firmware has a harmless Drive Identity Structure\n"
215 "checksum error bug.",
216 vendoropts_9_seconds,
217 NULL, NULL
218 },
219 { NULL, // MHM2200AT, MHM2150AT, MHM2100AT, MHM2060AT
220 "^FUJITSU MHM2(20|15|10|06)0AT$",
221 ".*",
222 "This drive's firmware has a harmless Drive Identity Structure\n"
223 "checksum error bug.",
224 vendoropts_9_seconds,
225 NULL, NULL
226 },
227 { "Fujitsu MHN series",
228 "^FUJITSU MHN2...AT$",
229 ".*",
230 NULL,
231 vendoropts_9_seconds,
232 NULL, NULL
233 },
234 { NULL, // Fujitsu MHR2020AT
235 "^FUJITSU MHR2020AT$",
236 ".*",
237 NULL,
238 vendoropts_9_seconds,
239 NULL, NULL
240 },
241 { NULL, // Fujitsu MHR2040AT
242 "^FUJITSU MHR2040AT$",
243 ".*", // Tested on 40BA
244 NULL,
245 vendoropts_Fujitsu_MHR2040AT,
246 NULL, NULL
247 },
248 { "Fujitsu MHSxxxxAT family",
249 "^FUJITSU MHS20[6432]0AT( .)?$",
250 ".*",
251 NULL,
252 vendoropts_Fujitsu_MHS2020AT,
253 NULL, NULL
254 },
255 { "Fujitsu MHT series",
256 "^FUJITSU MHT2...(AH|AS|AT|BH)U?",
257 ".*",
258 NULL,
259 vendoropts_9_seconds,
260 NULL, NULL
261 },
262 { "Fujitsu MHU series",
263 "^FUJITSU MHU2...ATU?",
264 ".*",
265 NULL,
266 vendoropts_9_seconds,
267 NULL, NULL
268 },
269 { "Fujitsu MHV series",
270 "^FUJITSU MHV2...(AH|AS|AT|BH|BS|BT)",
271 ".*",
272 NULL,
273 vendoropts_9_seconds,
274 NULL, NULL
275 },
276 { "Fujitsu MPA..MPG series",
277 "^FUJITSU MP[A-G]3...A[HTEV]U?",
278 ".*",
279 NULL,
280 vendoropts_9_seconds,
281 NULL, NULL
282 },
283 { NULL, // Samsung SV4012H (known firmware)
284 "^SAMSUNG SV4012H$",
285 "^RM100-08$",
286 NULL,
287 vendoropts_Samsung_SV4012H,
288 specialpurpose_reverse_samsung,
289 same_as_minus_F
290 },
291 { NULL, // Samsung SV4012H (all other firmware)
292 "^SAMSUNG SV4012H$",
293 ".*",
294 may_need_minus_F_disabled,
295 vendoropts_Samsung_SV4012H,
296 specialpurpose_reverse_samsung,
297 same_as_minus_F
298 },
299 { NULL, // Samsung SV0412H (known firmware)
300 "^SAMSUNG SV0412H$",
301 "^SK100-01$",
302 NULL,
303 vendoropts_Samsung_SV1204H,
304 specialpurpose_reverse_samsung,
305 same_as_minus_F
306 },
307 { NULL, // Samsung SV0412H (all other firmware)
308 "^SAMSUNG SV0412H$",
309 ".*",
310 may_need_minus_F_disabled,
311 vendoropts_Samsung_SV1204H,
312 specialpurpose_reverse_samsung,
313 same_as_minus_F
314 },
315 { NULL, // Samsung SV1204H (known firmware)
316 "^SAMSUNG SV1204H$",
317 "^RK100-1[3-5]$",
318 NULL,
319 vendoropts_Samsung_SV1204H,
320 specialpurpose_reverse_samsung,
321 same_as_minus_F
322 },
323 { NULL, // Samsung SV1204H (all other firmware)
324 "^SAMSUNG SV1204H$",
325 ".*",
326 may_need_minus_F_disabled,
327 vendoropts_Samsung_SV1204H,
328 specialpurpose_reverse_samsung,
329 same_as_minus_F
330 },
331 { NULL, // SAMSUNG SV0322A tested with FW JK200-35
332 "^SAMSUNG SV0322A$",
333 ".*",
334 NULL,
335 NULL,
336 NULL,
337 NULL
338 },
339 { NULL, // SAMSUNG SP40A2H with RR100-07 firmware
340 "^SAMSUNG SP40A2H$",
341 "^RR100-07$",
342 NULL,
343 vendoropts_9_halfminutes,
344 specialpurpose_reverse_samsung,
345 same_as_minus_F
346 },
347 { NULL, // SAMSUNG SP8004H with QW100-61 firmware
348 "^SAMSUNG SP8004H$",
349 "^QW100-61$",
350 NULL,
351 vendoropts_9_halfminutes,
352 specialpurpose_reverse_samsung,
353 same_as_minus_F
354 },
355 { "SAMSUNG SpinPoint T133 series", // tested with HD300LJ/ZT100-12, HD400LJ/ZZ100-14, HD401LJ/ZZ100-15
356 "^SAMSUNG HD(250KD|(30[01]|320|40[01])L[DJ])$",
357 ".*",
358 NULL, NULL, NULL, NULL
359 },
360 { "SAMSUNG SpinPoint P120 series", // tested with SP2504C/VT100-33
361 "^SAMSUNG SP(16[01]3|2[05][01]4)[CN]$",
362 ".*",
363 NULL, NULL, NULL, NULL
364 },
365 { "SAMSUNG SpinPoint P80 SD series", // tested with HD160JJ/ZM100-33
366 "^SAMSUNG HD(080H|120I|160J)J$",
367 ".*",
368 NULL, NULL, NULL, NULL
369 },
370 { "SAMSUNG SpinPoint P80 series", // firmware *-26 or later, tested with SP1614C/SW100-34
371 "^SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]$",
372 ".*-(2[6789]|3[0-9])$",
373 NULL,
374 vendoropts_9_halfminutes,
375 NULL, NULL
376 },
377 {
378 NULL, // Any other Samsung disk with *-23 *-24 firmware
379 // SAMSUNG SP1213N (TL100-23 firmware)
380 // SAMSUNG SP0802N (TK100-23 firmware)
381 // Samsung SP1604N, tested with FW TM100-23 and TM100-24
382 "^SAMSUNG .*$",
383 ".*-2[34]$",
384 NULL,
385 vendoropts_Samsung_SV4012H,
386 specialpurpose_reverse_samsung2,
387 same_as_minus_F2
388 },
389 { NULL, // All Samsung drives with '.*-25' firmware
390 "^SAMSUNG.*",
391 ".*-25$",
392 may_need_minus_F2_disabled,
393 vendoropts_Samsung_SV4012H,
394 specialpurpose_reverse_samsung2,
395 same_as_minus_F2
396 },
397 { NULL, // All Samsung drives with '.*-26 or later (currently to -39)' firmware
398 "^SAMSUNG.*",
399 ".*-(2[6789]|3[0-9])$",
400 NULL,
401 vendoropts_Samsung_SV4012H,
402 NULL,
403 NULL
404 },
405 { NULL, // Samsung ALL OTHER DRIVES
406 "^SAMSUNG.*",
407 ".*",
408 may_need_minus_F_enabled,
409 NULL, NULL, NULL
410 },
411 { "Maxtor Fireball 541DX family",
412 "^Maxtor 2B0(0[468]|1[05]|20)H1$",
413 ".*",
414 NULL,
415 vendoropts_Maxtor_4D080H4,
416 NULL, NULL
417 },
418 { "Maxtor Fireball 3 family",
419 "^Maxtor 2F0[234]0[JL]0$",
420 ".*",
421 NULL,
422 vendoropts_9_minutes,
423 NULL, NULL
424 },
425 { "Maxtor DiamondMax 2160 Ultra ATA family",
426 "^Maxtor 8(2160D2|3228D3|3240D3|4320D4|6480D6|8400D8|8455D8)$",
427 ".*",
428 NULL,
429 vendoropts_9_minutes,
430 NULL, NULL
431 },
432 { "Maxtor DiamondMax 2880 Ultra ATA family",
433 "^Maxtor 9(0510D4|0576D4|0648D5|0720D5|0840D6|0845D6|0864D6|1008D7|1080D8|1152D8)$",
434 ".*",
435 NULL,
436 vendoropts_9_minutes,
437 NULL, NULL
438 },
439 { "Maxtor DiamondMax 3400 Ultra ATA family",
440 "^Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)$",
441 ".*",
442 NULL,
443 vendoropts_9_minutes,
444 NULL, NULL
445 },
446 { "Maxtor DiamondMax D540X-4G family",
447 "^Maxtor 4G(120J6|160J[68])$",
448 ".*",
449 NULL,
450 vendoropts_Maxtor_4D080H4,
451 NULL, NULL
452 },
453 { "Maxtor DiamondMax D540X-4K family",
454 "^MAXTOR 4K(020H1|040H2|060H3|080H4)$",
455 ".*",
456 NULL, NULL, NULL, NULL
457 },
458 { "Maxtor DiamondMax Plus D740X family",
459 "^MAXTOR 6L0(20[JL]1|40[JL]2|60[JL]3|80[JL]4)$",
460 ".*",
461 NULL, NULL, NULL, NULL
462 },
463 { "Maxtor DiamondMax Plus 5120 Ultra ATA 33 family",
464 "^Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)$",
465 ".*",
466 NULL,
467 vendoropts_9_minutes,
468 NULL, NULL
469 },
470 { "Maxtor DiamondMax Plus 6800 Ultra ATA 66 family",
471 "^Maxtor 9(2732U8|2390U7|2049U6|1707U5|1366U4|1024U3|0845U3|0683U2)$",
472 ".*",
473 NULL,
474 vendoropts_9_minutes,
475 NULL, NULL
476 },
477 { "Maxtor DiamondMax D540X-4D",
478 "^Maxtor 4D0(20H1|40H2|60H3|80H4)$",
479 ".*",
480 NULL,
481 vendoropts_Maxtor_4D080H4,
482 NULL, NULL
483 },
484 { "Maxtor DiamondMax 16 family",
485 "^Maxtor 4(R0[68]0[JL]0|R1[26]0L0|A160J0|R120L4)$",
486 ".*",
487 NULL,
488 vendoropts_9_minutes,
489 NULL, NULL
490 },
491 { "Maxtor DiamondMax 4320 Ultra ATA family",
492 "^Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D[34]|90432D2)$",
493 ".*",
494 NULL,
495 vendoropts_9_minutes,
496 NULL, NULL
497 },
498 { "Maxtor DiamondMax 17 VL family",
499 "^Maxtor 9(0431U1|0641U2|0871U2|1301U3|1741U4)$",
500 ".*",
501 NULL,
502 vendoropts_9_minutes,
503 NULL, NULL
504 },
505 { "Maxtor DiamondMax 20 VL family",
506 "^Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)$",
507 ".*",
508 NULL,
509 vendoropts_9_minutes,
510 NULL, NULL
511 },
512 { "Maxtor DiamondMax VL 30 family",
513 "^Maxtor (33073U4|32049U3|31536U2|30768U1)$",
514 ".*",
515 NULL,
516 vendoropts_9_minutes,
517 NULL, NULL
518 },
519 { "Maxtor DiamondMax 36 family",
520 "^Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)$",
521 ".*",
522 NULL,
523 vendoropts_9_minutes,
524 NULL, NULL
525 },
526 { "Maxtor DiamondMax 40 ATA 66 series",
527 "^Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)$",
528 ".*",
529 NULL,
530 vendoropts_9_minutes,
531 NULL, NULL
532 },
533 { "Maxtor DiamondMax Plus 40 series (Ultra ATA 66 and Ultra ATA 100)",
534 "^Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)$",
535 ".*",
536 NULL,
537 vendoropts_9_minutes,
538 NULL, NULL
539 },
540 { "Maxtor DiamondMax 40 VL Ultra ATA 100 series",
541 "^Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?$",
542 ".*",
543 NULL,
544 vendoropts_9_minutes,
545 NULL, NULL
546 },
547 { "Maxtor DiamondMax Plus 45 Ulta ATA 100 family",
548 "^Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)$",
549 ".*",
550 NULL,
551 vendoropts_9_minutes,
552 NULL, NULL
553 },
554 { "Maxtor DiamondMax 60 ATA 66 family",
555 "^Maxtor 9(1023U2|1536U2|2049U3|2305U3|3073U4|4610U6|6147U8)$",
556 ".*",
557 NULL,
558 vendoropts_9_minutes,
559 NULL, NULL
560 },
561 { "Maxtor DiamondMax 60 ATA 100 family",
562 "^Maxtor 9(1023H2|1536H2|2049H3|2305H3|3073H4|4610H6|6147H8)$",
563 ".*",
564 NULL,
565 vendoropts_9_minutes,
566 NULL, NULL
567 },
568 { "Maxtor DiamondMax Plus 60 family",
569 "^Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)$",
570 ".*",
571 NULL,
572 vendoropts_9_minutes,
573 NULL, NULL
574 },
575 { "Maxtor DiamondMax 80 family",
576 "^Maxtor (98196H8|96147H6)$",
577 ".*",
578 NULL,
579 vendoropts_9_minutes,
580 NULL, NULL
581 },
582 { "Maxtor DiamondMax 536DX family",
583 "^Maxtor 4W(100H6|080H6|060H4|040H3|030H2)$",
584 ".*",
585 NULL,
586 vendoropts_9_minutes,
587 NULL, NULL
588 },
589 { "Maxtor DiamondMax Plus 8 family",
590 "^Maxtor 6(E0[234]|K04)0L0$",
591 ".*",
592 NULL,
593 vendoropts_9_minutes,
594 NULL, NULL
595 },
596 { "Maxtor DiamondMax 10 family (ATA/133 and SATA/150)",
597 "^Maxtor 6(B(30|25|20|16|12|08)0[MPRS]|L(080[MLP]|(100|120)[MP]|160[MP]|200[MPRS]|250[RS]|300[RS]))0$",
598 ".*",
599 NULL,
600 vendoropts_9_minutes,
601 NULL, NULL
602 },
603 { "Maxtor DiamondMax 10 family (SATA/300)",
604 "^Maxtor 6V(080E|160E|200E|250F|300F|320F)0$",
605 ".*",
606 NULL, NULL, NULL, NULL
607 },
608 { "Maxtor DiamondMax Plus 9 family",
609 "^Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)$",
610 ".*",
611 NULL,
612 vendoropts_9_minutes,
613 NULL, NULL
614 },
615 { "Maxtor DiamondMax 11 family",
616 "^Maxtor 6H[45]00[FR]0$",
617 ".*",
618 NULL, NULL, NULL, NULL
619 },
620 { "Maxtor MaXLine Plus II",
621 "^Maxtor 7Y250[PM]0$",
622 ".*",
623 NULL,
624 vendoropts_9_minutes,
625 NULL, NULL
626 },
627 { "Maxtor MaXLine II family",
628 "^Maxtor [45]A(25|30|32)0[JN]0$",
629 ".*",
630 NULL,
631 vendoropts_9_minutes,
632 NULL, NULL
633 },
634 { "Maxtor MaXLine III family (ATA/133 and SATA/150)",
635 "^Maxtor 7L(25|30)0[SR]0$",
636 ".*",
637 NULL,
638 vendoropts_9_minutes,
639 NULL, NULL
640 },
641 { "Maxtor MaXLine III family (SATA/300)",
642 "^Maxtor 7V(25|30)0F0$",
643 ".*",
644 NULL, NULL, NULL, NULL
645 },
646 { "Maxtor MaXLine Pro 500 family", // There is also a 7H500R0 model, but I
647 "^Maxtor 7H500F0$", // haven't added it because I suspect
648 ".*", // it might need vendoropts_9_minutes
649 NULL, NULL, NULL, NULL // and nobody has submitted a report yet
650 },
651 { NULL, // HITACHI_DK14FA-20B
652 "^HITACHI_DK14FA-20B$",
653 ".*",
654 NULL,
655 vendoropts_Hitachi_DK23XX,
656 NULL, NULL
657 },
658 { "HITACHI Travelstar DK23XX/DK23XXB series",
659 "^HITACHI_DK23..-..B?$",
660 ".*",
661 NULL,
662 vendoropts_Hitachi_DK23XX,
663 NULL, NULL
664 },
665 { "Hitachi Endurastar J4K20/N4K20 (formerly DK23FA-20J)",
666 "^(HITACHI_DK23FA-20J|HTA422020F9AT[JN]0)$",
667 ".*",
668 NULL,
669 vendoropts_Hitachi_DK23XX,
670 NULL, NULL
671 },
672 { "IBM Deskstar 14GXP and 16GP series",
673 "^IBM-DTTA-3(7101|7129|7144|5032|5043|5064|5084|5101|5129|5168)0$",
674 ".*",
675 NULL, NULL, NULL, NULL
676 },
677 { "IBM Deskstar 25GP and 22GXP family",
678 "^IBM-DJNA-3(5(101|152|203|250)|7(091|135|180|220))0$",
679 ".*",
680 NULL, NULL, NULL, NULL
681 },
682 { "IBM Travelstar 4GT family",
683 "^IBM-DTCA-2(324|409)0$",
684 ".*",
685 NULL, NULL, NULL, NULL
686 },
687 { "IBM Travelstar 25GS, 18GT, and 12GN family",
688 "^IBM-DARA-2(25|18|15|12|09|06)000$",
689 ".*",
690 NULL, NULL, NULL, NULL
691 },
692 { "IBM Travelstar 48GH, 30GN, and 15GN family",
693 "^(IBM-|Hitachi )?IC25(T048ATDA05|N0(30|20|15|12|10|07|06|05)ATDA04)-.$",
694 ".*",
695 NULL, NULL, NULL, NULL
696 },
697 { "IBM Travelstar 32GH, 30GT, and 20GN family",
698 "^IBM-DJSA-2(32|30|20|10|05)$",
699 ".*",
700 NULL, NULL, NULL, NULL
701 },
702 { "IBM Travelstar 4GN family",
703 "^IBM-DKLA-2(216|324|432)0$",
704 ".*",
705 NULL, NULL, NULL, NULL
706 },
707 { "IBM Deskstar 37GP and 34GXP family",
708 "^IBM-DPTA-3(5(375|300|225|150)|7(342|273|205|136))0$",
709 ".*",
710 NULL, NULL, NULL, NULL
711 },
712 { "IBM/Hitachi Travelstar 60GH and 40GN family",
713 "^(IBM-|Hitachi )?IC25(T060ATC[SX]05|N0[4321]0ATC[SX]04)-.$",
714 ".*",
715 NULL, NULL, NULL, NULL
716 },
717 { "IBM/Hitachi Travelstar 40GNX family",
718 "^(IBM-|Hitachi )?IC25N0[42]0ATC[SX]05-.$",
719 ".*",
720 NULL, NULL, NULL, NULL
721 },
722 { "Hitachi Travelstar 80GN family",
723 "^(Hitachi )?IC25N0[23468]0ATMR04-.$",
724 ".*",
725 NULL, NULL, NULL, NULL
726 },
727 { "Hitachi Travelstar 5K80 family",
728 "^HTS5480[8642]0M9AT00$",
729 ".*",
730 NULL, NULL, NULL, NULL
731 },
732 { "Hitachi Travelstar 5K100 series",
733 "^HTS5410[1864]0G9(AT|SA)00$",
734 ".*",
735 NULL, NULL, NULL, NULL
736 },
737 { "Hitachi Travelstar E5K100 series",
738 "^HTE541040G9(AT|SA)00$",
739 ".*",
740 NULL, NULL, NULL, NULL
741 },
742 { "Hitachi Travelstar 7K60",
743 "^HTS726060M9AT00$",
744 ".*",
745 NULL, NULL, NULL, NULL
746 },
747 { "Hitachi Travelstar 7K100",
748 "^HTS7210[168]0G9(AT|SA)00$",
749 ".*",
750 NULL, NULL, NULL, NULL
751 },
752 { "Hitachi Travelstar E7K100",
753 "^HTE7210[168]0G9(AT|SA)00$",
754 ".*",
755 NULL, NULL, NULL, NULL
756 },
757 { "Hitachi Travelstar E7K60 family",
758 "^HTE7260[46]0M9AT00$",
759 ".*",
760 NULL, NULL, NULL, NULL
761 },
762 { "IBM/Hitachi Deskstar 120GXP family",
763 "^(IBM-)?IC35L((020|040|060|080|120)AVVA|0[24]0AVVN)07-[01]$",
764 ".*",
765 NULL, NULL, NULL, NULL
766 },
767 { "IBM/Hitachi Deskstar GXP-180 family",
768 "^(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]$",
769 ".*",
770 NULL, NULL, NULL, NULL
771 },
772 { "IBM Travelstar 14GS",
773 "^IBM-DCYA-214000$",
774 ".*",
775 NULL, NULL, NULL, NULL
776 },
777 { "IBM Travelstar 4LP",
778 "^IBM-DTNA-2(180|216)0$",
779 ".*",
780 NULL, NULL, NULL, NULL
781 },
782 { "Hitachi Deskstar 7K80 series",
783 "^(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380)$",
784 ".*",
785 NULL, NULL, NULL, NULL
786 },
787 { "Hitachi Deskstar 7K250 series",
788 "^(Hitachi )?HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)$",
789 ".*",
790 NULL, NULL, NULL, NULL
791 },
792 { "Hitachi Deskstar T7K250 series",
793 "^(Hitachi )?HDT7225((25|20|16)DLA(T80|380))$",
794 ".*",
795 NULL, NULL, NULL, NULL
796 },
797 { "Hitachi Deskstar 7K400 series",
798 "^(Hitachi )?HDS724040KL(AT|SA)80$",
799 ".*",
800 NULL, NULL, NULL, NULL
801 },
802 { "Hitachi Deskstar 7K500 series",
803 "^(Hitachi )?HDS725050KLA(360|T80)$",
804 ".*",
805 NULL, NULL, NULL, NULL
806 },
807 { "Toshiba 2.5\" HDD series (30-60 GB)",
808 "^TOSHIBA MK((6034|4032)GSX|(6034|4032)GAX|(6026|4026|4019|3019)GAXB?|(6025|6021|4025|4021|4018|3021|3018)GAS|(4036|3029)GACE?|(4018|3017)GAP)$",
809 ".*",
810 NULL, NULL, NULL, NULL
811 },
812 { "Toshiba 2.5\" HDD series (80 GB and above)",
813 "^TOSHIBA MK(80(25GAS|26GAX|32GAX|32GSX)|10(31GAS|32GAX)|12(33GAS|34G[AS]X)|2035GSS)$",
814 ".*",
815 NULL, NULL, NULL, NULL
816 },
817 { NULL, // TOSHIBA MK6022GAX
818 "^TOSHIBA MK6022GAX$",
819 ".*",
820 NULL, NULL, NULL, NULL
821 },
822 { NULL, // TOSHIBA MK6409MAV
823 "^TOSHIBA MK6409MAV$",
824 ".*",
825 NULL, NULL, NULL, NULL
826 },
827 { NULL, // TOS MK3019GAXB SUN30G
828 "^TOS MK3019GAXB SUN30G$",
829 ".*",
830 NULL, NULL, NULL, NULL
831 },
832 { NULL, // TOSHIBA MK2016GAP, MK2017GAP, MK2018GAP, MK2018GAS, MK2023GAS
833 "^TOSHIBA MK20(1[678]GAP|(18|23)GAS)$",
834 ".*",
835 NULL, NULL, NULL, NULL
836 },
837 { "Seagate Momentus family",
838 "^ST9(20|28|40|48)11A$",
839 ".*",
840 NULL, NULL, NULL, NULL
841 },
842 { "Seagate Momentus 42 family",
843 "^ST9(2014|3015|4019)A$",
844 ".*",
845 NULL, NULL, NULL, NULL
846 },
847 { "Seagate Momentus 4200.2 Series",
848 "^ST9(100822|808210|60821|50212|402113|30219)A$",
849 ".*",
850 NULL, NULL, NULL, NULL
851 },
852 { "Seagate Momentus 5400.2 series",
853 "^ST9(808211|60822|408114|308110|120821|10082[34]|8823|6812|4813|3811)AS?$",
854 ".*",
855 NULL, NULL, NULL, NULL
856 },
857 { "Seagate Momentus 7200.1 series",
858 "^ST9(10021|80825|6023|4015)AS?$",
859 ".*",
860 NULL, NULL, NULL, NULL
861 },
862 { "Seagate Medalist 2110, 3221, 4321, 6531, and 8641",
863 "^ST3(2110|3221|4321|6531|8641)A$",
864 ".*",
865 NULL, NULL, NULL, NULL
866 },
867 { "Seagate U Series X family",
868 "^ST3(10014A(CE)?|20014A)$",
869 ".*",
870 NULL, NULL, NULL, NULL
871 },
872 { "Seagate U7 family",
873 "^ST3(30012|40012|60012|80022|120020)A$",
874 ".*",
875 NULL, NULL, NULL, NULL
876 },
877 { "Seagate U Series 6 family",
878 "^ST3(8002|6002|4081|3061|2041)0A$",
879 ".*",
880 NULL, NULL, NULL, NULL
881 },
882 { "Seagate U Series 5 family",
883 "^ST3(40823|30621|20413|15311|10211)A$",
884 ".*",
885 NULL, NULL, NULL, NULL
886 },
887 { "Seagate U4 family",
888 "^ST3(2112|4311|6421|8421)A$",
889 ".*",
890 NULL, NULL, NULL, NULL
891 },
892 { "Seagate U8 family",
893 "^ST3(8410|4313|17221|13021)A$",
894 ".*",
895 NULL, NULL, NULL, NULL
896 },
897 { "Seagate U10 family",
898 "^ST3(20423|15323|10212)A$",
899 ".*",
900 NULL, NULL, NULL, NULL
901 },
902 { "Seagate Barracuda ATA II family",
903 "^ST3(3063|2042|1532|1021)0A$",
904 ".*",
905 NULL, NULL, NULL, NULL
906 },
907 { "Seagate Barracuda ATA III family",
908 "^ST3(40824|30620|20414|15310|10215)A$",
909 ".*",
910 NULL, NULL, NULL, NULL
911 },
912 { "Seagate Barracuda ATA IV family",
913 "^ST3(20011|30011|40016|60021|80021)A$",
914 ".*",
915 NULL, NULL, NULL, NULL
916 },
917 { "Seagate Barracuda ATA V family",
918 "^ST3(12002(3A|4A|9A|3AS)|800(23A|15A|23AS)|60(015A|210A)|40017A)$",
919 ".*",
920 NULL, NULL, NULL, NULL
921 },
922 { "Seagate Barracuda 5400.1",
923 "^ST340015A$",
924 ".*",
925 NULL, NULL, NULL, NULL
926 },
927 { "Seagate Barracuda 7200.7 and 7200.7 Plus family",
928 "^ST3(200021A|200822AS?|16002[13]AS?|12002[26]AS?|1[26]082[78]AS|8001[13]AS?|80817AS|60014A|40111AS|40014AS?)$",
929 ".*",
930 NULL, NULL, NULL, NULL
931 },
932 { "Seagate Barracuda 7200.8 family",
933 "^ST3(400[68]32|300[68]31|250[68]23|200826)AS?$",
934 ".*",
935 NULL, NULL, NULL, NULL
936 },
937 { "Seagate Barracuda 7200.9 family",
938 "^ST3(500[68]41|400[68]33|300[68]22|250[68]24|250[68]24|200827|160[28]12|120814|120[28]13|80[28]110|402111)AS?$",
939 ".*",
940 NULL, NULL, NULL, NULL
941 },
942 { "Seagate Barracuda 7200.10 family",
943 "^ST3(750[68]4|500[68]3|400[68]2|320[68]2|300[68]2|250[68]2|20082)0AS?$",
944 ".*",
945 NULL, NULL, NULL, NULL
946 },
947 { "Seagate Medalist 17240, 13030, 10231, 8420, and 4310",
948 "^ST3(17240|13030|10231|8420|4310)A$",
949 ".*",
950 NULL, NULL, NULL, NULL
951 },
952 { "Seagate Medalist 17242, 13032, 10232, 8422, and 4312",
953 "^ST3(1724|1303|1023|842|431)2A$",
954 ".*",
955 NULL, NULL, NULL, NULL
956 },
957 { "Seagate NL35 family",
958 "^ST3(250623|250823|400632|400832|250824|250624|400633|400833|500641|500841)NS$",
959 ".*",
960 NULL, NULL, NULL, NULL
961 },
962 { "Western Digital Protege",
963 /* Western Digital drives with this comment all appear to use Attribute 9 in
964 * a non-standard manner. These entries may need to be updated when it
965 * is understood exactly how Attribute 9 should be interpreted.
966 * UPDATE: this is probably explained by the WD firmware bug described in the
967 * smartmontools FAQ */
968 "^WDC WD([2468]00E|1[26]00A)B-.*$",
969 ".*",
970 NULL, NULL, NULL, NULL
971 },
972 { "Western Digital Caviar family",
973 /* Western Digital drives with this comment all appear to use Attribute 9 in
974 * a non-standard manner. These entries may need to be updated when it
975 * is understood exactly how Attribute 9 should be interpreted.
976 * UPDATE: this is probably explained by the WD firmware bug described in the
977 * smartmontools FAQ */
978 "^WDC WD(2|3|4|6|8|10|12|16|18|20|25)00BB-.*$",
979 ".*",
980 NULL, NULL, NULL, NULL
981 },
982 { "Western Digital Caviar WDxxxAB series",
983 /* Western Digital drives with this comment all appear to use Attribute 9 in
984 * a non-standard manner. These entries may need to be updated when it
985 * is understood exactly how Attribute 9 should be interpreted.
986 * UPDATE: this is probably explained by the WD firmware bug described in the
987 * smartmontools FAQ */
988 "^WDC WD(3|4|6)00AB-.*$",
989 ".*",
990 NULL, NULL, NULL, NULL
991 },
992 { "Western Digital Caviar WDxxxAA series",
993 /* Western Digital drives with this comment all appear to use Attribute 9 in
994 * a non-standard manner. These entries may need to be updated when it
995 * is understood exactly how Attribute 9 should be interpreted.
996 * UPDATE: this is probably explained by the WD firmware bug described in the
997 * smartmontools FAQ */
998 "^WDC WD...?AA(-.*)?$",
999 ".*",
1000 NULL, NULL, NULL, NULL
1001 },
1002 { "Western Digital Caviar WDxxxBA series",
1003 /* Western Digital drives with this comment all appear to use Attribute 9 in
1004 * a non-standard manner. These entries may need to be updated when it
1005 * is understood exactly how Attribute 9 should be interpreted.
1006 * UPDATE: this is probably explained by the WD firmware bug described in the
1007 * smartmontools FAQ */
1008 "^WDC WD...BA$",
1009 ".*",
1010 NULL, NULL, NULL, NULL
1011 },
1012 { NULL, // Western Digital Caviar AC12500, AC14300, AC23200, AC24300, AC25100,
1013 // AC36400, AC38400
1014 "^WDC AC(125|143|232|243|251|364|384)00.?",
1015 ".*",
1016 NULL, NULL, NULL, NULL
1017 },
1018 { "Western Digital Caviar Serial ATA family",
1019 "^WDC WD(4|8|20|32)00BD-.*$",
1020 ".*",
1021 NULL, NULL, NULL, NULL
1022 },
1023 { "Western Digital Caviar SE family",
1024 /* Western Digital drives with this comment all appear to use Attribute 9 in
1025 * a non-standard manner. These entries may need to be updated when it
1026 * is understood exactly how Attribute 9 should be interpreted.
1027 * UPDATE: this is probably explained by the WD firmware bug described in the
1028 * smartmontools FAQ */
1029 "^WDC WD((4|6|8|10|12|16|18|20|25|30|32)00JB|(12|20|25)00PB)-.*$",
1030 ".*",
1031 NULL, NULL, NULL, NULL
1032 },
1033 { "Western Digital Caviar SE (Serial ATA) family",
1034 "^WDC WD((4|8|12|16|20|25|32)00JD|(12|16|20|25|30|32)00JS|1600AAJS)-.*$",
1035 ".*",
1036 NULL, NULL, NULL, NULL
1037 },
1038 { "Western Digital Caviar SE16 family",
1039 "^WDC WD((25|32|40|50)00KS|4000KD)-.*$",
1040 ".*",
1041 NULL, NULL, NULL, NULL
1042 },
1043 { "Western Digital Caviar RE Serial ATA series",
1044 "^WDC WD((12|16|25|32)00SD|2500YD|4000Y[RS]|5000YS)-.*$",
1045 ".*",
1046 NULL, NULL, NULL, NULL
1047 },
1048 { "Western Digital Raptor family",
1049 "^WDC WD((360|740|800)GD|(360|740|1500)ADFD)-.*$",
1050 ".*",
1051 NULL, NULL, NULL, NULL
1052 },
1053 { "Western Digital Scorpio family",
1054 "^WDC WD((12|10|8|6|4)00(UE|VE|BEAS|BEVS))-.*$",
1055 ".*",
1056 NULL, NULL, NULL, NULL
1057 },
1058 { NULL, // QUANTUM BIGFOOT TS10.0A
1059 "^QUANTUM BIGFOOT TS10.0A$",
1060 ".*",
1061 NULL, NULL, NULL, NULL
1062 },
1063 { NULL, // QUANTUM FIREBALLlct15 20 and QUANTUM FIREBALLlct15 30
1064 "^QUANTUM FIREBALLlct15 [123]0$",
1065 ".*",
1066 NULL, NULL, NULL, NULL
1067 },
1068 { "QUANTUM FIREBALLlct20 series",
1069 "^QUANTUM FIREBALLlct20 [234]0$",
1070 ".*",
1071 NULL, NULL, NULL, NULL
1072 },
1073 { NULL, // QUANTUM FIREBALL CX10.2A
1074 "^QUANTUM FIREBALL CX10.2A$",
1075 ".*",
1076 NULL, NULL, NULL, NULL
1077 },
1078 { "Quantum Fireball Plus LM series",
1079 "^QUANTUM FIREBALLP LM(10.2|15|20.5|30)$",
1080 ".*",
1081 NULL, NULL, NULL, NULL
1082 },
1083 { "Quantum Fireball CR series",
1084 "^QUANTUM FIREBALL CR(4.3|8.4)A$",
1085 ".*",
1086 NULL, NULL, NULL, NULL
1087 },
1088 { NULL, // QUANTUM FIREBALLP AS10.2, AS20.5, AS30.0, and AS40.0
1089 "^QUANTUM FIREBALLP AS(10.2|20.5|30.0|40.0)$",
1090 ".*",
1091 NULL, NULL, NULL, NULL
1092 },
1093 { NULL, // QUANTUM FIREBALL EX6.4A
1094 "^QUANTUM FIREBALL EX6.4A$",
1095 ".*",
1096 NULL, NULL, NULL, NULL
1097 },
1098 { NULL, // QUANTUM FIREBALL ST3.2A
1099 "^QUANTUM FIREBALL ST(3.2|4.3)A$",
1100 ".*",
1101 NULL, NULL, NULL, NULL
1102 },
1103 { NULL, // QUANTUM FIREBALL EX3.2A
1104 "^QUANTUM FIREBALL EX3.2A$",
1105 ".*",
1106 NULL, NULL, NULL, NULL
1107 },
1108 { NULL, // QUANTUM FIREBALLP KX27.3
1109 "^QUANTUM FIREBALLP KX27.3$",
1110 ".*",
1111 NULL, NULL, NULL, NULL
1112 },
1113 { "Quantum Fireball Plus KA series",
1114 "^QUANTUM FIREBALLP KA(9|10).1$",
1115 ".*",
1116 NULL, NULL, NULL, NULL
1117 },
1118 { "Quantum Fireball SE series",
1119 "^QUANTUM FIREBALL SE4.3A$",
1120 ".*",
1121 NULL, NULL, NULL, NULL
1122 },
1123 /*------------------------------------------------------------
1124 * End of table. Do not add entries below this marker.
1125 *------------------------------------------------------------ */
1126 {NULL, NULL, NULL, NULL, NULL, NULL, NULL}
1127 };
1128
1129 // Searches knowndrives[] for a drive with the given model number and firmware
1130 // string. If either the drive's model or firmware strings are not set by the
1131 // manufacturer then values of NULL may be used. Returns the index of the
1132 // first match in knowndrives[] or -1 if no match if found.
1133 int lookupdrive(const char *model, const char *firmware)
1134 {
1135 regex_t regex;
1136 int i, index;
1137 const char *empty = "";
1138
1139 model = model ? model : empty;
1140 firmware = firmware ? firmware : empty;
1141
1142 for (i = 0, index = -1; index == -1 && knowndrives[i].modelregexp; i++) {
1143 // Attempt to compile regular expression.
1144 if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
1145 goto CONTINUE;
1146
1147 // Check whether model matches the regular expression in knowndrives[i].
1148 if (!regexec(&regex, model, 0, NULL, 0)) {
1149 // model matches, now check firmware.
1150 if (!knowndrives[i].firmwareregexp)
1151 // The firmware regular expression in knowndrives[i] is NULL, which is
1152 // considered a match.
1153 index = i;
1154 else {
1155 // Compare firmware against the regular expression in knowndrives[i].
1156 regfree(&regex); // Recycle regex.
1157 if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
1158 goto CONTINUE;
1159 if (!regexec(&regex, firmware, 0, NULL, 0))
1160 index = i;
1161 }
1162 }
1163 CONTINUE:
1164 regfree(&regex);
1165 }
1166
1167 return index;
1168 }
1169
1170
1171 // Shows all presets for drives in knowndrives[].
1172 void showonepreset(const drivesettings *drivetable){
1173
1174 const unsigned char (* presets)[2] = drivetable->vendoropts;
1175 int first_preset = 1;
1176
1177 // Basic error check
1178 if (!drivetable || !drivetable->modelregexp){
1179 pout("Null known drive table pointer. Please report\n"
1180 "this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
1181 return;
1182 }
1183
1184 // print model and firmware regular expressions
1185 pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", drivetable->modelregexp);
1186 pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", drivetable->firmwareregexp ?
1187 drivetable->firmwareregexp : "");
1188 pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL FAMILY:", drivetable->modelfamily ?
1189 drivetable->modelfamily : "");
1190
1191 // if there are any presets, then show them
1192 if (presets && (*presets)[0]) while (1) {
1193 char out[256];
1194 const int attr = (*presets)[0], val = (*presets)[1];
1195 unsigned char fakearray[MAX_ATTRIBUTE_NUM];
1196
1197 // if we are at the end of the attribute list, break out
1198 if (!attr)
1199 break;
1200
1201 // This is a hack. ataPrintSmartAttribName() needs a pointer to an
1202 // "array" to dereference, so we provide such a pointer.
1203 fakearray[attr]=val;
1204 ataPrintSmartAttribName(out, attr, fakearray);
1205
1206 // Use leading zeros instead of spaces so that everything lines up.
1207 out[0] = (out[0] == ' ') ? '0' : out[0];
1208 out[1] = (out[1] == ' ') ? '0' : out[1];
1209 pout("%-*s %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "", out);
1210 first_preset = 0;
1211 presets++;
1212 }
1213 else
1214 pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
1215
1216
1217 // Is a special purpose function defined? If so, describe it
1218 if (drivetable->specialpurpose){
1219 pout("%-*s ", TABLEPRINTWIDTH, "OTHER PRESETS:");
1220 pout("%s\n", drivetable->functiondesc ?
1221 drivetable->functiondesc : "A special purpose function "
1222 "is defined for this drive");
1223 }
1224
1225 // Print any special warnings
1226 if (drivetable->warningmsg){
1227 pout("%-*s ", TABLEPRINTWIDTH, "WARNINGS:");
1228 pout("%s\n", drivetable->warningmsg);
1229 }
1230
1231 return;
1232 }
1233
1234 // Shows all presets for drives in knowndrives[].
1235 // Returns <0 on syntax error in regular expressions.
1236 int showallpresets(void){
1237 int i;
1238 int rc = 0;
1239 regex_t regex;
1240
1241 // loop over all entries in the knowndrives[] table, printing them
1242 // out in a nice format
1243 for (i=0; knowndrives[i].modelregexp; i++){
1244 showonepreset(&knowndrives[i]);
1245 pout("\n");
1246 }
1247
1248 // Check all regular expressions
1249 for (i=0; knowndrives[i].modelregexp; i++){
1250 if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
1251 rc = -1;
1252 if (knowndrives[i].firmwareregexp) {
1253 if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
1254 rc = -1;
1255 }
1256 }
1257 pout("For information about adding a drive to the database see the FAQ on the\n");
1258 pout("smartmontools home page: " PACKAGE_HOMEPAGE "\n");
1259 return rc;
1260 }
1261
1262 // Shows all matching presets for a drive in knowndrives[].
1263 // Returns # matching entries.
1264 int showmatchingpresets(const char *model, const char *firmware){
1265 int i;
1266 int cnt = 0;
1267 const char * firmwaremsg = (firmware ? firmware : "(any)");
1268 regex_t regex;
1269
1270 for (i=0; knowndrives[i].modelregexp; i++){
1271 if (i > 0)
1272 regfree(&regex);
1273 if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
1274 continue;
1275 if (regexec(&regex, model, 0, NULL, 0))
1276 continue;
1277 if (firmware && knowndrives[i].firmwareregexp) {
1278 regfree(&regex);
1279 if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
1280 continue;
1281 if (regexec(&regex, firmware, 0, NULL, 0))
1282 continue;
1283 }
1284 if (++cnt == 1)
1285 pout("Drive found in smartmontools Database. Drive identity strings:\n"
1286 "%-*s %s\n"
1287 "%-*s %s\n"
1288 "match smartmontools Drive Database entry:\n",
1289 TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmwaremsg);
1290 else if (cnt == 2)
1291 pout("and match these additional entries:\n");
1292 showonepreset(&knowndrives[i]);
1293 pout("\n");
1294 }
1295 regfree(&regex);
1296 if (cnt == 0)
1297 pout("No presets are defined for this drive. Its identity strings:\n"
1298 "MODEL: %s\n"
1299 "FIRMWARE: %s\n"
1300 "do not match any of the known regular expressions.\n",
1301 model, firmwaremsg);
1302 return cnt;
1303 }
1304
1305 // Shows the presets (if any) that are available for the given drive.
1306 void showpresets(const struct ata_identify_device *drive){
1307 int i;
1308 char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
1309
1310 // get the drive's model/firmware strings
1311 formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
1312 formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
1313
1314 // and search to see if they match values in the table
1315 if ((i = lookupdrive(model, firmware)) < 0) {
1316 // no matches found
1317 pout("No presets are defined for this drive. Its identity strings:\n"
1318 "MODEL: %s\n"
1319 "FIRMWARE: %s\n"
1320 "do not match any of the known regular expressions.\n"
1321 "Use -P showall to list all known regular expressions.\n",
1322 model, firmware);
1323 return;
1324 }
1325
1326 // We found a matching drive. Print out all information about it.
1327 pout("Drive found in smartmontools Database. Drive identity strings:\n"
1328 "%-*s %s\n"
1329 "%-*s %s\n"
1330 "match smartmontools Drive Database entry:\n",
1331 TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmware);
1332 showonepreset(&knowndrives[i]);
1333 return;
1334 }
1335
1336 // Sets preset vendor attribute options in opts by finding the entry
1337 // (if any) for the given drive in knowndrives[]. Values that have
1338 // already been set in opts will not be changed. Returns <0 if drive
1339 // not recognized else index >=0 into drive database.
1340 int applypresets(const struct ata_identify_device *drive, unsigned char **optsptr,
1341 smartmonctrl *con) {
1342 int i;
1343 unsigned char *opts;
1344 char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
1345
1346 if (*optsptr==NULL)
1347 bytes+=MAX_ATTRIBUTE_NUM;
1348
1349 if (*optsptr==NULL && !(*optsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM,1))){
1350 pout("Unable to allocate memory in applypresets()");
1351 bytes-=MAX_ATTRIBUTE_NUM;
1352 EXIT(1);
1353 }
1354
1355 opts=*optsptr;
1356
1357 // get the drive's model/firmware strings
1358 formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
1359 formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
1360
1361 // Look up the drive in knowndrives[].
1362 if ((i = lookupdrive(model, firmware)) >= 0) {
1363
1364 // if vendoropts is non-NULL then Attribute interpretation presets
1365 if (knowndrives[i].vendoropts) {
1366 const unsigned char (* presets)[2];
1367
1368 // For each attribute in list of attribute/val pairs...
1369 presets = knowndrives[i].vendoropts;
1370 while (1) {
1371 const int attr = (*presets)[0];
1372 const int val = (*presets)[1];
1373
1374 if (!attr)
1375 break;
1376
1377 // ... set attribute if user hasn't already done so.
1378 if (!opts[attr])
1379 opts[attr] = val;
1380 presets++;
1381 }
1382 }
1383
1384 // If a special-purpose function is defined for this drive then
1385 // call it. Note that if command line arguments or Directives
1386 // over-ride this choice, then the specialpurpose function that is
1387 // called must deal with this.
1388 if (knowndrives[i].specialpurpose)
1389 (*knowndrives[i].specialpurpose)(con);
1390 }
1391
1392 // return <0 if drive wasn't recognized, or index>=0 into database
1393 // if it was
1394 return i;
1395 }