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