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