]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - knowndrives.cpp
Do not Build-depends in libcap-ng-dev in armel, libcap-ng is broken in this arch.
[mirror_smartmontools-debian.git] / knowndrives.cpp
CommitLineData
832b75ed 1/*
4d59bff9 2 * knowndrives.cpp
832b75ed
GG
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 * Address of support mailing list: smartmontools-support@lists.sourceforge.net
6 *
2127e193
GI
7 * Copyright (C) 2003-9 Philip Williams, Bruce Allen
8 * Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
832b75ed
GG
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * You should have received a copy of the GNU General Public License
16 * (for example COPYING); if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21#include "config.h"
22#include "int64.h"
23#include <stdio.h>
24#include "atacmds.h"
832b75ed
GG
25#include "extern.h"
26#include "knowndrives.h"
2127e193 27#include "utility.h"
832b75ed 28
2127e193
GI
29#ifdef HAVE_UNISTD_H
30#include <unistd.h>
31#endif
32#ifdef _WIN32
33#include <io.h> // access()
34#endif
35
36#include <stdexcept>
37
38const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.207 2009/07/04 23:24:37 manfred99 Exp $"
39ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
832b75ed
GG
40
41#define MODEL_STRING_LENGTH 40
42#define FIRMWARE_STRING_LENGTH 8
43#define TABLEPRINTWIDTH 19
44
832b75ed
GG
45
46/* Table of settings for known drives terminated by an element containing all
47 * zeros. The drivesettings structure is described in knowndrives.h. Note
48 * that lookupdrive() will search knowndrives[] from the start to end or
49 * until it finds the first match, so the order in knowndrives[] is important
50 * for distinct entries that could match the same drive. */
51
52// Note that the table just below uses EXTENDED REGULAR EXPRESSIONS.
53// A good on-line reference for these is:
54// http://www.zeus.com/extra/docsystem/docroot/apps/web/docs/modules/access/regex.html
55
2127e193
GI
56// Starting with CVS version 1.179 of this file, the regular expressions
57// for drive model and firmware must match the full string. The effect of
58// "^FULLSTRING$" is identical to "FULLSTRING". The special characters '^'
59// and '$' are no longer required, but still allowed. The form ".*SUBSTRING.*"
60// can be used if substring match is desired.
61
62static const drive_settings builtin_knowndrives[] = {
63// BEGIN drivedb.h (DO NOT DELETE - used by Makefile)
64 { "Apple SSD SM128",
65 "APPLE SSD SM128",
66 "", "", ""
67 },
68 { "Asus-Phison SSD",
69 "ASUS-PHISON SSD",
70 "", "", ""
71 },
72 { "OCZ Vertex SSD",
73 "OCZ-VERTEX.*",
74 "", "", ""
75 },
76 { "Transcend Solid-State Drive",
77 "TS(8|16|32|64|128)GSSD25-(M|S)",
78 "", "", ""
79 },
80 { "Transcend Solid-State Drive V series",
81 "TS(8|16|32|64|128|192)GSSD25S-(M|S)",
82 "", "", ""
83 },
84 { "Marvell SSD SD88SA024BA0 (SUN branded)",
85 "MARVELL SD88SA024BA0 SUN24G 0902M0054V",
86 "", "", ""
87 },
88 { "HP 1TB SATA disk GB1000EAFJL",
89 "GB1000EAFJL",
90 "", "", ""
91 },
832b75ed 92 { "IBM Deskstar 60GXP series", // ER60A46A firmware
2127e193
GI
93 "(IBM-|Hitachi )?IC35L0[12346]0AVER07.*",
94 "ER60A46A",
95 "", ""
832b75ed
GG
96 },
97 { "IBM Deskstar 60GXP series", // All other firmware
2127e193
GI
98 "(IBM-|Hitachi )?IC35L0[12346]0AVER07.*",
99 "",
832b75ed
GG
100 "IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
101 "Please see http://www.geocities.com/dtla_update/index.html#rel and\n"
102 "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
103 "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
2127e193 104 ""
832b75ed
GG
105 },
106 { "IBM Deskstar 40GV & 75GXP series (A5AA/A6AA firmware)",
2127e193
GI
107 "(IBM-)?DTLA-30[57]0[123467][05].*",
108 "T[WX][123468AG][OF]A[56]AA",
109 "", ""
832b75ed
GG
110 },
111 { "IBM Deskstar 40GV & 75GXP series (all other firmware)",
2127e193
GI
112 "(IBM-)?DTLA-30[57]0[123467][05].*",
113 "",
832b75ed
GG
114 "IBM Deskstar 40GV and 75GXP drives may need upgraded SMART firmware.\n"
115 "Please see http://www.geocities.com/dtla_update/ and\n"
116 "http://www-3.ibm.com/pc/support/site.wss/document.do?lndocid=MIGR-42215 or\n"
117 "http://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-42215",
2127e193 118 ""
832b75ed 119 },
2127e193
GI
120 { "", // ExcelStor J240, J340, J360, J680, and J880
121 "ExcelStor Technology J(24|34|36|68|88)0",
122 "", "", ""
832b75ed 123 },
2127e193
GI
124 { "", // Fujitsu M1623TAU
125 "FUJITSU M1623TAU",
126 "",
127 "",
128 "-v 9,seconds"
832b75ed 129 },
ba59cff1 130 { "Fujitsu MHG series",
2127e193
GI
131 "FUJITSU MHG2...ATU?.*",
132 "",
133 "",
134 "-v 9,seconds"
832b75ed 135 },
ba59cff1 136 { "Fujitsu MHH series",
2127e193
GI
137 "FUJITSU MHH2...ATU?.*",
138 "",
139 "",
140 "-v 9,seconds"
832b75ed 141 },
ba59cff1 142 { "Fujitsu MHJ series",
2127e193
GI
143 "FUJITSU MHJ2...ATU?.*",
144 "",
145 "",
146 "-v 9,seconds"
ba59cff1
GG
147 },
148 { "Fujitsu MHK series",
2127e193
GI
149 "FUJITSU MHK2...ATU?.*",
150 "",
151 "",
152 "-v 9,seconds"
153 },
154 { "", // Fujitsu MHL2300AT
155 "FUJITSU MHL2300AT",
156 "",
ba59cff1
GG
157 "This drive's firmware has a harmless Drive Identity Structure\n"
158 "checksum error bug.",
2127e193 159 "-v 9,seconds"
ba59cff1 160 },
2127e193
GI
161 { "", // MHM2200AT, MHM2150AT, MHM2100AT, MHM2060AT
162 "FUJITSU MHM2(20|15|10|06)0AT",
163 "",
ba59cff1
GG
164 "This drive's firmware has a harmless Drive Identity Structure\n"
165 "checksum error bug.",
2127e193 166 "-v 9,seconds"
ba59cff1
GG
167 },
168 { "Fujitsu MHN series",
2127e193
GI
169 "FUJITSU MHN2...AT",
170 "",
171 "",
172 "-v 9,seconds"
173 },
174 { "", // Fujitsu MHR2020AT
175 "FUJITSU MHR2020AT",
176 "",
177 "",
178 "-v 9,seconds"
179 },
180 { "", // Fujitsu MHR2040AT
181 "FUJITSU MHR2040AT",
182 "", // Tested on 40BA
183 "",
184 "-v 9,seconds -v 192,emergencyretractcyclect "
185 "-v 198,offlinescanuncsectorct -v 200,writeerrorcount"
ba59cff1 186 },
832b75ed 187 { "Fujitsu MHSxxxxAT family",
2127e193
GI
188 "FUJITSU MHS20[6432]0AT( .)?",
189 "",
190 "",
191 "-v 9,seconds -v 192,emergencyretractcyclect "
192 "-v 198,offlinescanuncsectorct -v 200,writeerrorcount "
193 "-v 201,detectedtacount"
832b75ed 194 },
ba59cff1 195 { "Fujitsu MHT series",
2127e193
GI
196 "FUJITSU MHT2...(AH|AS|AT|BH)U?.*",
197 "",
198 "",
199 "-v 9,seconds"
ba59cff1
GG
200 },
201 { "Fujitsu MHU series",
2127e193
GI
202 "FUJITSU MHU2...ATU?.*",
203 "",
204 "",
205 "-v 9,seconds"
ba59cff1
GG
206 },
207 { "Fujitsu MHV series",
2127e193
GI
208 "FUJITSU MHV2...(AH|AS|AT|BH|BS|BT).*",
209 "",
210 "",
211 "-v 9,seconds"
832b75ed 212 },
4d59bff9 213 { "Fujitsu MPA..MPG series",
2127e193
GI
214 "FUJITSU MP[A-G]3...A[HTEV]U?.*",
215 "",
216 "",
217 "-v 9,seconds"
218 },
219 { "Fujitsu MHY2 BH series",
220 "FUJITSU MHY2(04|06|08|10|12|16|20|25)0BH.*",
221 "", "", ""
222 },
223 { "Fujitsu MHW2 BH series",
224 "FUJITSU MHW2(04|06|08|10|12|16)0BH.*",
225 "", "", ""
226 },
227 { "Fujitsu MHW2 BJ series",
228 "FUJITSU MHW2(08|12|16)0BJ.*",
229 "", "", ""
230 },
231 { "Fujitsu MHZ2 BH series",
232 "FUJITSU MHZ2(04|08|12|16|20|25|32)0BH.*",
233 "", "", ""
234 },
235 { "Fujitsu MHZ2 BJ series",
236 "FUJITSU MHZ2(08|12|16|20|25|32)0BJ.*",
237 "",
238 "",
239 "-v 9,minutes"
240 },
241 { "Fujitsu MHZ2 BS series",
242 "FUJITSU MHZ2(12|25)0BS.*",
243 "", "", ""
244 },
245 { "", // Samsung SV4012H (known firmware)
246 "SAMSUNG SV4012H",
247 "RM100-08",
248 "",
249 "-v 9,halfminutes -F samsung"
250 },
251 { "", // Samsung SV4012H (all other firmware)
252 "SAMSUNG SV4012H",
253 "",
254 "May need -F samsung disabled; see manual for details.",
255 "-v 9,halfminutes -F samsung"
256 },
257 { "", // Samsung SV0412H (known firmware)
258 "SAMSUNG SV0412H",
259 "SK100-01",
260 "",
261 "-v 9,halfminutes -v 194,10xCelsius -F samsung"
262 },
263 { "", // Samsung SV0412H (all other firmware)
264 "SAMSUNG SV0412H",
265 "",
266 "May need -F samsung disabled; see manual for details.",
267 "-v 9,halfminutes -v 194,10xCelsius -F samsung"
268 },
269 { "", // Samsung SV1204H (known firmware)
270 "SAMSUNG SV1204H",
271 "RK100-1[3-5]",
272 "",
273 "-v 9,halfminutes -v 194,10xCelsius -F samsung"
274 },
275 { "", // Samsung SV1204H (all other firmware)
276 "SAMSUNG SV1204H",
277 "",
278 "May need -F samsung disabled; see manual for details.",
279 "-v 9,halfminutes -v 194,10xCelsius -F samsung"
280 },
281 { "", // SAMSUNG SV0322A tested with FW JK200-35
282 "SAMSUNG SV0322A",
283 "", "", ""
284 },
285 { "", // SAMSUNG SP40A2H with RR100-07 firmware
286 "SAMSUNG SP40A2H",
287 "RR100-07",
288 "",
289 "-v 9,halfminutes -F samsung"
290 },
291 { "", // SAMSUNG SP80A4H with RT100-06 firmware
292 "SAMSUNG SP80A4H",
293 "RT100-06",
294 "",
295 "-v 9,halfminutes -F samsung"
296 },
297 { "", // SAMSUNG SP8004H with QW100-61 firmware
298 "SAMSUNG SP8004H",
299 "QW100-61",
300 "",
301 "-v 9,halfminutes -F samsung"
302 },
303 { "SAMSUNG SpinPoint F1 DT series", // tested with HD103UJ/1AA01113
304 "SAMSUNG HD(083G|16[12]G|25[12]H|32[12]H|50[12]I|642J|75[23]L|10[23]U)J",
305 "", "", ""
306 },
307 { "SAMSUNG SpinPoint F1 RE series", // tested with HE103UJ/1AA01113
308 "SAMSUNG HE(252H|322H|502I|642J|753L|103U)J",
309 "", "", ""
310 },
311 { "SAMSUNG SpinPoint S250 series", // tested with HD200HJ/KF100-06
312 "SAMSUNG HD(162|200|250)HJ",
313 "", "", ""
ba59cff1 314 },
4d59bff9 315 { "SAMSUNG SpinPoint T133 series", // tested with HD300LJ/ZT100-12, HD400LJ/ZZ100-14, HD401LJ/ZZ100-15
2127e193
GI
316 "SAMSUNG HD(250KD|(30[01]|320|40[01])L[DJ])",
317 "", "", ""
ba59cff1 318 },
a37e7145 319 { "SAMSUNG SpinPoint T166 series", // tested with HD501LJ/CR100-10
2127e193
GI
320 "SAMSUNG HD(080G|160H|32[01]K|403L|50[01]L)J",
321 "", "", ""
ba59cff1 322 },
a37e7145 323 { "SAMSUNG SpinPoint P120 series", // VF100-37 firmware, tested with SP2514N/VF100-37
2127e193
GI
324 "SAMSUNG SP(16[01]3|2[05][01]4)[CN]",
325 "VF100-37",
326 "",
327 "-F samsung3"
a37e7145
GG
328 },
329 { "SAMSUNG SpinPoint P120 series", // other firmware, tested with SP2504C/VT100-33
2127e193
GI
330 "SAMSUNG SP(16[01]3|2[05][01]4)[CN]",
331 "",
332 "May need -F samsung3 enabled; see manual for details.",
333 ""
a37e7145 334 },
ba59cff1 335 { "SAMSUNG SpinPoint P80 SD series", // tested with HD160JJ/ZM100-33
2127e193
GI
336 "SAMSUNG HD(080H|120I|160J)J",
337 "", "", ""
ba59cff1 338 },
a37e7145 339 { "SAMSUNG SpinPoint P80 series", // BH100-35 firmware, tested with SP0842N/BH100-35
2127e193
GI
340 "SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
341 "BH100-35",
342 "",
343 "-F samsung3"
a37e7145
GG
344 },
345 { "SAMSUNG SpinPoint P80 series", // firmware *-35 or later
2127e193
GI
346 "SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
347 ".*-3[5-9]",
348 "May need -F samsung3 enabled; see manual for details.",
349 ""
a37e7145 350 },
1953ff6d 351 { "SAMSUNG SpinPoint P80 series", // firmware *-25...34, tested with SP1614C/SW100-25 and -34
2127e193
GI
352 "SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
353 ".*-(2[5-9]|3[0-4])",
354 "",
355 "-v 9,halfminutes -v 198,increasing"
356 },
357 { "SAMSUNG SpinPoint P80 series", // firmware *-23...24, tested with
358 // SP0802N/TK100-23,
359 // SP1213N/TL100-23,
360 // SP1604N/TM100-23 and -24
361 "SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
362 ".*-2[34]",
363 "",
364 "-v 9,halfminutes -F samsung2"
365 },
366 { "SAMSUNG SpinPoint P80 series", // unknown firmware
367 "SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
368 "",
369 "May need -F samsung2 or -F samsung3 enabled; see manual for details.",
370 ""
832b75ed 371 },
2127e193
GI
372/*
373 // TODO: Make the entries below more specific.
374 // These entries produce misleading results, because newer
375 // Samsung disks reuse the version numbers *-NN.
376 { "", // All Samsung drives with '.*-25' firmware
377 "SAMSUNG.*",
378 ".*-25",
379 "May need -F samsung2 disabled; see manual for details.",
380 "-v 9,halfminutes -F samsung2"
381 },
382 { "", // All Samsung drives with '.*-26 or later (currently to -39)' firmware
383 "SAMSUNG.*",
384 ".*-(2[6789]|3[0-9])",
385 "",
386 "-v 9,halfminutes"
387 },
388 { "", // Samsung ALL OTHER DRIVES
389 "SAMSUNG.*",
390 "",
391 "May need -F samsung or -F samsung2 enabled; see manual for details.",
392 ""
393 },
394*/
832b75ed 395 { "Maxtor Fireball 541DX family",
2127e193
GI
396 "Maxtor 2B0(0[468]|1[05]|20)H1",
397 "",
398 "",
399 "-v 9,minutes -v 194,unknown"
832b75ed
GG
400 },
401 { "Maxtor Fireball 3 family",
2127e193
GI
402 "Maxtor 2F0[234]0[JL]0",
403 "",
404 "",
405 "-v 9,minutes"
406 },
407 { "Maxtor DiamondMax 1280 ATA family", // no self-test log, ATA2-Fast
408 "Maxtor 8(1280A2|2160A4|2560A4|3840A6|4000A6|5120A8)",
409 "",
410 "",
411 "-v 9,minutes"
832b75ed
GG
412 },
413 { "Maxtor DiamondMax 2160 Ultra ATA family",
2127e193
GI
414 "Maxtor 8(2160D2|3228D3|3240D3|4320D4|6480D6|8400D8|8455D8)",
415 "",
416 "",
417 "-v 9,minutes"
832b75ed
GG
418 },
419 { "Maxtor DiamondMax 2880 Ultra ATA family",
2127e193
GI
420 "Maxtor 9(0510D4|0576D4|0648D5|0720D5|0840D6|0845D6|0864D6|1008D7|1080D8|1152D8)",
421 "",
422 "",
423 "-v 9,minutes"
832b75ed
GG
424 },
425 { "Maxtor DiamondMax 3400 Ultra ATA family",
2127e193
GI
426 "Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)",
427 "",
428 "",
429 "-v 9,minutes"
832b75ed
GG
430 },
431 { "Maxtor DiamondMax D540X-4G family",
2127e193
GI
432 "Maxtor 4G(120J6|160J[68])",
433 "",
434 "",
435 "-v 9,minutes -v 194,unknown"
832b75ed
GG
436 },
437 { "Maxtor DiamondMax D540X-4K family",
2127e193
GI
438 "MAXTOR 4K(020H1|040H2|060H3|080H4)",
439 "", "", ""
832b75ed
GG
440 },
441 { "Maxtor DiamondMax Plus D740X family",
2127e193
GI
442 "MAXTOR 6L0(20[JL]1|40[JL]2|60[JL]3|80[JL]4)",
443 "", "", ""
832b75ed
GG
444 },
445 { "Maxtor DiamondMax Plus 5120 Ultra ATA 33 family",
2127e193
GI
446 "Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)",
447 "",
448 "",
449 "-v 9,minutes"
832b75ed
GG
450 },
451 { "Maxtor DiamondMax Plus 6800 Ultra ATA 66 family",
2127e193
GI
452 "Maxtor 9(2732U8|2390U7|204[09]U6|1707U5|1366U4|1024U3|0845U3|0683U2)",
453 "",
454 "",
455 "-v 9,minutes"
832b75ed
GG
456 },
457 { "Maxtor DiamondMax D540X-4D",
2127e193
GI
458 "Maxtor 4D0(20H1|40H2|60H3|80H4)",
459 "",
460 "",
461 "-v 9,minutes -v 194,unknown"
832b75ed
GG
462 },
463 { "Maxtor DiamondMax 16 family",
2127e193
GI
464 "Maxtor 4(R0[68]0[JL]0|R1[26]0L0|A160J0|R120L4)",
465 "",
466 "",
467 "-v 9,minutes"
832b75ed 468 },
ba59cff1 469 { "Maxtor DiamondMax 4320 Ultra ATA family",
2127e193
GI
470 "Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D[34]|90432D2)",
471 "",
472 "",
473 "-v 9,minutes"
832b75ed
GG
474 },
475 { "Maxtor DiamondMax 17 VL family",
2127e193
GI
476 "Maxtor 9(0431U1|0641U2|0871U2|1301U3|1741U4)",
477 "",
478 "",
479 "-v 9,minutes"
832b75ed
GG
480 },
481 { "Maxtor DiamondMax 20 VL family",
2127e193
GI
482 "Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)",
483 "",
484 "",
485 "-v 9,minutes"
486 },
487 { "Maxtor DiamondMax VL 30 family", // U: ATA66, H: ATA100
488 "Maxtor (33073U4|32049U3|31536U2|30768U1|33073H4|32305H3|31536H2|30768H1)",
489 "",
490 "",
491 "-v 9,minutes"
832b75ed
GG
492 },
493 { "Maxtor DiamondMax 36 family",
2127e193
GI
494 "Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)",
495 "",
496 "",
497 "-v 9,minutes"
832b75ed
GG
498 },
499 { "Maxtor DiamondMax 40 ATA 66 series",
2127e193
GI
500 "Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)",
501 "",
502 "",
503 "-v 9,minutes"
832b75ed
GG
504 },
505 { "Maxtor DiamondMax Plus 40 series (Ultra ATA 66 and Ultra ATA 100)",
2127e193
GI
506 "Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)",
507 "",
508 "",
509 "-v 9,minutes"
832b75ed
GG
510 },
511 { "Maxtor DiamondMax 40 VL Ultra ATA 100 series",
2127e193
GI
512 "Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?",
513 "",
514 "",
515 "-v 9,minutes"
832b75ed
GG
516 },
517 { "Maxtor DiamondMax Plus 45 Ulta ATA 100 family",
2127e193
GI
518 "Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)",
519 "",
520 "",
521 "-v 9,minutes"
832b75ed 522 },
ba59cff1 523 { "Maxtor DiamondMax 60 ATA 66 family",
2127e193
GI
524 "Maxtor 9(1023U2|1536U2|2049U3|2305U3|3073U4|4610U6|6147U8)",
525 "",
526 "",
527 "-v 9,minutes"
ba59cff1
GG
528 },
529 { "Maxtor DiamondMax 60 ATA 100 family",
2127e193
GI
530 "Maxtor 9(1023H2|1536H2|2049H3|2305H3|3073H4|4098H6|4610H6|6147H8)",
531 "",
532 "",
533 "-v 9,minutes"
ba59cff1 534 },
832b75ed 535 { "Maxtor DiamondMax Plus 60 family",
2127e193
GI
536 "Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)",
537 "",
538 "",
539 "-v 9,minutes"
832b75ed
GG
540 },
541 { "Maxtor DiamondMax 80 family",
2127e193
GI
542 "Maxtor (98196H8|96147H6)",
543 "",
544 "",
545 "-v 9,minutes"
832b75ed
GG
546 },
547 { "Maxtor DiamondMax 536DX family",
2127e193
GI
548 "Maxtor 4W(100H6|080H6|060H4|040H3|030H2)",
549 "",
550 "",
551 "-v 9,minutes"
832b75ed
GG
552 },
553 { "Maxtor DiamondMax Plus 8 family",
2127e193
GI
554 "Maxtor 6(E0[234]|K04)0L0",
555 "",
556 "",
557 "-v 9,minutes"
832b75ed 558 },
ba59cff1 559 { "Maxtor DiamondMax 10 family (ATA/133 and SATA/150)",
2127e193
GI
560 "Maxtor 6(B(30|25|20|16|12|10|08)0[MPRS]|L(080[MLP]|(100|120)[MP]|160[MP]|200[MPRS]|250[RS]|300[RS]))0",
561 "",
562 "",
563 "-v 9,minutes"
832b75ed 564 },
ba59cff1 565 { "Maxtor DiamondMax 10 family (SATA/300)",
2127e193
GI
566 "Maxtor 6V(080E|160E|200E|250F|300F|320F)0",
567 "", "", ""
ba59cff1 568 },
832b75ed 569 { "Maxtor DiamondMax Plus 9 family",
2127e193
GI
570 "Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)",
571 "",
572 "",
573 "-v 9,minutes"
832b75ed 574 },
ba59cff1 575 { "Maxtor DiamondMax 11 family",
2127e193
GI
576 "Maxtor 6H[45]00[FR]0",
577 "", "", ""
ba59cff1 578 },
1953ff6d 579 { "Maxtor DiamondMax 17",
2127e193
GI
580 "Maxtor 6G(080L|160[PE])0",
581 "", "", ""
1953ff6d
GG
582 },
583 { "Seagate Maxtor DiamondMax 20",
2127e193
GI
584 "MAXTOR STM3(40|80|160)[28]1[12]0?AS?",
585 "", "", ""
1953ff6d
GG
586 },
587 { "Seagate Maxtor DiamondMax 21",
2127e193
GI
588 "MAXTOR STM3(160215|(250|320)820|320620|500630)AS?",
589 "", "", ""
590 },
591 { "Seagate Maxtor DiamondMax 22", // fixed firmware
592 "(MAXTOR )?STM3(500320|750330|1000340)AS?",
593 "MX1A", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207969
594 "", ""
595 },
596 { "Seagate Maxtor DiamondMax 22", // fixed firmware
597 "(MAXTOR )?STM3(160813|320614|640323|1000334)AS?",
598 "MX1B", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207975
599 "", ""
600 },
601 { "Seagate Maxtor DiamondMax 22", // buggy firmware
602 "(MAXTOR )?STM3(500320|750330|1000340)AS?",
603 "MX15",
604 "There are known problems with these drives,\n"
605 "AND THIS FIRMWARE VERSION IS AFFECTED,\n"
606 "see the following Seagate web pages:\n"
607 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207931\n"
608 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207969",
609 ""
610 },
611 { "Seagate Maxtor DiamondMax 22", // unknown firmware
612 "(MAXTOR )?STM3(160813|32061[34]|500320|640323|750330|10003(34|40))AS?",
613 "",
614 "There are known problems with these drives,\n"
615 "see the following Seagate web pages:\n"
616 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207931\n"
617 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207969\n"
618 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207975",
619 ""
620 },
621 { "Seagate Maxtor DiamondMax 23",
622 "STM3((160|250)31|(320|500)41|(750|1000)52)8AS?",
623 "", "", ""
1953ff6d 624 },
832b75ed 625 { "Maxtor MaXLine Plus II",
2127e193
GI
626 "Maxtor 7Y250[PM]0",
627 "",
628 "",
629 "-v 9,minutes"
832b75ed
GG
630 },
631 { "Maxtor MaXLine II family",
2127e193
GI
632 "Maxtor [45]A(25|30|32)0[JN]0",
633 "",
634 "",
635 "-v 9,minutes"
832b75ed 636 },
ba59cff1 637 { "Maxtor MaXLine III family (ATA/133 and SATA/150)",
2127e193
GI
638 "Maxtor 7L(25|30)0[SR]0",
639 "",
640 "",
641 "-v 9,minutes"
ba59cff1
GG
642 },
643 { "Maxtor MaXLine III family (SATA/300)",
2127e193
GI
644 "Maxtor 7V(25|30)0F0",
645 "", "", ""
ba59cff1
GG
646 },
647 { "Maxtor MaXLine Pro 500 family", // There is also a 7H500R0 model, but I
2127e193
GI
648 "Maxtor 7H500F0", // haven't added it because I suspect
649 "", // it might need vendoropts_9_minutes
650 "", "" // and nobody has submitted a report yet
ba59cff1 651 },
2127e193
GI
652 { "", // HITACHI_DK14FA-20B
653 "HITACHI_DK14FA-20B",
654 "",
655 "",
656 "-v 9,minutes -v 193,loadunload"
832b75ed
GG
657 },
658 { "HITACHI Travelstar DK23XX/DK23XXB series",
2127e193
GI
659 "HITACHI_DK23..-..B?",
660 "",
661 "",
662 "-v 9,minutes -v 193,loadunload"
832b75ed
GG
663 },
664 { "Hitachi Endurastar J4K20/N4K20 (formerly DK23FA-20J)",
2127e193
GI
665 "(HITACHI_DK23FA-20J|HTA422020F9AT[JN]0)",
666 "",
667 "",
668 "-v 9,minutes -v 193,loadunload"
669 },
670 { "Hitachi Endurastar J4K30/N4K30",
671 "HE[JN]4230[23]0F9AT00",
672 "",
673 "",
674 "-v 9,minutes -v 193,loadunload"
675 },
676 { "Hitachi Travelstar C4K60 family", // 1.8" slim drive
677 "HTC4260[23]0G5CE00|HTC4260[56]0G8CE00",
678 "",
679 "",
680 "-v 9,minutes -v 193,loadunload"
832b75ed 681 },
ba59cff1 682 { "IBM Travelstar 4GT family",
2127e193
GI
683 "IBM-DTCA-2(324|409)0",
684 "", "", ""
685 },
686 { "IBM Travelstar 6GN family",
687 "IBM-DBCA-20(324|486|648)0",
688 "", "", ""
ba59cff1 689 },
832b75ed 690 { "IBM Travelstar 25GS, 18GT, and 12GN family",
2127e193
GI
691 "IBM-DARA-2(25|18|15|12|09|06)000",
692 "", "", ""
693 },
694 { "IBM Travelstar 14GS",
695 "IBM-DCYA-214000",
696 "", "", ""
697 },
698 { "IBM Travelstar 4LP",
699 "IBM-DTNA-2(180|216)0",
700 "", "", ""
832b75ed
GG
701 },
702 { "IBM Travelstar 48GH, 30GN, and 15GN family",
2127e193
GI
703 "(IBM-|Hitachi )?IC25(T048ATDA05|N0(30|20|15|12|10|07|06|05)ATDA04)-.",
704 "", "", ""
832b75ed
GG
705 },
706 { "IBM Travelstar 32GH, 30GT, and 20GN family",
2127e193
GI
707 "IBM-DJSA-2(32|30|20|10|05)",
708 "", "", ""
832b75ed 709 },
ba59cff1 710 { "IBM Travelstar 4GN family",
2127e193
GI
711 "IBM-DKLA-2(216|324|432)0",
712 "", "", ""
832b75ed
GG
713 },
714 { "IBM/Hitachi Travelstar 60GH and 40GN family",
2127e193
GI
715 "(IBM-|Hitachi )?IC25(T060ATC[SX]05|N0[4321]0ATC[SX]04)-.",
716 "", "", ""
832b75ed
GG
717 },
718 { "IBM/Hitachi Travelstar 40GNX family",
2127e193
GI
719 "(IBM-|Hitachi )?IC25N0[42]0ATC[SX]05-.",
720 "", "", ""
832b75ed
GG
721 },
722 { "Hitachi Travelstar 80GN family",
2127e193
GI
723 "(Hitachi )?IC25N0[23468]0ATMR04-.",
724 "", "", ""
832b75ed 725 },
1953ff6d 726 { "Hitachi Travelstar 4K40",
2127e193
GI
727 "(Hitachi )?HTS4240[234]0M9AT00",
728 "", "", ""
729 },
730 { "Hitachi Travelstar 4K120",
731 "(Hitachi )?(HTS4212(60|80|10|12)H9AT00|HTS421260G9AT00)",
732 "", "", ""
1953ff6d 733 },
832b75ed 734 { "Hitachi Travelstar 5K80 family",
2127e193
GI
735 "(Hitachi )?HTS5480[8642]0M9AT00",
736 "", "", ""
832b75ed
GG
737 },
738 { "Hitachi Travelstar 5K100 series",
2127e193
GI
739 "(Hitachi )?HTS5410[1864]0G9(AT|SA)00",
740 "", "", ""
832b75ed 741 },
ba59cff1 742 { "Hitachi Travelstar E5K100 series",
2127e193
GI
743 "(Hitachi )?HTE541040G9(AT|SA)00",
744 "", "", ""
1953ff6d
GG
745 },
746 { "Hitachi Travelstar 5K120",
2127e193
GI
747 "(Hitachi )?HTS5412(60|80|10|12)H9(AT|SA)00",
748 "", "", ""
ba59cff1 749 },
a37e7145 750 { "Hitachi Travelstar 5K160 series",
2127e193
GI
751 "(Hitachi |HITACHI )?HTS5416([468]0|1[26])J9(AT|SA)00",
752 "", "", ""
753 },
754 { "Hitachi Travelstar E5K160 series",
755 "(Hitachi )?HTE5416(12|16|60|80)J9(AT|SA)00",
756 "", "", ""
757 },
758 { "Hitachi Travelstar 5K250 series",
759 "(Hitachi |HITACHI )?HTS5425(80|12|16|20|25)K9(A3|SA)00",
760 "", "", ""
a37e7145 761 },
832b75ed 762 { "Hitachi Travelstar 7K60",
2127e193
GI
763 "(Hitachi )?HTS726060M9AT00",
764 "", "", ""
1953ff6d
GG
765 },
766 { "Hitachi Travelstar E7K60",
2127e193
GI
767 "(Hitachi )?HTE7260[46]0M9AT00",
768 "", "", ""
832b75ed 769 },
ba59cff1 770 { "Hitachi Travelstar 7K100",
2127e193
GI
771 "(Hitachi )?HTS7210[168]0G9(AT|SA)00",
772 "", "", ""
ba59cff1
GG
773 },
774 { "Hitachi Travelstar E7K100",
2127e193
GI
775 "(Hitachi )?HTE7210[168]0G9(AT|SA)00",
776 "", "", ""
ba59cff1 777 },
1953ff6d 778 { "Hitachi Travelstar 7K200",
2127e193
GI
779 "(Hitachi )?HTS7220(80|10|12|16|20)K9(A3|SA)00",
780 "", "", ""
832b75ed 781 },
2127e193
GI
782 { "IBM Deskstar 14GXP and 16GP series",
783 "IBM-DTTA-3(7101|7129|7144|5032|5043|5064|5084|5101|5129|5168)0",
784 "", "", ""
832b75ed 785 },
2127e193
GI
786 { "IBM Deskstar 25GP and 22GXP family",
787 "IBM-DJNA-3(5(101|152|203|250)|7(091|135|180|220))0",
788 "", "", ""
832b75ed 789 },
2127e193
GI
790 { "IBM Deskstar 37GP and 34GXP family",
791 "IBM-DPTA-3(5(375|300|225|150)|7(342|273|205|136))0",
792 "", "", ""
832b75ed 793 },
2127e193
GI
794 { "IBM/Hitachi Deskstar 120GXP family",
795 "(IBM-)?IC35L((020|040|060|080|120)AVVA|0[24]0AVVN)07-[01]",
796 "", "", ""
797 },
798 { "IBM/Hitachi Deskstar GXP-180 family",
799 "(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]",
800 "", "", ""
832b75ed
GG
801 },
802 { "Hitachi Deskstar 7K80 series",
2127e193
GI
803 "(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380).*",
804 "", "", ""
832b75ed 805 },
1953ff6d 806 { "Hitachi Deskstar 7K160",
2127e193
GI
807 "(Hitachi )?HDS7216(80|16)PLA[3T]80.*",
808 "", "", ""
1953ff6d 809 },
832b75ed 810 { "Hitachi Deskstar 7K250 series",
2127e193
GI
811 "(Hitachi )?HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)",
812 "", "", ""
813 },
814 { "Hitachi Deskstar 7K250 (SUN branded)",
815 "HITACHI HDS7225SBSUN250G.*",
816 "", "", ""
832b75ed 817 },
ba59cff1 818 { "Hitachi Deskstar T7K250 series",
2127e193
GI
819 "(Hitachi )?HDT7225((25|20|16)DLA(T80|380))",
820 "", "", ""
ba59cff1 821 },
832b75ed 822 { "Hitachi Deskstar 7K400 series",
2127e193
GI
823 "(Hitachi )?HDS724040KL(AT|SA)80",
824 "", "", ""
832b75ed 825 },
ba59cff1 826 { "Hitachi Deskstar 7K500 series",
2127e193
GI
827 "(Hitachi )?HDS725050KLA(360|T80)",
828 "", "", ""
829 },
830 { "Hitachi Deskstar P7K500 series",
831 "(Hitachi )?HDP7250(16|25|32|40|50)GLA(36|38|T8)0",
832 "", "", ""
832b75ed 833 },
1953ff6d 834 { "Hitachi Deskstar T7K500",
2127e193
GI
835 "(Hitachi )?HDT7250(25|32|40|50)VLA(360|380|T80)",
836 "", "", ""
1953ff6d
GG
837 },
838 { "Hitachi Deskstar 7K1000",
2127e193
GI
839 "(Hitachi )?HDS7210(50|75|10)KLA330",
840 "", "", ""
841 },
842 { "Hitachi Deskstar 7K1000.B",
843 "(Hitachi )?HDT7210((16|25)SLA380|(32|50|64|75|10)SLA360)",
844 "", "", ""
1953ff6d
GG
845 },
846 { "Hitachi Ultrastar 7K1000",
2127e193
GI
847 "(Hitachi )?HUA7210(50|75|10)KLA330",
848 "", "", ""
849 },
850 { "Toshiba 2.5\" HDD series (10-20 GB)",
851 "TOSHIBA MK(101[67]GAP|15[67]GAP|20(1[678]GAP|(18|23)GAS))",
852 "", "", ""
1953ff6d 853 },
ba59cff1 854 { "Toshiba 2.5\" HDD series (30-60 GB)",
2127e193
GI
855 "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)",
856 "", "", ""
832b75ed 857 },
ba59cff1 858 { "Toshiba 2.5\" HDD series (80 GB and above)",
2127e193
GI
859 "TOSHIBA MK(80(25GAS|26GAX|32GAX|32GSX)|10(31GAS|32GAX)|12(33GAS|34G[AS]X)|2035GSS)",
860 "", "", ""
861 },
862 { "Toshiba 2.5\" HDD MK..52GSX series",
863 "TOSHIBA MK(80|12|16|25|32)52GSX",
864 "", "", ""
832b75ed 865 },
1953ff6d 866 { "Toshiba 1.8\" HDD series",
2127e193
GI
867 "TOSHIBA MK[23468]00[4-9]GA[HL]",
868 "", "", ""
869 },
870 { "", // TOSHIBA MK6022GAX
871 "TOSHIBA MK6022GAX",
872 "", "", ""
873 },
874 { "", // TOSHIBA MK6409MAV
875 "TOSHIBA MK6409MAV",
876 "", "", ""
877 },
878 { "Toshiba MKx019GAXB (SUN branded)",
879 "TOS MK[34]019GAXB SUN[34]0G",
880 "", "", ""
832b75ed 881 },
ba59cff1 882 { "Seagate Momentus family",
2127e193
GI
883 "ST9(20|28|40|48)11A",
884 "", "", ""
832b75ed 885 },
ba59cff1 886 { "Seagate Momentus 42 family",
2127e193
GI
887 "ST9(2014|3015|4019)A",
888 "", "", ""
832b75ed 889 },
2127e193
GI
890 { "Seagate Momentus 4200.2 series",
891 "ST9(100822|808210|60821|50212|402113|30219)A",
892 "", "", ""
832b75ed 893 },
ba59cff1 894 { "Seagate Momentus 5400.2 series",
2127e193
GI
895 "ST9(808211|60822|408114|308110|120821|10082[34]|8823|6812|4813|3811)AS?",
896 "", "", ""
897 },
898 { "Seagate Momentus 5400.3 series",
899 "ST9(4081[45]|6081[35]|8081[15]|100828|120822|160821)AS?",
900 "", "", ""
901 },
902 { "Seagate Momentus 5400.3 ED series",
903 "ST9(4081[45]|6081[35]|8081[15]|100828|120822|160821)AB",
904 "", "", ""
832b75ed 905 },
2127e193
GI
906 { "Seagate Momentus 5400.4 series",
907 "ST9(120817|(160|200|250)827)AS",
908 "", "", ""
1953ff6d 909 },
2127e193
GI
910 { "Seagate Momentus 5400.5 series",
911 "ST9((80|120|160)310|(250|320)320)AS",
912 "", "", ""
913 },
914 { "Seagate Momentus 5400.6 series",
915 "ST9((12|25)0315AS|500325)ASG?",
916 "", "", ""
917 },
918 { "Seagate Momentus 5400 PSD series", // Hybrid drives
919 "ST9(808212|(120|160)8220)AS",
920 "", "", ""
1953ff6d 921 },
ba59cff1 922 { "Seagate Momentus 7200.1 series",
2127e193
GI
923 "ST9(10021|80825|6023|4015)AS?",
924 "", "", ""
925 },
926 { "Seagate Momentus 7200.2 series",
927 "ST9(80813|100821|120823|160823|200420)ASG?",
928 "", "", ""
832b75ed 929 },
2127e193
GI
930 { "Seagate Momentus 7200.3 series",
931 "ST9((80|120|160)411|(250|320)421)ASG?",
932 "", "", ""
933 },
934 { "Seagate Medalist 1010, 1721, 2120, 3230 and 4340", // ATA2, with -t permissive
935 "ST3(1010|1721|2120|3230|4340)A",
936 "", "", ""
1953ff6d 937 },
ba59cff1 938 { "Seagate Medalist 2110, 3221, 4321, 6531, and 8641",
2127e193
GI
939 "ST3(2110|3221|4321|6531|8641)A",
940 "", "", ""
832b75ed 941 },
ba59cff1 942 { "Seagate U Series X family",
2127e193
GI
943 "ST3(10014A(CE)?|20014A)",
944 "", "", ""
945 },
946 { "Seagate U8 family",
947 "ST3(4313|6811|8410|13021|17221)A",
948 "", "", ""
832b75ed 949 },
ba59cff1 950 { "Seagate U7 family",
2127e193
GI
951 "ST3(30012|40012|60012|80022|120020)A",
952 "", "", ""
832b75ed
GG
953 },
954 { "Seagate U Series 6 family",
2127e193
GI
955 "ST3(8002|6002|4081|3061|2041)0A",
956 "", "", ""
832b75ed
GG
957 },
958 { "Seagate U Series 5 family",
2127e193
GI
959 "ST3(40823|30621|20413|15311|10211)A",
960 "", "", ""
832b75ed
GG
961 },
962 { "Seagate U4 family",
2127e193
GI
963 "ST3(2112|4311|6421|8421)A",
964 "", "", ""
832b75ed
GG
965 },
966 { "Seagate U8 family",
2127e193
GI
967 "ST3(8410|4313|17221|13021)A",
968 "", "", ""
832b75ed
GG
969 },
970 { "Seagate U10 family",
2127e193
GI
971 "ST3(20423|15323|10212)A",
972 "", "", ""
973 },
974 { "Seagate Barracuda ATA family",
975 "ST3(2804|2724|2043|1362|1022|681)0A",
976 "", "", ""
832b75ed
GG
977 },
978 { "Seagate Barracuda ATA II family",
2127e193
GI
979 "ST3(3063|2042|1532|1021)0A",
980 "", "", ""
832b75ed
GG
981 },
982 { "Seagate Barracuda ATA III family",
2127e193
GI
983 "ST3(40824|30620|20414|15310|10215)A",
984 "", "", ""
832b75ed
GG
985 },
986 { "Seagate Barracuda ATA IV family",
2127e193
GI
987 "ST3(20011|30011|40016|60021|80021)A",
988 "", "", ""
832b75ed
GG
989 },
990 { "Seagate Barracuda ATA V family",
2127e193
GI
991 "ST3(12002(3A|4A|9A|3AS)|800(23A|15A|23AS)|60(015A|210A)|40017A)",
992 "", "", ""
832b75ed
GG
993 },
994 { "Seagate Barracuda 5400.1",
2127e193
GI
995 "ST340015A",
996 "", "", ""
832b75ed
GG
997 },
998 { "Seagate Barracuda 7200.7 and 7200.7 Plus family",
2127e193
GI
999 "ST3(200021A|200822AS?|16002[13]AS?|12002[26]AS?|1[26]082[78]AS|8001[13]AS?|8081[79]AS|60014A|40111AS|40014AS?)",
1000 "", "", ""
832b75ed
GG
1001 },
1002 { "Seagate Barracuda 7200.8 family",
2127e193
GI
1003 "ST3(400[68]32|300[68]31|250[68]23|200826)AS?",
1004 "", "", ""
ba59cff1
GG
1005 },
1006 { "Seagate Barracuda 7200.9 family",
2127e193
GI
1007 "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?.*",
1008 "", "", ""
ba59cff1
GG
1009 },
1010 { "Seagate Barracuda 7200.10 family",
2127e193
GI
1011 "ST3((80|160)[28]15|200820|250[34]10|(250|300|320|400)[68]20|500[68]30|750[68]40)AS?",
1012 "", "", ""
1013 },
1014 { "Seagate Barracuda 7200.11 family", // unaffected firmware
1015 "ST3(160813|320[68]13|500[368]20|640[36]23|640[35]30|750[36]30|1000(333|[36]40)|1500341)AS?",
1016 "CC.?.?", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957
1017 "", ""
1018 },
1019 { "Seagate Barracuda 7200.11 family", // fixed firmware
1020 "ST3(500[368]20|750[36]30|1000340)AS?",
1021 "SD1A", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207951
1022 "", ""
1023 },
1024 { "Seagate Barracuda 7200.11 family", // fixed firmware
1025 "ST3(160813|320[68]13|640[36]23|1000333|1500341)AS?",
1026 "SD1B", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957
1027 "", ""
1028 },
1029 { "Seagate Barracuda 7200.11 family", // buggy firmware
1030 "ST3(500[368]20|640[35]30|750[36]30|1000340)AS?",
1031 "(AD14|SD1[5-9])",
1032 "There are known problems with these drives,\n"
1033 "AND THIS FIRMWARE VERSION IS AFFECTED,\n"
1034 "see the following Seagate web pages:\n"
1035 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207931\n"
1036 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207951",
1037 ""
1038 },
1039 { "Seagate Barracuda 7200.11 family", // unknown firmware
1040 "ST3(160813|320[68]13|500[368]20|640[36]23|640[35]30|750[36]30|1000(333|[36]40)|1500341)AS?",
1041 "",
1042 "There are known problems with these drives,\n"
1043 "see the following Seagate web pages:\n"
1044 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207931\n"
1045 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207951\n"
1046 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957",
1047 ""
1048 },
1049 { "Seagate Barracuda 7200.12 family",
1050 "ST3((160|250)318|(320|500)418|500410|(750|1000)528)AS",
1051 "", "", ""
1953ff6d
GG
1052 },
1053 { "Seagate Barracuda ES",
2127e193
GI
1054 "ST3(250[68]2|32062|40062|50063|75064)0NS",
1055 "", "", ""
1056 },
1057 { "Seagate Barracuda ES.2", // fixed firmware
1058 "ST3(25031|50032|75033|100034)0NS",
1059 "SN[01]6", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207963
1060 "", ""
1061 },
1062 { "Seagate Barracuda ES.2", // unknown firmware
1063 "ST3(25031|50032|75033|100034)0NS",
1064 "",
1065 "There are known problems with these drives,\n"
1066 "see the following Seagate web pages:\n"
1067 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207931\n"
1068 "http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207963",
1069 ""
832b75ed
GG
1070 },
1071 { "Seagate Medalist 17240, 13030, 10231, 8420, and 4310",
2127e193
GI
1072 "ST3(17240|13030|10231|8420|4310)A",
1073 "", "", ""
832b75ed
GG
1074 },
1075 { "Seagate Medalist 17242, 13032, 10232, 8422, and 4312",
2127e193
GI
1076 "ST3(1724|1303|1023|842|431)2A",
1077 "", "", ""
832b75ed 1078 },
ba59cff1 1079 { "Seagate NL35 family",
2127e193
GI
1080 "ST3(250623|250823|400632|400832|250824|250624|400633|400833|500641|500841)NS",
1081 "", "", ""
1082 },
1083 { "Seagate SV35.2 Series",
1084 "ST3(160815|250820|320620|500630|750640)(A|S)V",
1085 "", "", ""
1086 },
1087 { "Seagate DB35.3 Series",
1088 "ST3(750640SCE|((80|160)215|(250|320|400)820|500830|750840)(A|S)CE)",
1089 "", "", ""
ba59cff1 1090 },
832b75ed
GG
1091 { "Western Digital Protege",
1092 /* Western Digital drives with this comment all appear to use Attribute 9 in
1093 * a non-standard manner. These entries may need to be updated when it
1094 * is understood exactly how Attribute 9 should be interpreted.
1095 * UPDATE: this is probably explained by the WD firmware bug described in the
1096 * smartmontools FAQ */
2127e193
GI
1097 "WDC WD([2468]00E|1[26]00A)B-.*",
1098 "", "", ""
832b75ed
GG
1099 },
1100 { "Western Digital Caviar family",
1101 /* Western Digital drives with this comment all appear to use Attribute 9 in
1102 * a non-standard manner. These entries may need to be updated when it
1103 * is understood exactly how Attribute 9 should be interpreted.
1104 * UPDATE: this is probably explained by the WD firmware bug described in the
1105 * smartmontools FAQ */
2127e193
GI
1106 "WDC WD(2|3|4|6|8|10|12|16|18|20|25)00BB-.*",
1107 "", "", ""
832b75ed
GG
1108 },
1109 { "Western Digital Caviar WDxxxAB series",
1110 /* Western Digital drives with this comment all appear to use Attribute 9 in
1111 * a non-standard manner. These entries may need to be updated when it
1112 * is understood exactly how Attribute 9 should be interpreted.
1113 * UPDATE: this is probably explained by the WD firmware bug described in the
1114 * smartmontools FAQ */
2127e193
GI
1115 "WDC WD(3|4|6|8|25)00AB-.*",
1116 "", "", ""
832b75ed
GG
1117 },
1118 { "Western Digital Caviar WDxxxAA series",
1119 /* Western Digital drives with this comment all appear to use Attribute 9 in
1120 * a non-standard manner. These entries may need to be updated when it
1121 * is understood exactly how Attribute 9 should be interpreted.
1122 * UPDATE: this is probably explained by the WD firmware bug described in the
1123 * smartmontools FAQ */
2127e193
GI
1124 "WDC WD...?AA(-.*)?",
1125 "", "", ""
832b75ed
GG
1126 },
1127 { "Western Digital Caviar WDxxxBA series",
1128 /* Western Digital drives with this comment all appear to use Attribute 9 in
1129 * a non-standard manner. These entries may need to be updated when it
1130 * is understood exactly how Attribute 9 should be interpreted.
1131 * UPDATE: this is probably explained by the WD firmware bug described in the
1132 * smartmontools FAQ */
2127e193
GI
1133 "WDC WD...BA",
1134 "", "", ""
832b75ed 1135 },
2127e193
GI
1136 { "Western Digital Caviar AC series", // add only 5400rpm/7200rpm (ata33 and faster)
1137 "WDC AC((116|121|125|225|132|232)|([1-4][4-9][0-9])|([1-4][0-9][0-9][0-9]))00[A-Z]?.*",
1138 "", "", ""
ba59cff1 1139 },
832b75ed
GG
1140 { "Western Digital Caviar SE family",
1141 /* Western Digital drives with this comment all appear to use Attribute 9 in
1142 * a non-standard manner. These entries may need to be updated when it
1143 * is understood exactly how Attribute 9 should be interpreted.
1144 * UPDATE: this is probably explained by the WD firmware bug described in the
1953ff6d
GG
1145 * smartmontools FAQ
1146 * UPDATE 2: this does not apply to more recent models, at least WD3200AAJB */
2127e193
GI
1147 "WDC WD(4|6|8|10|12|16|18|20|25|30|32|40|50)00(JB|PB)-.*",
1148 "", "", ""
1149 },
1150 { "Western Digital Caviar Blue EIDE family", // WD Caviar SE EIDE family
1151 /* not completely accurate: at least also WD800JB, WD(4|8|20|25)00BB sold as Caviar Blue */
1152 "WDC WD(16|25|32|40|50)00AAJB-.*",
1153 "", "", ""
1154 },
1155 { "Western Digital Caviar Blue EIDE family", // WD Caviar SE16 EIDE family
1156 "WDC WD(25|32|40|50)00AAKB-.*",
1157 "", "", ""
1158 },
1159 { "Western Digital RE EIDE family",
1160 "WDC WD(12|16|25|32)00SB-.*",
1161 "", "", ""
1162 },
1163 { "Western Digital Caviar Serial ATA family",
1164 "WDC WD(4|8|20|32)00BD-.*",
1165 "", "", ""
1166 },
1167 { "Western Digital Caviar SE Serial ATA family",
1168 "WDC WD(4|8|12|16|20|25|32|40)00(JD|KD|PD)-.*",
1169 "", "", ""
1953ff6d
GG
1170 },
1171 { "Western Digital Caviar SE Serial ATA family",
2127e193
GI
1172 "WDC WD(8|12|16|20|25|30|32|40|50)00JS-.*",
1173 "", "", ""
1174 },
1175 { "Western Digital Caviar SE16 Serial ATA family",
1176 "WDC WD(16|20|25|32|40|50|75)00KS-.*",
1177 "", "", ""
1178 },
1179 { "Western Digital Caviar Blue Serial ATA family", // WD Caviar SE Serial ATA family
1180 /* not completely accurate: at least also WD800BD, (4|8)00JD sold as Caviar Blue */
1181 "WDC WD((8|12|16|25|32)00AABS|(12|16|25|32|40|50)00AAJS)-.*",
1182 "", "", ""
1183 },
1184 { "Western Digital Caviar Blue Serial ATA family", // WD Caviar SE16 Serial ATA family
1185 "WDC WD(16|20|25|32|40|50|64|75)00AAKS-.*",
1186 "", "", ""
1187 },
1188 { "Western Digital RE Serial ATA family",
1189 "WDC WD(12|16|25|32)00(SD|YD|YS)-.*",
1190 "", "", ""
1191 },
1192 { "Western Digital RE2 Serial ATA family",
1193 "WDC WD((40|50|75)00(YR|YS|AYYS)|(16|32|40|50)0[01]ABYS)-.*",
1194 "", "", ""
1195 },
1196 { "Western Digital RE2-GP family",
1197 "WDC WD(5000AB|7500AY|1000FY)PS-.*",
1198 "", "", ""
1199 },
1200 { "Western Digital RE3 Serial ATA family",
1201 "WDC WD((25|32|50)02A|(75|10)02F)BYS-.*",
1202 "", "", ""
1203 },
1204 { "Western Digital Caviar Green family",
1205 "WDC WD((50|64|75)00AA(C|V)S|(50|75)00AADS|10EA(C|V)S|(10|15|20)EADS)-.*",
1206 "", "", ""
832b75ed 1207 },
2127e193
GI
1208 { "Western Digital Caviar Black family",
1209 "WDC WD((500|640|750)1AA|1001FA)LS-.*",
1210 "", "", ""
ba59cff1 1211 },
2127e193
GI
1212 { "Western Digital AV ATA family",
1213 "WDC WD(8|16|50)00AV(B|J)B-.*",
1214 "", "", ""
832b75ed 1215 },
2127e193
GI
1216 { "Western Digital AV-GP family",
1217 "WDC WD((16|25|32|50|64|75)00AVVS|(50|75)00AVCS|10EVVS|(10|20)EVCS|WD(10|15|20)EVDS)-.*",
1218 "", "", ""
832b75ed
GG
1219 },
1220 { "Western Digital Raptor family",
2127e193
GI
1221 "WDC WD((360|740|800)GD|(360|740|1500)ADF[DS])-.*",
1222 "", "", ""
832b75ed 1223 },
2127e193
GI
1224 { "Western Digital VelociRaptor family",
1225 "WDC WD((1500|3000)B|3000G)LFS-.*",
1226 "", "", ""
1227 },
1228 { "Western Digital Scorpio EIDE family",
1229 "WDC WD(4|6|8|10|12|16)00(UE|VE)-.*",
1230 "", "", ""
1231 },
1232 { "Western Digital Scorpio Blue EIDE family",
1233 "WDC WD(4|6|8|10|12|16|25)00BEVE-.*",
1234 "", "", ""
1235 },
1236 { "Western Digital Scorpio Serial ATA family",
1237 "WDC WD(4|6|8|10|12|16|25)00BEAS-.*",
1238 "", "", ""
1239 },
1240 { "Western Digital Scorpio Blue Serial ATA family",
1241 "WDC WD((4|6|8|10|12|16|25)00BEVS|(8|12|16|25|32|40|50)00BEVT)-.*",
1242 "", "", ""
1243 },
1244 { "Western Digital Scorpio Black Serial ATA family",
1245 "WDC WD(8|12|16|25|32)00B[EJ]KT-.*",
1246 "", "", ""
1247 },
1248 { "Quantum Bigfoot series",
1249 "QUANTUM BIGFOOT TS10.0A",
1250 "", "", ""
1251 },
1252 { "Quantum Fireball lct15 series",
1253 "QUANTUM FIREBALLlct15 ([123]0|22)",
1254 "", "", ""
1255 },
1256 { "Quantum Fireball lct20 series",
1257 "QUANTUM FIREBALLlct20 [234]0",
1258 "", "", ""
1259 },
1260 { "Quantum Fireball CX series",
1261 "QUANTUM FIREBALL CX10.2A",
1262 "", "", ""
832b75ed
GG
1263 },
1264 { "Quantum Fireball CR series",
2127e193
GI
1265 "QUANTUM FIREBALL CR(4.3|6.4|8.4|13.0)A",
1266 "", "", ""
832b75ed 1267 },
2127e193
GI
1268 { "Quantum Fireball EX series",
1269 "QUANTUM FIREBALL EX(3.2|6.4)A",
1270 "", "", ""
1271 },
1272 { "Quantum Fireball ST series",
1273 "QUANTUM FIREBALL ST(3.2|4.3|4300)A",
1274 "", "", ""
ba59cff1
GG
1275 },
1276 { "Quantum Fireball SE series",
2127e193
GI
1277 "QUANTUM FIREBALL SE4.3A",
1278 "", "", ""
1279 },
1280 { "Quantum Fireball Plus LM series",
1281 "QUANTUM FIREBALLP LM(10.2|15|20.[45]|30)",
1282 "", "", ""
1283 },
1284 { "Quantum Fireball Plus AS series",
1285 "QUANTUM FIREBALLP AS(10.2|20.5|30.0|40.0)",
1286 "", "", ""
1287 },
1288 { "Quantum Fireball Plus KX series",
1289 "QUANTUM FIREBALLP KX27.3",
1290 "", "", ""
1291 },
1292 { "Quantum Fireball Plus KA series",
1293 "QUANTUM FIREBALLP KA(9|10).1",
1294 "", "", ""
1295 },
1296// END drivedb.h (DO NOT DELETE - used by Makefile)
832b75ed
GG
1297};
1298
2127e193
GI
1299
1300/// Drive database class. Stores custom entries read from file.
1301/// Provides transparent access to concatenation of custom and
1302/// default table.
1303class drive_database
1304{
1305public:
1306 drive_database();
1307
1308 ~drive_database();
1309
1310 /// Get total number of entries.
1311 unsigned size() const
1312 { return m_custom_tab.size() + m_builtin_size; }
1313
1314 /// Get number of custom entries.
1315 unsigned custom_size() const
1316 { return m_custom_tab.size(); }
1317
1318 /// Array access.
1319 const drive_settings & operator[](unsigned i);
1320
1321 /// Append new custom entry.
1322 void push_back(const drive_settings & src);
1323
1324 /// Append builtin table.
1325 void append(const drive_settings * builtin_tab, unsigned builtin_size)
1326 { m_builtin_tab = builtin_tab; m_builtin_size = builtin_size; }
1327
1328private:
1329 const drive_settings * m_builtin_tab;
1330 unsigned m_builtin_size;
1331
1332 std::vector<drive_settings> m_custom_tab;
1333 std::vector<char *> m_custom_strings;
1334
1335 const char * copy_string(const char * str);
1336
1337 drive_database(const drive_database &);
1338 void operator=(const drive_database &);
1339};
1340
1341drive_database::drive_database()
1342: m_builtin_tab(0), m_builtin_size(0)
1343{
1344}
1345
1346drive_database::~drive_database()
1347{
1348 for (unsigned i = 0; i < m_custom_strings.size(); i++)
1349 delete [] m_custom_strings[i];
1350}
1351
1352const drive_settings & drive_database::operator[](unsigned i)
1353{
1354 return (i < m_custom_tab.size() ? m_custom_tab[i]
1355 : m_builtin_tab[i - m_custom_tab.size()] );
1356}
1357
1358void drive_database::push_back(const drive_settings & src)
1359{
1360 drive_settings dest;
1361 dest.modelfamily = copy_string(src.modelfamily);
1362 dest.modelregexp = copy_string(src.modelregexp);
1363 dest.firmwareregexp = copy_string(src.firmwareregexp);
1364 dest.warningmsg = copy_string(src.warningmsg);
1365 dest.presets = copy_string(src.presets);
1366 m_custom_tab.push_back(dest);
1367}
1368
1369const char * drive_database::copy_string(const char * src)
1370{
1371 char * dest = new char[strlen(src)+1];
1372 try {
1373 m_custom_strings.push_back(dest);
1374 }
1375 catch (...) {
1376 delete [] dest; throw;
1377 }
1378 return strcpy(dest, src);
1379}
1380
1381
1382/// The drive database.
1383static drive_database knowndrives;
1384
1385
1386// Compile regular expression, print message on failure.
1387static bool compile(regular_expression & regex, const char *pattern)
1388{
1389 if (!regex.compile(pattern, REG_EXTENDED)) {
1390 pout("Internal error: unable to compile regular expression \"%s\": %s\n"
1391 "Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n",
1392 pattern, regex.get_errmsg());
1393 return false;
1394 }
1395 return true;
1396}
1397
1398// Compile & match a regular expression.
1399static bool match(const char * pattern, const char * str)
1400{
1401 regular_expression regex;
1402 if (!compile(regex, pattern))
1403 return false;
1404 return regex.full_match(str);
1405}
1406
832b75ed
GG
1407// Searches knowndrives[] for a drive with the given model number and firmware
1408// string. If either the drive's model or firmware strings are not set by the
2127e193
GI
1409// manufacturer then values of NULL may be used. Returns the entry of the
1410// first match in knowndrives[] or 0 if no match if found.
1411const drive_settings * lookup_drive(const char * model, const char * firmware)
832b75ed 1412{
2127e193
GI
1413 if (!model)
1414 model = "";
1415 if (!firmware)
1416 firmware = "";
832b75ed 1417
2127e193
GI
1418 for (unsigned i = 0; i < knowndrives.size(); i++) {
1419 // Check whether model matches the regular expression in knowndrives[i].
1420 if (!match(knowndrives[i].modelregexp, model))
1421 continue;
832b75ed 1422
2127e193
GI
1423 // Model matches, now check firmware. "" matches always.
1424 if (!( !*knowndrives[i].firmwareregexp
1425 || match(knowndrives[i].firmwareregexp, firmware)))
1426 continue;
832b75ed 1427
2127e193
GI
1428 // Found
1429 return &knowndrives[i];
832b75ed
GG
1430 }
1431
2127e193
GI
1432 // Not found
1433 return 0;
832b75ed
GG
1434}
1435
2127e193
GI
1436// Parse '-v' and '-F' options in preset string, return false on error.
1437static bool parse_presets(const char * presets, unsigned char * opts, unsigned char & fix_firmwarebug)
1438{
1439 for (int i = 0; ; ) {
1440 i += strspn(presets+i, " \t");
1441 if (!presets[i])
1442 break;
1443 char opt, arg[40+1+13]; int len = -1;
1444 if (!(sscanf(presets+i, "-%c %40[^ ]%n", &opt, arg, &len) >= 2 && len > 0))
1445 return false;
1446 if (opt == 'v') {
1447 // Parse "-v N,option"
1448 unsigned char newopts[MAX_ATTRIBUTE_NUM] = {0, };
1449 if (parse_attribute_def(arg, newopts))
1450 return false;
1451 // Set only if not set by user
1452 for (int j = 0; j < MAX_ATTRIBUTE_NUM; j++)
1453 if (newopts[j] && !opts[j])
1454 opts[j] = newopts[j];
1455 }
1456 else if (opt == 'F') {
1457 unsigned char fix;
1458 if (!strcmp(arg, "samsung"))
1459 fix = FIX_SAMSUNG;
1460 else if (!strcmp(arg, "samsung2"))
1461 fix = FIX_SAMSUNG2;
1462 else if (!strcmp(arg, "samsung3"))
1463 fix = FIX_SAMSUNG3;
1464 else
1465 return false;
1466 // Set only if not set by user
1467 if (fix_firmwarebug == FIX_NOTSPECIFIED)
1468 fix_firmwarebug = fix;
1469 }
1470 else
1471 return false;
832b75ed 1472
2127e193
GI
1473 i += len;
1474 }
1475 return true;
1476}
1477
1478// Shows one entry of knowndrives[], returns #errors.
1479static int showonepreset(const drive_settings * dbentry)
1480{
832b75ed 1481 // Basic error check
2127e193
GI
1482 if (!( dbentry
1483 && dbentry->modelfamily
1484 && dbentry->modelregexp && *dbentry->modelregexp
1485 && dbentry->firmwareregexp
1486 && dbentry->warningmsg
1487 && dbentry->presets )) {
1488 pout("Invalid drive database entry. Please report\n"
832b75ed 1489 "this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
2127e193 1490 return 1;
832b75ed
GG
1491 }
1492
2127e193
GI
1493 // print and check model and firmware regular expressions
1494 int errcnt = 0;
1495 regular_expression regex;
1496 pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", dbentry->modelregexp);
1497 if (!compile(regex, dbentry->modelregexp))
1498 errcnt++;
832b75ed 1499
2127e193
GI
1500 pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", *dbentry->firmwareregexp ?
1501 dbentry->firmwareregexp : ".*"); // preserve old output (TODO: Change)
1502 if (*dbentry->firmwareregexp && !compile(regex, dbentry->firmwareregexp))
1503 errcnt++;
1504
1505 pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL FAMILY:", dbentry->modelfamily);
1506
1507 // if there are any presets, then show them
1508 unsigned char fix_firmwarebug = 0;
1509 bool first_preset = true;
1510 if (*dbentry->presets) {
1511 unsigned char opts[MAX_ATTRIBUTE_NUM] = {0,};
1512 if (!parse_presets(dbentry->presets, opts, fix_firmwarebug)) {
1513 pout("Syntax error in preset option string \"%s\"\n", dbentry->presets);
1514 errcnt++;
1515 }
1516 for (int i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
1517 char out[256];
1518 if (opts[i]) {
1519 ataPrintSmartAttribName(out, i, opts);
1520 // Use leading zeros instead of spaces so that everything lines up.
1521 out[0] = (out[0] == ' ') ? '0' : out[0];
1522 out[1] = (out[1] == ' ') ? '0' : out[1];
1523 pout("%-*s %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "", out);
1524 first_preset = false;
1525 }
1526 }
832b75ed 1527 }
2127e193 1528 if (first_preset)
832b75ed
GG
1529 pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
1530
2127e193
GI
1531 // describe firmwarefix
1532 if (fix_firmwarebug) {
1533 const char * fixdesc;
1534 switch (fix_firmwarebug) {
1535 case FIX_SAMSUNG:
1536 fixdesc = "Fixes byte order in some SMART data (same as -F samsung)";
1537 break;
1538 case FIX_SAMSUNG2:
1539 fixdesc = "Fixes byte order in some SMART data (same as -F samsung2)";
1540 break;
1541 case FIX_SAMSUNG3:
1542 fixdesc = "Fixes completed self-test reported as in progress (same as -F samsung3)";
1543 break;
1544 default:
1545 fixdesc = "UNKNOWN"; errcnt++;
1546 break;
1547 }
1548 pout("%-*s %s\n", TABLEPRINTWIDTH, "OTHER PRESETS:", fixdesc);
832b75ed 1549 }
2127e193 1550
832b75ed 1551 // Print any special warnings
2127e193
GI
1552 if (*dbentry->warningmsg)
1553 pout("%-*s %s\n", TABLEPRINTWIDTH, "WARNINGS:", dbentry->warningmsg);
1554 return errcnt;
832b75ed
GG
1555}
1556
1557// Shows all presets for drives in knowndrives[].
2127e193
GI
1558// Returns #syntax errors.
1559int showallpresets()
1560{
832b75ed
GG
1561 // loop over all entries in the knowndrives[] table, printing them
1562 // out in a nice format
2127e193
GI
1563 int errcnt = 0;
1564 for (unsigned i = 0; i < knowndrives.size(); i++) {
1565 errcnt += showonepreset(&knowndrives[i]);
832b75ed
GG
1566 pout("\n");
1567 }
1568
2127e193
GI
1569 pout("Total number of entries :%5u\n"
1570 "Entries read from file(s):%5u\n\n",
1571 knowndrives.size(), knowndrives.custom_size());
1572
832b75ed
GG
1573 pout("For information about adding a drive to the database see the FAQ on the\n");
1574 pout("smartmontools home page: " PACKAGE_HOMEPAGE "\n");
2127e193
GI
1575
1576 if (errcnt > 0)
1577 pout("\nFound %d syntax error(s) in database.\n"
1578 "Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n", errcnt);
1579 return errcnt;
832b75ed
GG
1580}
1581
1582// Shows all matching presets for a drive in knowndrives[].
1583// Returns # matching entries.
2127e193
GI
1584int showmatchingpresets(const char *model, const char *firmware)
1585{
832b75ed
GG
1586 int cnt = 0;
1587 const char * firmwaremsg = (firmware ? firmware : "(any)");
832b75ed 1588
2127e193
GI
1589 for (unsigned i = 0; i < knowndrives.size(); i++) {
1590 if (!match(knowndrives[i].modelregexp, model))
832b75ed 1591 continue;
2127e193
GI
1592 if ( firmware && *knowndrives[i].firmwareregexp
1593 && !match(knowndrives[i].firmwareregexp, firmware))
832b75ed 1594 continue;
2127e193 1595 // Found
832b75ed
GG
1596 if (++cnt == 1)
1597 pout("Drive found in smartmontools Database. Drive identity strings:\n"
1598 "%-*s %s\n"
1599 "%-*s %s\n"
1600 "match smartmontools Drive Database entry:\n",
1601 TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmwaremsg);
1602 else if (cnt == 2)
1603 pout("and match these additional entries:\n");
1604 showonepreset(&knowndrives[i]);
1605 pout("\n");
1606 }
832b75ed
GG
1607 if (cnt == 0)
1608 pout("No presets are defined for this drive. Its identity strings:\n"
1609 "MODEL: %s\n"
1610 "FIRMWARE: %s\n"
1611 "do not match any of the known regular expressions.\n",
1612 model, firmwaremsg);
1613 return cnt;
1614}
1615
1616// Shows the presets (if any) that are available for the given drive.
2127e193
GI
1617void show_presets(const ata_identify_device * drive, bool fix_swapped_id)
1618{
832b75ed
GG
1619 char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
1620
1621 // get the drive's model/firmware strings
2127e193
GI
1622 format_ata_string(model, drive->model, MODEL_STRING_LENGTH, fix_swapped_id);
1623 format_ata_string(firmware, drive->fw_rev, FIRMWARE_STRING_LENGTH, fix_swapped_id);
832b75ed
GG
1624
1625 // and search to see if they match values in the table
2127e193
GI
1626 const drive_settings * dbentry = lookup_drive(model, firmware);
1627 if (!dbentry) {
832b75ed
GG
1628 // no matches found
1629 pout("No presets are defined for this drive. Its identity strings:\n"
1630 "MODEL: %s\n"
1631 "FIRMWARE: %s\n"
1632 "do not match any of the known regular expressions.\n"
1633 "Use -P showall to list all known regular expressions.\n",
1634 model, firmware);
1635 return;
1636 }
1637
1638 // We found a matching drive. Print out all information about it.
1639 pout("Drive found in smartmontools Database. Drive identity strings:\n"
1640 "%-*s %s\n"
1641 "%-*s %s\n"
1642 "match smartmontools Drive Database entry:\n",
1643 TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmware);
2127e193 1644 showonepreset(dbentry);
832b75ed
GG
1645}
1646
1647// Sets preset vendor attribute options in opts by finding the entry
1648// (if any) for the given drive in knowndrives[]. Values that have
2127e193
GI
1649// already been set in opts will not be changed. Returns false if drive
1650// not recognized.
1651bool apply_presets(const ata_identify_device *drive, unsigned char * opts,
1652 unsigned char & fix_firmwarebug, bool fix_swapped_id)
1653{
832b75ed 1654 // get the drive's model/firmware strings
2127e193
GI
1655 char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
1656 format_ata_string(model, drive->model, MODEL_STRING_LENGTH, fix_swapped_id);
1657 format_ata_string(firmware, drive->fw_rev, FIRMWARE_STRING_LENGTH, fix_swapped_id);
832b75ed
GG
1658
1659 // Look up the drive in knowndrives[].
2127e193
GI
1660 const drive_settings * dbentry = lookup_drive(model, firmware);
1661 if (!dbentry)
1662 return false;
1663
1664 if (*dbentry->presets) {
1665 // Apply presets
1666 if (!parse_presets(dbentry->presets, opts, fix_firmwarebug))
1667 pout("Syntax error in preset option string \"%s\"\n", dbentry->presets);
1668 }
1669 return true;
1670}
1671
1672
1673/////////////////////////////////////////////////////////////////////////////
1674// Parser for drive database files
1675
1676// Abstract pointer to read file input.
1677// Operations supported: c = *p; c = p[1]; ++p;
1678class stdin_iterator
1679{
1680public:
1681 explicit stdin_iterator(FILE * f)
1682 : m_f(f) { get(); get(); }
1683
1684 stdin_iterator & operator++()
1685 { get(); return *this; }
1686
1687 char operator*() const
1688 { return m_c; }
1689
1690 char operator[](int i) const
1691 {
1692 if (i != 1)
1693 fail();
1694 return m_next;
1695 }
1696
1697private:
1698 FILE * m_f;
1699 char m_c, m_next;
1700 void get();
1701 void fail() const;
1702};
1703
1704void stdin_iterator::get()
1705{
1706 m_c = m_next;
1707 int ch = getc(m_f);
1708 m_next = (ch != EOF ? ch : 0);
1709}
1710
1711void stdin_iterator::fail() const
1712{
1713 throw std::runtime_error("stdin_iterator: wrong usage");
1714}
1715
1716
1717// Use above as parser input 'pointer'. Can easily be changed later
1718// to e.g. 'const char *' if above is too slow.
1719typedef stdin_iterator parse_ptr;
1720
1721// Skip whitespace and comments.
1722static parse_ptr skip_white(parse_ptr src, const char * path, int & line)
1723{
1724 for ( ; ; ++src) switch (*src) {
1725 case ' ': case '\t':
1726 continue;
1727
1728 case '\n':
1729 ++line;
1730 continue;
1731
1732 case '/':
1733 switch (src[1]) {
1734 case '/':
1735 // skip '// comment'
1736 ++src; ++src;
1737 while (*src && *src != '\n')
1738 ++src;
1739 if (*src)
1740 ++line;
1741 break;
1742 case '*':
1743 // skip '/* comment */'
1744 ++src; ++src;
1745 for (;;) {
1746 if (!*src) {
1747 pout("%s(%d): Missing '*/'\n", path, line);
1748 return src;
1749 }
1750 char c = *src; ++src;
1751 if (c == '\n')
1752 ++line;
1753 else if (c == '*' && *src == '/')
1754 break;
1755 }
1756 break;
1757 default:
1758 return src;
832b75ed 1759 }
2127e193
GI
1760 continue;
1761
1762 default:
1763 return src;
1764 }
1765}
1766
1767// Info about a token.
1768struct token_info
1769{
1770 char type;
1771 int line;
1772 std::string value;
1773
1774 token_info() : type(0), line(0) { }
1775};
1776
1777// Get next token.
1778static parse_ptr get_token(parse_ptr src, token_info & token, const char * path, int & line)
1779{
1780 src = skip_white(src, path, line);
1781 switch (*src) {
1782 case '{': case '}': case ',':
1783 // Simple token
1784 token.type = *src; token.line = line;
1785 ++src;
1786 break;
1787
1788 case '"':
1789 // String constant
1790 token.type = '"'; token.line = line;
1791 token.value = "";
1792 do {
1793 for (++src; *src != '"'; ++src) {
1794 char c = *src;
1795 if (!c || c == '\n' || (c == '\\' && !src[1])) {
1796 pout("%s(%d): Missing terminating '\"'\n", path, line);
1797 token.type = '?'; token.line = line;
1798 return src;
1799 }
1800 if (c == '\\') {
1801 c = *++src;
1802 switch (c) {
1803 case 'n' : c = '\n'; break;
1804 case '\n': ++line; break;
1805 case '\\': case '"': break;
1806 default:
1807 pout("%s(%d): Unknown escape sequence '\\%c'\n", path, line, c);
1808 token.type = '?'; token.line = line;
1809 continue;
1810 }
1811 }
1812 token.value += c;
1813 }
1814 // Lookahead to detect string constant concatentation
1815 src = skip_white(++src, path, line);
1816 } while (*src == '"');
1817 break;
1818
1819 case 0:
1820 // EOF
1821 token.type = 0; token.line = line;
1822 break;
1823
1824 default:
1825 pout("%s(%d): Syntax error, invalid char '%c'\n", path, line, *src);
1826 token.type = '?'; token.line = line;
1827 while (*src && *src != '\n')
1828 ++src;
1829 break;
1830 }
1831
1832 return src;
1833}
1834
1835// Parse drive database from abstract input pointer.
1836static bool parse_drive_database(parse_ptr src, drive_database & db, const char * path)
1837{
1838 int state = 0, field = 0;
1839 std::string values[5];
1840 bool ok = true;
1841
1842 token_info token; int line = 1;
1843 src = get_token(src, token, path, line);
1844 for (;;) {
1845 // EOF is ok after '}', trailing ',' is also allowed.
1846 if (!token.type && (state == 0 || state == 4))
1847 break;
1848
1849 // Check expected token
1850 const char expect[] = "{\",},";
1851 if (token.type != expect[state]) {
1852 if (token.type != '?')
1853 pout("%s(%d): Syntax error, '%c' expected\n", path, token.line, expect[state]);
1854 ok = false;
1855 // Skip to next entry
1856 while (token.type && token.type != '{')
1857 src = get_token(src, token, path, line);
1858 state = 0;
1859 if (token.type)
1860 continue;
1861 break;
832b75ed 1862 }
2127e193
GI
1863
1864 // Interpret parser state
1865 switch (state) {
1866 case 0: // ... ^{...}
1867 state = 1; field = 0;
1868 break;
1869 case 1: // {... ^"..." ...}
1870 switch (field) {
1871 case 1: case 2:
1872 if (!token.value.empty()) {
1873 regular_expression regex;
1874 if (!regex.compile(token.value.c_str(), REG_EXTENDED)) {
1875 pout("%s(%d): Error in regular expression: %s\n", path, token.line, regex.get_errmsg());
1876 ok = false;
1877 }
1878 }
1879 else if (field == 1) {
1880 pout("%s(%d): Missing regular expression for drive model\n", path, token.line);
1881 ok = false;
1882 }
1883 break;
1884 case 4:
1885 if (!token.value.empty()) {
1886 unsigned char opts[MAX_ATTRIBUTE_NUM] = {0, }; unsigned char fix = 0;
1887 if (!parse_presets(token.value.c_str(), opts, fix)) {
1888 pout("%s(%d): Syntax error in preset option string\n", path, token.line);
1889 ok = false;
1890 }
1891 }
1892 break;
1893 }
1894 values[field] = token.value;
1895 state = (++field < 5 ? 2 : 3);
1896 break;
1897 case 2: // {... "..."^, ...}
1898 state = 1;
1899 break;
1900 case 3: // {...^}, ...
1901 {
1902 drive_settings entry;
1903 entry.modelfamily = values[0].c_str();
1904 entry.modelregexp = values[1].c_str();
1905 entry.firmwareregexp = values[2].c_str();
1906 entry.warningmsg = values[3].c_str();
1907 entry.presets = values[4].c_str();
1908 db.push_back(entry);
1909 }
1910 state = 4;
1911 break;
1912 case 4: // {...}^, ...
1913 state = 0;
1914 break;
1915 default:
1916 pout("Bad state %d\n", state);
1917 return false;
1918 }
1919 src = get_token(src, token, path, line);
832b75ed 1920 }
2127e193
GI
1921 return ok;
1922}
1923
1924// Read drive database from file.
1925bool read_drive_database(const char * path)
1926{
1927 stdio_file f(path, "r");
1928 if (!f) {
1929 pout("%s: cannot open drive database file\n", path);
1930 return false;
1931 }
1932
1933 return parse_drive_database(parse_ptr(f), knowndrives, path);
1934}
1935
1936// Read drive databases from standard places.
1937bool read_default_drive_databases()
1938{
1939#ifndef _WIN32
1940 // Read file for local additions: /{,usr/local/}etc/smart_drivedb.h
1941 static const char db1[] = SMARTMONTOOLS_SYSCONFDIR"/smart_drivedb.h";
1942#else
1943 static const char db1[] = "./smart_drivedb.h";
1944#endif
1945 if (!access(db1, 0)) {
1946 if (!read_drive_database(db1))
1947 return false;
1948 }
1949
1950#ifdef SMARTMONTOOLS_DRIVEDBDIR
1951 // Read file from package: // /usr/{,local/}share/smartmontools/drivedb.h
1952 static const char db2[] = SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h";
1953 if (!access(db2, 0)) {
1954 if (!read_drive_database(db2))
1955 return false;
1956 }
1957 else
1958#endif
1959 {
1960 // Append builtin table.
1961 knowndrives.append(builtin_knowndrives,
1962 sizeof(builtin_knowndrives)/sizeof(builtin_knowndrives[0]));
1963 }
1964
1965 return true;
832b75ed 1966}