CHANGELOG for smartmontools
-$Id: CHANGELOG 3296 2011-03-16 22:17:51Z chrfranke $
+$Id: CHANGELOG 3365 2011-06-09 18:47:31Z chrfranke $
The most recent version of this file is:
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/CHANGELOG?view=markup
<DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
+smartmontools 5.41 2011-06-09
+
+ [MS] drivedb.h: revert attribute 190 to default for Samsung SSD controllers,
+ some 470 series SSDs seem to have some temperature information at
+ this location.
+
+ [MS] drivedb.h update:
+ add attribute details for Samsung controllers, centralize entries
+
+ [MS] drivedb.h update:
+ add attribute details for JMicron JMF61x controllers
+
+ [CF] drivedb.h update:
+ - SandForce Driven SSDs: Add OCZ DENEVA
+
+ [CF] os_win32.cpp: Ignore vendor ID "ATA" if returned by
+ IOCTL_STORAGE_QUERY_PROPERTY.
+
+ [CF] Add ATA NCQ commands to error register decoding.
+
+ [CF] Re-enable '--with-initscriptdir=auto' as default.
+ Change search for initddir and systemdsystemunitdir such that
+ default ./configure does never overwrite system files.
+
+ [MS] drivedb.h update:
+ disentangle Transcend SSD versions
+
+ [MS] drivedb.h update:
+ add attribute details for Crucial C300
+
+ [MS] smartd.initd.in:
+ fix for debian, cleanup. Based on patch of CF.
+
+ [AS] --with-initscriptdir default changed to "no" from "auto" to avoid
+ filesystem pollution.
+
+ [MS] drivedb.h cleanup:
+ harmonize family names, add AF information into name
+
+ [MS] drivedb.h update:
+ - OCZ Vertex 3
+ - Seagate Barracuda Green 1TB variant
+
+ [CF] Windows: Avoid '%n' printf format specifier because it is always
+ disabled in recent versions of msvcrt.dll. This fixes truncation
+ of smartd warning email (ticket #174).
+
+ [MS] smartd.initd.in:
+ cleanup, provide targets "reload" and "report" for all platforms
+
+ [CF] drivedb.h update:
+ - JMicron based SSD (JMicron JMF602?): rename from
+ Kingston SSDNow V Series, move Transcend IDE and SATA
+ entries to here.
+
+ [CF] Support ':BYTEORDER' for all attribute print formats.
+
+ [CF] drivedb.h update:
+ - Kingston SSDNow V Series SSDs (ticket #171)
+
+ [CF] Increase size of drive database option parse buffer
+ to allow long '-v N,FORMAT:BYTEORDER,NAME' options.
+
+ [MS] drivedb.h update:
+ - Western Digital Scorpio Blue Advanced Format variants
+
+ [MS] drivedb.h update:
+ correct typo for Cowon iAudio X5
+
+ [MS] drivedb.h USB updates:
+ - Maxtor OneTouch 200GB (unsupported)
+ - LaCie Little Disk
+
+ [AS] FreeBSD: Added native rc.conf style script to the package.
+ Modifications to the configure script to use correct template and
+ path.
+
+ [AS] freebsd_os.cpp:
+ Fix memory leak in the ata detection code (added free())
+ Using bzero in cam code to clear structure (fixing varnish varning)
+
+ [MS] drivedb.h update:
+ Kingston SSDNow S100 Series
+
+ [MS] drivedb.h USB update:
+ - Samsung S1 Portable
+ - LaCie rikiki USB 3.0
+ - Seagate FreeAgent GoFlex USB 3.0
+ - Cowon iAudio X5
+ - Oxford OXU921DS chip (unsupported)
+
+ [CF] Windows: Add debug output of SCSI sense data.
+
+ [CF] Add 'smartd.service' file for systemd.
+ Add configure option '--with-systemdsystemunitdir'.
+ Disable initd script if systemd is used.
+
+ [MS] drivedb.h update:
+ - Western Digital AV-25 family
+
+ [MS] drivedb.h update:
+ JMicron based SSDs: Add
+ Kingston SSDNow V, Kingston SSDNow V+100, TOSHIBA THNS128GG4BBAA,
+ APPLE SSD TS*, ADATA S596 Turbo
+
+ [CF] drivedb.h update:
+ - Intel 510 Series SSDs (ticket #170)
+
+ [CF] smartctl: Don't issue SMART DISABLE command to 3ware controllers
+ when the port number was not specified (ticket #165).
+
+ [CF] Use get_errmsg() from device instead of errno or syserror() for
+ printing error messages.
+
+ [MS] drivedb.h updates:
+ - G.Skill FALCON II SSD (Indilinx)
+ - HP 250GB SATA disk VB0250EAVER
+ - SAMSUNG SpinPoint M5 HM160HC
+ - SAMSUNG SpinPoint MT2 HM100UI
+ - SAMSUNG HM100UX
+ - Hitachi Deskstar 5K3000 Series
+ - Seagate Barracuda Green (Adv. Format)
+ - Seagate Barracuda XT 3TB variant
+ - Western Digital RE4 Serial ATA family
+ - Western Digital Caviar Green WD20EACS
+ - Western Digital Caviar Black family, SATA 3.0 variants
+ - QUANTUM FIREBALLlct20 10
+ - QUANTUM FIREBALLP AS60.0
+
+ [CF] drivedb.h update:
+ - SandForce Driven SSDs: Add more OCZ SF-1200 and SF-1500 based drives
+
+ Thanks to Sudhir Verman from OCZ Technology for providing this info.
+
+ [CF] drivedb.h USB updates:
+ - Seagate Expansion External (0x0bc2:0x3300) (Debian bug 621411)
+ - ASMedia USB 3.0 (0x174c:0x55aa) (unsupported)
+
+ [CF] smartctl.8.in: Clarify '-t vendor,N' (ticket #169).
+ Update Intel info (ticket #168).
+
+ [CF] drivedb.h update:
+ - Intel 320 Series SSDs (ticket #168)
+
+ [CF] smartctl: Always print sector size in '-i' output (ticket #166).
+
+ [CF] os_linux.cpp: Shorten version string.
+
+ [CF] smartctl: Add option '-f brief' to select new attribute output
+ format. This format includes additional attribute flags
+ (ticket #109) and fits in 80 columns (ticket #158).
+ This format is now the default for '-x'.
+
+ [CF] smartd: Log changes of offline data collection status if
+ '-l selftest' is specified.
+
+ [CF] drivedb.h updates:
+ - SandForce Driven SSDs: Add ADATA S599 64GB,
+ OWC Mercury Extreme Pro
+ - Kingston branded X25-V SSDs (ticket #156)
+ - Transcend SATA Solid State Drive: Truncate attribute name
+
+ [CF] drivedb.h USB updates:
+ - LaCie (0x059f:0x1029) (ticket #153)
+ - WD My Book Office Edition (0x1058:0x1101)
+ - JMicron USB 3.0 (0x152d:0x0539)
+
+ [CF] drivedb.h USB update:
+ - Verbatim Pocket Hard Drive (0x18a5:0x0227) (ticket #159)
+
+ [CF] drivedb.h update:
+ - SAMSUNG SpinPoint N3U-3 (USB, 4KiB LLS) (ticket #159)
+
+ [CF] Add support for ATA Long Logical Sectors (LLS) (ticket #159).
+
+ [DG] [SCSI] smartctl: (re-)use capacity formatting in utility.cpp
+
+ [CF] configure.in: Remove '-Wno-format' for MinGW.
+ Recent MinGW versions support MSVCRT printf format strings.
+
+ [CF] Print ATA disk capacity with SI prefix.
+ Add/move capacity formatting to utility.cpp
+
+ [CF] Add error messages if ATA pass-through does not return required
+ ATA output registers (for SMART RETURN STATUS, GET POWER MODE).
+ This prevents misleading 'SMART Status command failed' messages
+ (see ticket #155).
+
+ [CF] Fix WWN support check for older ATA-7 disks.
+
+ [DG] [SCSI] smartctl: add 'Logical Unit id' from the Device
+ Identification VPD page (0x83)
+
+ [DG] [SCSI] smartctl: add 'User Capacity' (disk size) in human
+ readable form
+
+ [CF] smartctl, smartd: Print World Wide Name (WWN) of ATA device.
+
+ [CF] smartctl: Print more specific error message if IDENTIFY DEVICE
+ failed (ticket #61). Add check for empty IDENTIFY data.
+
+ [CF] Windows installer: Add help message box.
+
+ [CF] Windows installer: Request admin rights, select 'All Users'
+ section. This fixes shortcut removal under Vista and later.
+ Add '/SO' option to select components for unattended install.
+ Patch was provided by József Fejes.
+
[CF] Windows: Add update-smart-drivedb.nsi NSIS script to build
drivedb.h update tool.
Smartmontools installation instructions
=======================================
-$Id: INSTALL 3205 2010-11-15 18:32:55Z chrfranke $
+$Id: INSTALL 3356 2011-06-06 18:37:53Z chrfranke $
Please also see the smartmontools home page:
http://smartmontools.sourceforge.net/
./configure --build=$(./config.guess) \
--host=i686-pc-mingw32 \
CC='gcc-3 -mno-cygwin' \
- CXX='g++-3 -mno-cygwin'
+ CXX='g++-3 -mno-cygwin' \
+ CXXFLAGS='-g -O2 -Wall -W -Wno-format'
Cross-compile on Debian Linux with gcc-mingw32:
Contents of smartd executable;
Contents of smartd/smartd.conf man pages;
Directory for rc.d/init.d/smartd init script
---with-initscriptdir ${sysconfdir}/init.d/rc.d Location of init scripts
+--with-initscriptdir auto Location of init scripts
+--with-systemdsystemunitdir auto Location of systemd service files
--with-docdir ${prefix}/share/doc/smartmontools Location of the documentation
--with-exampledir ${docdir}/examplescripts Location of example scripts
--enable-sample --disable-sample Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file
This was changed to make it consistent with the default of the
new --docdir option added in autoconf 2.60.
+The defaults for --with-initscriptdir and --with-systemdsystemunitdir are
+guessed such that the following rules apply:
+- If --prefix=/usr --sysconfdir=/etc is specified, the guessed directories
+ should be the defaults used by the current OS or distribution.
+- If --sysconfdir=/etc is NOT specified, the guessed directories should
+ always be below ${prefix} or below ${sysconfdir}.
+
Here's an example:
If you set --prefix=/home/joe and none of the other four
variables then the different directories that are used would be:
--sbindir /home/joe/sbin
+--docdir /home/joe/share/doc/smartmontools
--mandir /home/joe/share/man
--sysconfdir /home/joe/etc
---with-initscriptdir /home/joe/etc/init.d/rc.d
---with-docdir /home/joe/doc/smartmontools
+--with-exampledir /home/joe/share/doc/smartmontools/examplescripts
+--with-drivedbdir /home/joe/share/smartmontools
+--with-initscriptdir [see below]
+--with-systemdsystemunitdir [see below]
+
+If systemd is present (and pkg-config reports /lib/systemd/system
+as the systemdsystemunitdir):
+
+--with-initscriptdir [disabled]
+--with-systemdsystemunitdir /home/joe/lib/systemd/system
+
+else if /etc/rc.d/init.d exists:
+
+--with-initscriptdir /home/joe/etc/rc.d/init.d
+--with-systemdsystemunitdir [disabled]
+
+else if /etc/init.d exists:
+
+--with-initscriptdir /home/joe/etc/init.d
+--with-systemdsystemunitdir [disabled]
+
+else if /etc/rc.d exists:
+
+--with-initscriptdir /home/joe/etc/rc.d
+--with-systemdsystemunitdir [disabled]
+
+else
+
+--with-initscriptdir [disabled]
+--with-systemdsystemunitdir [disabled]
This is useful for test installs in a harmless subdirectory somewhere.
Here are the differences with and without --enable-sample, assuming
-no other options specified (see above for details)
+that initscript location is set and no other options specified
+(see above for details)
Case 1:
--enable-sample provided
## Process this file with automake to produce Makefile.in
#
-# $Id: Makefile.am 3296 2011-03-16 22:17:51Z chrfranke $
+# $Id: Makefile.am 3338 2011-05-23 08:29:12Z samm2 $
#
@SET_MAKE@
rm -f "$$f"
EXTRA_DIST = \
+ autogen.sh \
smartd.initd.in \
+ smartd.freebsd.initd.in \
smartd.8.in \
smartctl.8.in \
smartd.conf.5.in \
smartd.conf \
- autogen.sh \
+ smartd.service.in \
update-smart-drivedb.in \
os_darwin/SMART.in \
os_darwin/StartupParameters.plist \
$(examples_DATA) \
$(examples_SCRIPTS)
-CLEANFILES = smartd.conf.5 \
- smartd.conf.4 \
- smartd.8 \
- smartd.1m \
- smartd.8.html \
- smartd.8.txt \
- smartctl.8 \
- smartctl.1m \
- smartctl.8.html \
- smartctl.8.txt \
- smartd.conf.5.html \
- smartd.conf.5.txt \
- smartd.initd \
- svnversion.h \
- update-smart-drivedb \
- SMART
+CLEANFILES = \
+ smartd.conf.5 \
+ smartd.conf.4 \
+ smartd.8 \
+ smartd.1m \
+ smartd.8.html \
+ smartd.8.txt \
+ smartctl.8 \
+ smartctl.1m \
+ smartctl.8.html \
+ smartctl.8.txt \
+ smartd.conf.5.html \
+ smartd.conf.5.txt \
+ smartd.initd \
+ smartd.freebsd.initd \
+ smartd.service \
+ svnversion.h \
+ update-smart-drivedb \
+ SMART
# 'make maintainer-clean' also removes files generated by './autogen.sh'
MAINTAINERCLEANFILES = \
else
-initd_DATA = smartd.initd
+initd_DATA = @initdfile@
-smartd.initd: $(srcdir)/smartd.initd.in Makefile
- sed "s|/usr/local/sbin/|$(sbindir)/|g" $(srcdir)/smartd.initd.in > $@
+@initdfile@: $(srcdir)/@initdfile@.in Makefile
+ sed "s|/usr/local/sbin/|$(sbindir)/|g" $(srcdir)/@initdfile@.in > $@
initd_install_name = smartd$(smartd_suffix)
install-initdDATA-generic: $(initd_DATA)
$(mkinstalldirs) $(DESTDIR)$(initddir)
- $(INSTALL_SCRIPT) $(top_builddir)/smartd.initd $(DESTDIR)$(initddir)/smartd$(smartd_suffix)
+ $(INSTALL_SCRIPT) $(top_builddir)/@initdfile@ $(DESTDIR)$(initddir)/smartd$(smartd_suffix)
uninstall-initdDATA-generic:
uninstall-initdDATA: $(initd_DATA_uninstall)
+if INSTALL_SYSTEMDUNIT
+systemdsystemunit_DATA = smartd.service
+endif
+
+smartd.service: smartd.service.in Makefile
+ sed "s|/usr/local/sbin/smartd|$(sbindir)/smartd|g; \
+ s|/usr/local/etc/sysconfig/smartmontools|$(sysconfdir)/sysconfig/smartmontools|g" \
+ $(srcdir)/smartd.service.in > $@
+
if ENABLE_CAPABILITIES
MAN_CAPABILITIES = cat
else
smartmontools NEWS
------------------
-$Id: NEWS 3296 2011-03-16 22:17:51Z chrfranke $
+$Id: NEWS 3365 2011-06-09 18:47:31Z chrfranke $
The most up-to-date version of this file is:
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/NEWS?view=markup
-Date <Not released yet, please try current SVN>
+Date 2011-06-09
Summary: smartmontools release 5.41
-----------------------------------------------------------
- Failed self-tests outdated by a newer successful extended
self-test are no longer reported as errors.
-- smartctl prints physical and logical sector sizes.
+- Support for ATA Long Logical/Physical Sectors (LLS/LPS).
- 'smartctl --scan-open' can create a draft smartd.conf.
-- smartd logs identify information of each ATA device.
+- smartctl prints World Wide Name (WWN) of ATA device.
+- smartctl option '-f brief' to select new attribute output
+ format which includes more flags and fits in 80 columns.
+- smartd logs identify information and WWN of each ATA device.
- smartd logs warning from drive database if present.
+- smartd logs changes of offline data collection status.
- smartd directive '-l scterc,READTIME,WRITETIME'.
- smartd preserves last scheduled selective self-tests span.
+- 'smartd.service' file for systemd.
+- configure option '--with-systemdsystemunitdir'
- configure option '--with-exampledir'.
+- configure searches for init.d or rc.d directory.
- 'make install' does no longer overwrite an existing
smartd.conf file.
- 'update-smart-drivedb' does no longer require GNU sed.
+- Many HDD, SSD and USB additions to drive database.
+- Linux USB autodetection: Enable '-d sat,16' for newer kernels.
- Linux megaraid: Fix segfault on non-data SCSI commands.
- Linux megaraid: Fix pass-through of non-data ATA commands.
- FreeBSD: Use 'fetch' in 'update-smart-drivedb'.
- OpenBSD: Use 'ftp' in 'update-smart-drivedb'.
- OpenBSD: Workaround for shell bug.
- OpenBSD: Fix DEVICESCAN for OpenBSD >= 4.8.
-- Windows: Experimental support for Intel Matrix RAID.
+- Windows: Experimental support for Intel ICHxR RAID.
- Windows: DEVICESCAN includes USB devices.
- Windows: Faster USB ID detection.
- Windows: update-smart-drivedb tool.
+- Windows installer: Option '/SO component,...'.
+- Windows: Fix smartd warning email truncation on Win7.
+- Windows installer: Fix shortcut removal on Vista/Win7.
- Windows: Add missing quotes in smartctl-run.bat and
smartd-run.bat
#include "utility.h"
#include "dev_ata_cmd_set.h" // for parsed_ata_device
-const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3288 2011-03-09 18:40:36Z chrfranke $"
+const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3345 2011-05-25 20:50:02Z chrfranke $"
ATACMDS_H_CVSID;
// Print ATA debug messages?
return;
}
-// Invalidate serial number and adjust checksum in IDENTIFY data
-static void invalidate_serno(ata_identify_device * id){
+// Invalidate serial number and WWN and adjust checksum in IDENTIFY data
+static void invalidate_serno(ata_identify_device * id)
+{
unsigned char sum = 0;
- for (unsigned i = 0; i < sizeof(id->serial_no); i++) {
+ unsigned i;
+ for (i = 0; i < sizeof(id->serial_no); i++) {
sum += id->serial_no[i]; sum -= id->serial_no[i] = 'X';
}
+ unsigned char * b = (unsigned char *)id;
+ for (i = 2*108; i < 2*112; i++) { // words108-111: WWN
+ sum += b[i]; sum -= b[i] = 0x00;
+ }
+
#ifndef __NetBSD__
bool must_swap = !!isbigendian();
if (must_swap)
pout("Unrecognized command %d in smartcommandhandler()\n"
"Please contact " PACKAGE_BUGREPORT "\n", command);
device->set_err(ENOSYS);
- errno = ENOSYS;
return -1;
}
retval = 0;
break;
case CHECK_POWER_MODE:
- data[0] = out.out_regs.sector_count;
- retval = 0;
+ if (out.out_regs.sector_count.is_set()) {
+ data[0] = out.out_regs.sector_count;
+ retval = 0;
+ }
+ else {
+ pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
+ device->set_err(ENOSYS);
+ retval = -1;
+ }
break;
case STATUS_CHECK:
// Cyl low and Cyl high unchanged means "Good SMART status"
if (ata_debugmode)
pout("SMART STATUS RETURN: half unhealthy response sequence, "
"probable SAT/USB truncation\n");
- } else {
+ }
+ else if (!out.out_regs.is_set()) {
+ pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
+ device->set_err(ENOSYS);
+ retval = -1;
+ }
+ else {
// We haven't gotten output that makes sense; print out some debugging info
pout("Error SMART Status command failed\n");
pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
pout("Register values returned from SMART Status command are:\n");
print_regs(" ", out.out_regs);
- errno = EIO;
+ device->set_err(EIO);
retval = -1;
}
break;
}
}
- errno = device->get_errno(); // TODO: Callers should not call syserror()
return retval;
}
-// Get number of sectors from IDENTIFY sector. If the drive doesn't
-// support LBA addressing or has no user writable sectors
-// (eg, CDROM or DVD) then routine returns zero.
-uint64_t get_num_sectors(const ata_identify_device * drive)
+// Get capacity and sector sizes from IDENTIFY data
+void ata_get_size_info(const ata_identify_device * id, ata_size_info & sizes)
{
- unsigned short command_set_2 = drive->command_set_2;
- unsigned short capabilities_0 = drive->words047_079[49-47];
- unsigned short sects_16 = drive->words047_079[60-47];
- unsigned short sects_32 = drive->words047_079[61-47];
- unsigned short lba_16 = drive->words088_255[100-88];
- unsigned short lba_32 = drive->words088_255[101-88];
- unsigned short lba_48 = drive->words088_255[102-88];
- unsigned short lba_64 = drive->words088_255[103-88];
+ sizes.sectors = sizes.capacity = 0;
+ sizes.log_sector_size = sizes.phy_sector_size = 0;
+ sizes.log_sector_offset = 0;
+
+ // Return if no LBA support
+ if (!(id->words047_079[49-47] & 0x0200))
+ return;
+
+ // Determine 28-bit LBA capacity
+ unsigned lba28 = (unsigned)id->words047_079[61-47] << 16
+ | (unsigned)id->words047_079[60-47] ;
+
+ // Determine 48-bit LBA capacity if supported
+ uint64_t lba48 = 0;
+ if ((id->command_set_2 & 0xc400) == 0x4400)
+ lba48 = (uint64_t)id->words088_255[103-88] << 48
+ | (uint64_t)id->words088_255[102-88] << 32
+ | (uint64_t)id->words088_255[101-88] << 16
+ | (uint64_t)id->words088_255[100-88] ;
+
+ // Return if capacity unknown (ATAPI CD/DVD)
+ if (!(lba28 || lba48))
+ return;
- // LBA support?
- if (!(capabilities_0 & 0x0200))
- return 0; // No
+ // Determine sector sizes
+ sizes.log_sector_size = sizes.phy_sector_size = 512;
- // if drive supports LBA addressing, determine 32-bit LBA capacity
- uint64_t lba32 = (unsigned int)sects_32 << 16 |
- (unsigned int)sects_16 << 0 ;
+ unsigned short word106 = id->words088_255[106-88];
+ if ((word106 & 0xc000) == 0x4000) {
+ // Long Logical/Physical Sectors (LLS/LPS) ?
+ if (word106 & 0x1000)
+ // Logical sector size is specified in 16-bit words
+ sizes.log_sector_size = sizes.phy_sector_size =
+ ((id->words088_255[118-88] << 16) | id->words088_255[117-88]) << 1;
- uint64_t lba64 = 0;
- // if drive supports 48-bit addressing, determine THAT capacity
- if ((command_set_2 & 0xc000) == 0x4000 && (command_set_2 & 0x0400))
- lba64 = (uint64_t)lba_64 << 48 |
- (uint64_t)lba_48 << 32 |
- (uint64_t)lba_32 << 16 |
- (uint64_t)lba_16 << 0 ;
+ if (word106 & 0x2000)
+ // Physical sector size is multiple of logical sector size
+ sizes.phy_sector_size <<= (word106 & 0x0f);
- // return the larger of the two possible capacities
- return (lba32 > lba64 ? lba32 : lba64);
+ unsigned short word209 = id->words088_255[209-88];
+ if ((word209 & 0xc000) == 0x4000)
+ sizes.log_sector_offset = (word209 & 0x3fff) * sizes.log_sector_size;
+ }
+
+ // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
+ if (lba48 >= lba28 || (lba48 && sizes.log_sector_size > 512))
+ sizes.sectors = lba48;
+ else
+ sizes.sectors = lba28;
+
+ sizes.capacity = sizes.sectors * sizes.log_sector_size;
}
// This function computes the checksum of a single disk sector (512
return (int)result;
}
-
-
-
// Reads current Device Identity info (512 bytes) into buf. Returns 0
// if all OK. Returns -1 if no ATA Device identity can be
// established. Returns >0 if Device is ATA Packet Device (not SMART
return i;
}
+// Get World Wide Name (WWN) fields.
+// Return NAA field or -1 if WWN is unsupported.
+// Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
+// (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
+int ata_get_wwn(const ata_identify_device * id, unsigned & oui, uint64_t & unique_id)
+{
+ // Don't use word 84 to be compatible with some older ATA-7 disks
+ unsigned short word087 = id->csf_default;
+ if ((word087 & 0xc100) != 0x4100)
+ return -1; // word not valid or WWN support bit 8 not set
+
+ unsigned short word108 = id->words088_255[108-88];
+ unsigned short word109 = id->words088_255[109-88];
+ unsigned short word110 = id->words088_255[110-88];
+ unsigned short word111 = id->words088_255[111-88];
+
+ oui = ((word108 & 0x0fff) << 12) | (word109 >> 4);
+ unique_id = ((uint64_t)(word109 & 0xf) << 32)
+ | (unsigned)((word110 << 16) | word111);
+ return (word108 >> 12);
+}
+
// returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
int ataSmartSupport(const ata_identify_device * drive)
{
int ataReadSmartValues(ata_device * device, struct ata_smart_values *data){
if (smartcommandhandler(device, READ_VALUES, 0, (char *)data)){
- syserror("Error SMART Values Read failed");
+ pout("Error SMART Values Read failed: %s\n", device->get_errmsg());
return -1;
}
// get data from device
if (smartcommandhandler(device, READ_LOG, 0x06, (char *)data)){
- syserror("Error SMART Error Self-Test Log Read failed");
+ pout("Error SMART Error Self-Test Log Read failed: %s\n", device->get_errmsg());
return -1;
}
// get data from device
if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){
- syserror("Error SMART Read Selective Self-Test Log failed");
+ pout("Error SMART Read Selective Self-Test Log failed: %s\n", device->get_errmsg());
return -1;
}
// write new selective self-test log
if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){
- syserror("Error Write Selective Self-Test Log failed");
+ pout("Error Write Selective Self-Test Log failed: %s\n", device->get_errmsg());
return -3;
}
// get data from device
if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){
- syserror("Error SMART Error Log Read failed");
+ pout("Error SMART Error Log Read failed: %s\n", device->get_errmsg());
return -1;
}
// get data from device
if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
- syserror("Error SMART Thresholds Read failed");
+ pout("Error SMART Thresholds Read failed: %s\n", device->get_errmsg());
return -1;
}
int ataEnableSmart (ata_device * device ){
if (smartcommandhandler(device, ENABLE, 0, NULL)){
- syserror("Error SMART Enable failed");
+ pout("Error SMART Enable failed: %s\n", device->get_errmsg());
return -1;
}
return 0;
int ataDisableSmart (ata_device * device ){
if (smartcommandhandler(device, DISABLE, 0, NULL)){
- syserror("Error SMART Disable failed");
+ pout("Error SMART Disable failed: %s\n", device->get_errmsg());
return -1;
}
return 0;
int ataEnableAutoSave(ata_device * device){
if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
- syserror("Error SMART Enable Auto-save failed");
+ pout("Error SMART Enable Auto-save failed: %s\n", device->get_errmsg());
return -1;
}
return 0;
int ataDisableAutoSave(ata_device * device){
if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
- syserror("Error SMART Disable Auto-save failed");
+ pout("Error SMART Disable Auto-save failed: %s\n", device->get_errmsg());
return -1;
}
return 0;
/* timer hard coded to 4 hours */
if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
- syserror("Error SMART Enable Automatic Offline failed");
+ pout("Error SMART Enable Automatic Offline failed: %s\n", device->get_errmsg());
return -1;
}
return 0;
int ataDisableAutoOffline (ata_device * device){
if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
- syserror("Error SMART Disable Automatic Offline failed");
+ pout("Error SMART Disable Automatic Offline failed: %s\n", device->get_errmsg());
return -1;
}
return 0;
const ata_smart_values * sv, uint64_t num_sectors)
{
char cmdmsg[128]; const char *type, *captive;
- int errornum, cap, retval, select=0;
+ int cap, retval, select=0;
// Boolean, if set, says test is captive
cap=testtype & CAPTIVE_MASK;
}
// Now send the command to test
- errornum=smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL);
-
- if (errornum && !(cap && errno==EIO)){
- char errormsg[128];
- sprintf(errormsg,"Command \"%s\" failed",cmdmsg);
- syserror(errormsg);
- pout("\n");
- return -1;
+ if (smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL)) {
+ if (!(cap && device->get_errno() == EIO)) {
+ pout("Command \"%s\" failed: %s\n", cmdmsg, device->get_errmsg());
+ return -1;
+ }
}
// Since the command succeeded, tell user
// Get 48 bit or 64 bit raw value
uint64_t rawvalue = ata_get_attr_raw_value(attr, defs);
- // Get 16 bit words
- // TODO: rebuild raw[6] from rawvalue
- const unsigned char * raw = attr.raw;
+ // Split into bytes and words
+ unsigned char raw[6];
+ raw[0] = (unsigned char) rawvalue;
+ raw[1] = (unsigned char)(rawvalue >> 8);
+ raw[2] = (unsigned char)(rawvalue >> 16);
+ raw[3] = (unsigned char)(rawvalue >> 24);
+ raw[4] = (unsigned char)(rawvalue >> 32);
+ raw[5] = (unsigned char)(rawvalue >> 40);
unsigned word[3];
word[0] = raw[0] | (raw[1] << 8);
word[1] = raw[2] | (raw[3] << 8);
// read SCT status via SMART log 0xe0
memset(sts, 0, sizeof(*sts));
if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){
- syserror("Error Read SCT Status failed");
+ pout("Error Read SCT Status failed: %s\n", device->get_errmsg());
return -1;
}
// write command via SMART log page 0xe0
if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
- syserror("Error Write SCT Data Table command failed");
+ pout("Error Write SCT Data Table command failed: %s\n", device->get_errmsg());
return -1;
}
// read SCT data via SMART log page 0xe1
memset(tmh, 0, sizeof(*tmh));
if (smartcommandhandler(device, READ_LOG, 0xe1, (char *)tmh)){
- syserror("Error Read SCT Data Table failed");
+ pout("Error Read SCT Data Table failed: %s\n", device->get_errmsg());
return -1;
}
// write command via SMART log page 0xe0
if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
- syserror("Error Write SCT Feature Control Command failed");
+ pout("Error Write SCT Feature Control Command failed: %s\n", device->get_errmsg());
return -1;
}
*
* Home page of code is: http://smartmontools.sourceforge.net
*
- * Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
#ifndef ATACMDS_H_
#define ATACMDS_H_
-#define ATACMDS_H_CVSID "$Id: atacmds.h 3288 2011-03-09 18:40:36Z chrfranke $"
+#define ATACMDS_H_CVSID "$Id: atacmds.h 3316 2011-04-19 19:34:57Z chrfranke $"
#include "dev_interface.h" // ata_device
// 5: Selfpereserving bit
#define ATTRIBUTE_FLAGS_SELFPRESERVING(x) (x & 0x20)
+// 6-15: Reserved for future use
+#define ATTRIBUTE_FLAGS_OTHER(x) ((x) & 0xffc0)
-// Last ten bits are reserved for future use
/* ata_smart_values is format of the read drive Attribute command */
/* see Table 34 of T13/1321D Rev 1 spec (Device SMART data structure) for *some* info */
// supports. Returns -1 if Version command is not supported
int ataVersionInfo(const char ** description, const ata_identify_device * drive, unsigned short * minor);
+// Get World Wide Name (WWN) fields.
+// Return NAA field or -1 if WWN is unsupported.
+int ata_get_wwn(const ata_identify_device * id, unsigned & oui, uint64_t & unique_id);
+
// If SMART supported, this is guaranteed to return 1 if SMART is enabled, else 0.
int ataDoesSmartWork(ata_device * device);
int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries,
unsigned char fix_firmwarebug);
-// Get number of sectors from IDENTIFY sector.
-uint64_t get_num_sectors(const ata_identify_device * drive);
+// Get capacity and sector sizes from IDENTIFY data
+struct ata_size_info
+{
+ uint64_t sectors;
+ uint64_t capacity;
+ unsigned log_sector_size;
+ unsigned phy_sector_size;
+ unsigned log_sector_offset;
+};
+
+void ata_get_size_info(const ata_identify_device * id, ata_size_info & sizes);
// Convenience function for formatting strings from ata_identify_device.
void ata_format_id_string(char * out, const unsigned char * in, int n);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif // #ifdef HAVE_LOCALE_H
#include "int64.h"
#include "atacmdnames.h"
#include "utility.h"
#include "knowndrives.h"
-const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3288 2011-03-09 18:40:36Z chrfranke $"
+const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3357 2011-06-06 18:56:55Z chrfranke $"
ATAPRINT_H_CVSID;
print_lba=1;
print_sector=SC;
break;
- case 0x25: /* READ DMA EXT */
+ case 0x25: // READ DMA EXT
case 0x26: // READ DMA QUEUED EXT
case 0xC7: // READ DMA QUEUED
- case 0xC8: /* READ DMA */
- case 0xC9:
+ case 0xC8: // READ DMA (with retries)
+ case 0xC9: // READ DMA (without retries, obsolete since ATA-5)
+ case 0x60: // READ FPDMA QUEUED (NCQ)
error_flag[7] = icrc;
error_flag[6] = unc;
error_flag[5] = mc;
break;
}
break;
- case 0xCA: /* WRITE DMA */
- case 0xCB:
+ case 0xCA: // WRITE DMA (with retries)
+ case 0xCB: // WRITE DMA (without retries, obsolete since ATA-5)
case 0x35: // WRITE DMA EXT
case 0x3D: // WRITE DMA FUA EXT
case 0xCC: // WRITE DMA QUEUED
case 0x36: // WRITE DMA QUEUED EXT
case 0x3E: // WRITE DMA QUEUED FUA EXT
+ case 0x61: // WRITE FPDMA QUEUED (NCQ)
error_flag[7] = icrc;
error_flag[6] = wp;
error_flag[5] = mc;
(const ata_smart_errorlog_error_struct *)0, &data->error);
}
-
-// This returns the capacity of a disk drive and also prints this into
-// a string, using comma separators to make it easier to read. If the
-// drive doesn't support LBA addressing or has no user writable
-// sectors (eg, CDROM or DVD) then routine returns zero.
-static uint64_t determine_capacity(const ata_identify_device * drive, char * pstring)
-{
- // get correct character to use as thousands separator
- const char *separator = ",";
-#ifdef HAVE_LOCALE_H
- struct lconv *currentlocale=NULL;
- setlocale (LC_ALL, "");
- currentlocale=localeconv();
- if (*(currentlocale->thousands_sep))
- separator=(char *)currentlocale->thousands_sep;
-#endif // #ifdef HAVE_LOCALE_H
-
- // get #sectors and turn into bytes
- uint64_t capacity = get_num_sectors(drive) * 512;
- uint64_t retval = capacity;
-
- // print with locale-specific separators (default is comma)
- int started=0, k=1000000000;
- uint64_t power_of_ten = k;
- power_of_ten *= k;
-
- for (k=0; k<7; k++) {
- uint64_t threedigits = capacity/power_of_ten;
- capacity -= threedigits*power_of_ten;
- if (started)
- // we have already printed some digits
- pstring += sprintf(pstring, "%s%03"PRIu64, separator, threedigits);
- else if (threedigits || k==6) {
- // these are the first digits that we are printing
- pstring += sprintf(pstring, "%"PRIu64, threedigits);
- started = 1;
- }
- if (k!=6)
- power_of_ten /= 1000;
- }
-
- return retval;
-}
-
-// Get sector sizes and offset.
-// Return physical sector size if valid else return 0.
-static unsigned determine_sector_sizes(const ata_identify_device * id,
- unsigned & log_sector_size, unsigned & log_sector_offset)
-{
- unsigned short word106 = id->words088_255[106-88];
- if ((word106 & 0xc000) != 0x4000)
- return 0; // word not valid
-
- log_sector_size = 512;
- if (word106 & 0x1000)
- // logical sector size is specified in 16-bit words
- log_sector_size = ((id->words088_255[118-88] << 16) | id->words088_255[117-88]) << 1;
-
- unsigned phy_sector_size = log_sector_size;
- if (word106 & 0x2000)
- // physical sector size is multiple of logical sector size
- phy_sector_size <<= (word106 & 0x0f);
-
- unsigned short word209 = id->words088_255[209-88];
- log_sector_offset = 0;
- if ((word209 & 0xc000) == 0x4000)
- log_sector_offset = (word209 & 0x3fff) * log_sector_size;
-
- return phy_sector_size;
-}
-
static void print_drive_info(const ata_identify_device * drive,
+ const ata_size_info & sizes,
const drive_settings * dbentry)
{
// format drive information (with byte swapping as needed)
pout("Model Family: %s\n", dbentry->modelfamily);
pout("Device Model: %s\n", infofound(model));
- if (!dont_print_serial_number)
+ if (!dont_print_serial_number) {
pout("Serial Number: %s\n", infofound(serial));
+
+ unsigned oui = 0; uint64_t unique_id = 0;
+ int naa = ata_get_wwn(drive, oui, unique_id);
+ if (naa >= 0)
+ pout("LU WWN Device Id: %x %06x %09"PRIx64"\n", naa, oui, unique_id);
+ }
pout("Firmware Version: %s\n", infofound(firmware));
- char capacity[64];
- if (determine_capacity(drive, capacity))
- pout("User Capacity: %s bytes\n", capacity);
-
- // Print sector sizes.
- // Don't print if drive reports the default values.
- // Some from 4KiB sector drives report 512 bytes in IDENTIFY word 106
- // (e.g. Samsung HD204UI).
- unsigned log_sector_size = 0, log_sector_offset = 0;
- unsigned phy_sector_size = determine_sector_sizes(drive, log_sector_size,
- log_sector_offset);
- if (phy_sector_size && !(phy_sector_size == 512 && log_sector_size == 512)) {
- pout("Sector Sizes: %u bytes physical, %u bytes logical",
- phy_sector_size, log_sector_size);
- if (log_sector_offset)
- pout(" (offset %u bytes)", log_sector_offset);
- pout("\n");
+ if (sizes.capacity) {
+ // Print capacity
+ char num[64], cap[32];
+ pout("User Capacity: %s bytes [%s]\n",
+ format_with_thousands_sep(num, sizeof(num), sizes.capacity),
+ format_capacity(cap, sizeof(cap), sizes.capacity));
+
+ // Print sector sizes.
+ if (sizes.phy_sector_size == sizes.log_sector_size)
+ pout("Sector Size: %u bytes logical/physical\n", sizes.log_sector_size);
+ else {
+ pout("Sector Sizes: %u bytes logical, %u bytes physical",
+ sizes.log_sector_size, sizes.phy_sector_size);
+ if (sizes.log_sector_offset)
+ pout(" (offset %u bytes)", sizes.log_sector_offset);
+ pout("\n");
+ }
}
// See if drive is recognized
static void PrintSmartAttribWithThres(const ata_smart_values * data,
const ata_smart_thresholds_pvt * thresholds,
const ata_vendor_attr_defs & defs,
- int onlyfailed)
+ int onlyfailed, unsigned char format)
{
bool needheader = true;
pout("SMART Attributes Data Structure revision number: %d\n",(int)data->revnumber);
pout("Vendor Specific SMART Attributes with Thresholds:\n");
}
- pout("ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE\n");
+ if (format == 0)
+ pout("ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE\n");
+ else
+ pout("ID# ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE\n");
needheader = false;
}
// Print line for each valid attribute
std::string attrname = ata_get_smart_attr_name(attr.id, defs);
- pout("%3d %-24s0x%04x %-3s %-3s %-3s %-10s%-9s%-12s%s\n",
- attr.id, attrname.c_str(), attr.flags,
- valstr.c_str(), worstr.c_str(), threstr.c_str(),
- (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags)? "Pre-fail" : "Old_age"),
- (ATTRIBUTE_FLAGS_ONLINE(attr.flags)? "Always" : "Offline"),
- (state == ATTRSTATE_FAILED_NOW ? "FAILING_NOW" :
- state == ATTRSTATE_FAILED_PAST ? "In_the_past" :
- " -" ),
- ata_format_attr_raw_value(attr, defs).c_str());
- }
- if (!needheader) pout("\n");
+ std::string rawstr = ata_format_attr_raw_value(attr, defs);
+
+ if (format == 0)
+ pout("%3d %-24s0x%04x %-3s %-3s %-3s %-10s%-9s%-12s%s\n",
+ attr.id, attrname.c_str(), attr.flags,
+ valstr.c_str(), worstr.c_str(), threstr.c_str(),
+ (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) ? "Pre-fail" : "Old_age"),
+ (ATTRIBUTE_FLAGS_ONLINE(attr.flags) ? "Always" : "Offline"),
+ (state == ATTRSTATE_FAILED_NOW ? "FAILING_NOW" :
+ state == ATTRSTATE_FAILED_PAST ? "In_the_past"
+ : " -" ) ,
+ rawstr.c_str());
+ else
+ pout("%3d %-24s%c%c%c%c%c%c%c %-3s %-3s %-3s %-5s%s\n",
+ attr.id, attrname.c_str(),
+ (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) ? 'P' : '-'),
+ (ATTRIBUTE_FLAGS_ONLINE(attr.flags) ? 'O' : '-'),
+ (ATTRIBUTE_FLAGS_PERFORMANCE(attr.flags) ? 'S' : '-'),
+ (ATTRIBUTE_FLAGS_ERRORRATE(attr.flags) ? 'R' : '-'),
+ (ATTRIBUTE_FLAGS_EVENTCOUNT(attr.flags) ? 'C' : '-'),
+ (ATTRIBUTE_FLAGS_SELFPRESERVING(attr.flags) ? 'K' : '-'),
+ (ATTRIBUTE_FLAGS_OTHER(attr.flags) ? '+' : ' '),
+ valstr.c_str(), worstr.c_str(), threstr.c_str(),
+ (state == ATTRSTATE_FAILED_NOW ? "NOW" :
+ state == ATTRSTATE_FAILED_PAST ? "Past"
+ : "-" ),
+ rawstr.c_str());
+
+ }
+
+ if (!needheader) {
+ if (!onlyfailed && format == 1)
+ pout("%28s||||||_ K auto-keep\n"
+ "%28s|||||__ C event count\n"
+ "%28s||||___ R error rate\n"
+ "%28s|||____ S speed/performance\n"
+ "%28s||_____ O updated online\n"
+ "%28s|______ P prefailure warning\n",
+ "", "", "", "", "", "");
+ pout("\n");
+ }
}
// Print SMART related SCT capabilities
int powermode = ataCheckPowerMode(device);
switch (powermode) {
case -1:
- if (errno == ENOSYS) {
+ if (device->get_errno() == ENOSYS) {
pout("CHECK POWER MODE not implemented, ignoring -n option\n"); break;
}
powername = "SLEEP"; powerlimit = 2;
// Start by getting Drive ID information. We need this, to know if SMART is supported.
int returnval = 0;
ata_identify_device drive; memset(&drive, 0, sizeof(drive));
+ device->clear_err();
int retid = ata_read_identity(device, &drive, options.fix_swapped_id);
if (retid < 0) {
- pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n");
+ pout("Smartctl: Device Read Identity Failed: %s\n\n",
+ (device->get_errno() ? device->get_errmsg() : "Unknown error"));
+ failuretest(MANDATORY_CMD, returnval|=FAILID);
+ }
+ else if (!nonempty(&drive, sizeof(drive))) {
+ pout("Smartctl: Device Read Identity Failed: empty IDENTIFY data\n\n");
failuretest(MANDATORY_CMD, returnval|=FAILID);
}
dbentry = lookup_drive_apply_presets(&drive, attribute_defs,
fix_firmwarebug);
+ // Get capacity and sector sizes
+ ata_size_info sizes;
+ ata_get_size_info(&drive, sizes);
+
// Print most drive identity information if requested
if (options.drive_info) {
pout("=== START OF INFORMATION SECTION ===\n");
- print_drive_info(&drive, dbentry);
+ print_drive_info(&drive, sizes, dbentry);
}
// Check and print SMART support and state
else {
print_on();
pout("Please note the following marginal Attributes:\n");
- PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 2);
+ PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 2, options.output_format);
}
returnval|=FAILAGE;
}
else {
print_on();
pout("Failed Attributes:\n");
- PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 1);
+ PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 1, options.output_format);
}
}
else
else {
print_on();
pout("Failed Attributes:\n");
- PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 1);
+ PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 1, options.output_format);
}
}
else {
else {
print_on();
pout("Please note the following marginal Attributes:\n");
- PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 2);
+ PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 2, options.output_format);
}
returnval|=FAILAGE;
}
if (smart_val_ok && options.smart_vendor_attrib) {
print_on();
PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs,
- (printing_is_switchable ? 2 : 0));
+ (printing_is_switchable ? 2 : 0), options.output_format);
print_off();
}
// Now do the test. Note ataSmartTest prints its own error/success
// messages
if (ataSmartTest(device, options.smart_selftest_type, options.smart_selective_args,
- &smartval, get_num_sectors(&drive) ))
+ &smartval, sizes.sectors ))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
else {
// Tell user how long test will take to complete. This is tricky
#ifndef ATAPRINT_H_
#define ATAPRINT_H_
-#define ATAPRINT_H_CVSID "$Id: ataprint.h 3196 2010-10-28 21:31:49Z chrfranke $\n"
+#define ATAPRINT_H_CVSID "$Id: ataprint.h 3316 2011-04-19 19:34:57Z chrfranke $\n"
#include <vector>
unsigned sct_temp_int;
bool sct_temp_int_pers;
+ unsigned char output_format; // 0=old, 1=brief
unsigned char fix_firmwarebug; // FIX_*, see atacmds.h
bool fix_swapped_id; // Fix swapped ID strings returned by some buggy drivers
smart_auto_save_disable(false), smart_auto_save_enable(false),
smart_selftest_type(-1),
sct_temp_int(0), sct_temp_int_pers(false),
+ output_format(0),
fix_firmwarebug(FIX_NOTSPECIFIED),
fix_swapped_id(false),
ignore_presets(false),
#
-# $Id: configure.in 3296 2011-03-16 22:17:51Z chrfranke $
+# $Id: configure.in 3365 2011-06-09 18:47:31Z chrfranke $
#
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(smartctl.cpp)
smartmontools_configure_date=`date -u +'%Y-%m-%d %T %Z'`
-smartmontools_cvs_tag=`echo '$Id: configure.in 3296 2011-03-16 22:17:51Z chrfranke $'`
-smartmontools_release_date=2010-10-16
-smartmontools_release_time="16:34:38 UTC"
+smartmontools_cvs_tag=`echo '$Id: configure.in 3365 2011-06-09 18:47:31Z chrfranke $'`
+smartmontools_release_date=2011-06-09
+smartmontools_release_time="18:46:32 UTC"
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args", [smartmontools Configure Arguments])
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_DATE, "$smartmontools_configure_date", [smartmontools Configure Date])
AC_PROG_CXX
AM_PROG_AS
AC_PROG_INSTALL
+PKG_PROG_PKG_CONFIG
AC_ARG_VAR(WINDMC, [Windows message compiler command])
AC_ARG_VAR(WINDRES, [Windows resource compiler command])
AC_SUBST(LDFLAGS)
AC_SUBST(ASFLAGS)
+AC_ARG_WITH(systemdsystemunitdir,
+ [AS_HELP_STRING([--with-systemdsystemunitdir@<:@=DIR|auto|yes|no@:>@], [Location of systemd service files [auto]])],
+ [], [with_systemdsystemunitdir=auto])
+
+systemdsystemunitdir=
+case "$with_systemdsystemunitdir" in
+ auto|yes)
+ test -n "$PKG_CONFIG" && systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd`
+ case "$with_systemdsystemunitdir:$sysconfdir:$systemdsystemunitdir" in
+ yes:*:) AC_MSG_ERROR([Location of systemd service files not found]) ;;
+ yes:*:*|auto:*:|auto:/etc:*) ;;
+ *) systemdsystemunitdir='${prefix}'$systemdsystemunitdir ;;
+ esac ;;
+ no) ;;
+ *) systemdsystemunitdir="$with_systemdsystemunitdir" ;;
+esac
+AC_SUBST(systemdsystemunitdir)
+AM_CONDITIONAL(INSTALL_SYSTEMDUNIT, [test -n "$systemdsystemunitdir"])
+
AC_ARG_WITH(initscriptdir,
- [AC_HELP_STRING([--with-initscriptdir=DIR],[Location of init scripts [SYSCONFDIR/rc.d/init.d]])],
- [initddir="$withval"],[initddir='${sysconfdir}/rc.d/init.d'])
+ [AC_HELP_STRING([--with-initscriptdir@<:@=DIR|auto|yes|no@:>@], [Location of init scripts [auto]])],
+ [], [with_initscriptdir=auto])
+
+AC_MSG_CHECKING(which init (rc) directory to use)
+initddir=""
+for dir in rc.d/init.d init.d rc.d; do
+ if test -d /etc/$dir; then
+ initddir='${sysconfdir}'/$dir
+ break
+ fi
+done
+AC_MSG_RESULT([${initddir:-not found}])
+
+case "$with_initscriptdir" in
+ auto) test -n "$systemdsystemunitdir" && initddir= ;;
+ yes)
+ if test -z "$initddir"; then
+ AC_MSG_ERROR([Location of init scripts not found])
+ fi ;;
+ no) initddir= ;;
+ *) initddir="$with_initscriptdir" ;;
+esac
+
AC_SUBST(initddir)
-AM_CONDITIONAL(INSTALL_INITSCRIPT, [test "$with_initscriptdir" != "no"])
+AM_CONDITIONAL(INSTALL_INITSCRIPT, [test -n "$initddir"])
+
+# use different init script templates for different OS
+case "${host}" in
+ *-*-freebsd*)
+ initdfile="smartd.freebsd.initd"
+ ;;
+ *)
+ initdfile="smartd.initd"
+ ;;
+esac
+AC_SUBST(initdfile)
AC_ARG_WITH(docdir,
[AC_HELP_STRING([--with-docdir=DIR],[Location of documentation [DATADIR/doc/smartmontools]])],
AC_ARG_WITH(libcap-ng,
[AC_HELP_STRING([--with-libcap-ng@<:@=auto|yes|no@:>@],[Add Libcap-ng support to smartd [auto]])],
- [with_libcap_ng="$withval"],
- [with_libcap_ng=auto])
+ [], [with_libcap_ng=auto])
use_libcap_ng=no
if test "$with_libcap_ng" != "no"; then
if test -z "`echo "$CXXFLAGS " | grep "\-W " 2> /dev/null`" ; then
CXXFLAGS="$CXXFLAGS -W"
fi
- case "${host}" in
- *-*-mingw*)
- # MinGW uses MSVCRT.DLL which uses printf format "%I64d" and not "%lld" for int64_t
- CXXFLAGS="$CXXFLAGS -Wno-format";;
- esac
else
dnl We are NOT using gcc, so enable host-specific compiler flags
fi
echo "local drive database: `eval eval eval echo $sysconfdir`/smart_drivedb.h" >&AS_MESSAGE_FD
echo "smartd config file: `eval eval eval echo $sysconfdir`/smartd.conf${smartd_suffix}" >&AS_MESSAGE_FD
- echo "smartd initd script: `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD
+ if test -n "$initddir"; then
+ echo "smartd initd script: `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD
+ elif test -z "$systemdsystemunitdir"; then
+ echo "smartd initd script: [[disabled]]" >&AS_MESSAGE_FD
+ fi
+ if test -n "$systemdsystemunitdir"; then
+ echo "smartd systemd file: `eval eval eval echo $systemdsystemunitdir`/smartd.service" >&AS_MESSAGE_FD
+ fi
if test -n "$savestates"; then
echo "smartd save files: `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
else
/*
const drive_settings builtin_knowndrives[] = {
*/
- { "$Id: drivedb.h 3290 2011-03-09 20:40:36Z chrfranke $",
+ { "$Id: drivedb.h 3364 2011-06-08 21:26:23Z manfred99 $",
"-", "-",
"This is a dummy entry to hold the SVN-Id of drivedb.h",
""
"APPLE SSD SM128",
"", "", ""
},
- { "Apple SSD TS*", // Toshiba?
- // tested with APPLE SSD TS064C/CJAA0201
- "APPLE SSD TS.*",
- "", "",
- "-v 10,raw48,Unknown_Attribute "
- "-v 240,raw48,Unknown_Attribute"
- },
{ "Asus-Phison SSD",
"ASUS-PHISON SSD",
"", "", ""
},
- { "Crucial RealSSD C300 Series", // tested with C300-CTFDDAC128MAG/0002
+ { "Crucial RealSSD C300", // Marvell 88SS9174 BJP2, tested with C300-CTFDDAC128MAG/0002
"C300-CTFDDA[AC](064|128|256)MAG",
"", "",
- "-v 189,raw48,Unknown_Attribute "
- "-v 202,raw48,Unknown_Attribute "
- "-v 206,raw48,Unknown_Attribute"
+ "-v 170,raw48,Grown_Failing_Block_Ct "
+ "-v 171,raw48,Program_Fail_Count "
+ "-v 172,raw48,Erase_Fail_Count "
+ "-v 173,raw48,Wear_Levelling_Count "
+ "-v 174,raw48,Unexpect_Power_Loss_Ct "
+ "-v 181,raw48,Non4k_Aligned_Access "
+ "-v 183,raw48,SATA_Iface_Downshift "
+ "-v 189,raw48,Factory_Bad_Block_Ct "
+ "-v 202,raw48,Perc_Rated_Life_Used "
+ "-v 206,raw48,Write_Error_Rate"
},
{ "SandForce Driven SSDs",
"SandForce 1st Ed\\.|" // Demo Drive, tested with firmware 320A13F0
- "ADATA SSD S599 ...GB|" // tested with ADATA SSD S599 256GB/3.1.0
+ "ADATA SSD S599 .?..GB|" // tested with ADATA SSD S599 256GB/3.1.0, 64GB/3.4.6
"Corsair CSSD-F(40|60|80|120|160|240)GBP?2.*|" // Corsair Force, tested with
// Corsair CSSD-F40GB2/1.1
"FTM(06|12|24|48)CT25H|" // Supertalent TeraDrive CT, tested with
// FTM24CT25H/STTMP2P1
- "OCZ[ -](AGILITY2|VERTEX2(-PRO)?|VERTEX-LE)( .*)?|" // tested with
- // OCZ-VERTEX2/1.11, OCZ-VERTEX2 3.5/1.11
+ "OCZ[ -](AGILITY2([ -]EX)?|COLOSSUS2|ONYX2|VERTEX2|VERTEX-LE)( [123]\\..*)?|" // SF-1200,
+ // tested with OCZ-VERTEX2/1.11, OCZ-VERTEX2 3.5/1.11
+ "OCZ[ -](VELO|VERTEX2[ -](EX|PRO))( [123]\\..*)?|" // SF-1500, tested with
// OCZ VERTEX2-PRO/1.10 (Bogus thresholds for attribute 232 and 235)
+ "OCZ-VERTEX3|" // SF-2200, tested with OCZ-VERTEX3/2.02
+ "(APOC|DENC|DENEVA|FTNC|GFGC|MANG|MMOC|NIMC|TMSC).*|" // other OCZ SF-1200,
+ // tested with DENCSTE251M11-0120/1.33, DENEVA PCI-E/1.33
+ "(DENR|DRSAK|EC188|NIMR|PSIR|TRSAK).*|" // other OCZ SF-1500
+ "OWC Mercury Extreme Pro SSD|" // tested with firmware 360A13F0
"UGB(88P|99S)GC...H[BF].", // Unigen, tested with
// UGB88PGC100HF2/MP Rev2, UGB99SGC100HB3/RC Rev3
"", "",
"OCZ[ -](AGILITY|ONYX|VERTEX( 1199|-TURBO)?)|" // tested with
// OCZ-ONYX/1.6, OCZ-VERTEX 1199/00.P97, OCZ-VERTEX/1.30, OCZ VERTEX-TURBO/1.5
"Patriot[ -]Torqx.*|"
- "STT_FT[MD](28|32|56|64)GX25H|" // Super Talent Ultradrive, tested with STT_FTM64GX25H/1916
- "TS(18|25)M(64|128)MLC(16|32|64|128|256|512)GSSD", // ASAX Leopard Hunt II, tested with TS25M64MLC64GSSD/0.1
+ "STT_FT[MD](28|32|56|64)GX25H|" // Super Talent Ultradrive GX, tested with STT_FTM64GX25H/1916
+ "TS(18|25)M(64|128)MLC(16|32|64|128|256|512)GSSD|" // ASAX Leopard Hunt II, tested with TS25M64MLC64GSSD/0.1
+ "FM-25S2I-(64|128)GBFII|" // G.Skill FALCON II, tested with FM-25S2I-64GBFII
+ "TS(60|120)GSSD25D-M", // Transcend Ultra SSD (SATA II), see also Ticket #80
"", "",
"-v 1,raw64 " // Raw_Read_Error_Rate
"-v 9,raw64 " // Power_On_Hours
"-v 227,raw48,Workld_Host_Reads_Perc "
"-v 228,raw48,Workload_Minutes"
},
- { "Kingston SSDNow V Series", // tested with KINGSTON SNV425S264GB/C091126a
- "KINGSTON SNV425S2(64|128)GB",
+ { "Intel 320 Series SSDs",
+ "INTEL SSDSA[12]CW(040|080|120|160|300|600)G3",
+ "", "",
+ //"-v 3,raw48,Spin_Up_Time "
+ //"-v 4,raw48,Start_Stop_Count "
+ //"-v 5,raw48,Reallocated_Sector_Ct "
+ //"-v 9,raw48,Power_On_Hours "
+ //"-v 12,raw48,Power_Cycle_Count "
+ "-v 170,raw48,Reserve_Block_Count "
+ "-v 171,raw48,Program_Fail_Count "
+ "-v 172,raw48,Erase_Fail_Count "
+ //"-v 184,raw48,End-to-End_Error "
+ //"-v 187,raw48,Reported_Uncorrect "
+ "-v 192,raw48,Unsafe_Shutdown_Count "
+ "-v 225,raw48,Host_Writes_32MiB "
+ "-v 226,raw48,Workld_Media_Wear_Indic " // Timed Workload Media Wear Indicator (percent*1024)
+ "-v 227,raw48,Workld_Host_Reads_Perc " // Timed Workload Host Reads Percentage
+ "-v 228,raw48,Workload_Minutes " // 226,227,228 can be reset by 'smartctl -t vendor,0x40'
+ //"-v 232,raw48,Available_Reservd_Space "
+ //"-v 233,raw48,Media_Wearout_Indicator "
+ "-v 241,raw48,Host_Writes_32MiB "
+ "-v 242,raw48,Host_Reads_32MiB"
+ },
+ { "Intel 510 Series SSDs",
+ "INTEL SSDSC2MH(120|250)A2",
+ "", "",
+ //"-v 3,raw48,Spin_Up_Time "
+ //"-v 4,raw48,Start_Stop_Count "
+ //"-v 5,raw48,Reallocated_Sector_Ct "
+ //"-v 9,raw48,Power_On_Hours "
+ //"-v 12,raw48,Power_Cycle_Count "
+ "-v 192,raw48,Unsafe_Shutdown_Count "
+ "-v 225,raw48,Host_Writes_32MiB "
+ //"-v 232,raw48,Available_Reservd_Space "
+ //"-v 233,raw48,Media_Wearout_Indicator"
+ },
+ { "Kingston branded X25-V SSDs", // fixed firmware
+ "KINGSTON SSDNow 40GB",
+ "2CV102(J[89A-Z]|[K-Z].)", // >= "2CV102J8"
+ "",
+ "-v 192,raw48,Unsafe_Shutdown_Count "
+ "-v 225,raw48,Host_Writes_32MiB "
+ "-v 226,raw48,Workld_Media_Wear_Indic "
+ "-v 227,raw48,Workld_Host_Reads_Perc "
+ "-v 228,raw48,Workload_Minutes"
+ },
+ { "Kingston branded X25-V SSDs", // buggy or unknown firmware
+ "KINGSTON SSDNow 40GB",
+ "",
+ "This drive may require a firmware update to\n"
+ "fix possible drive hangs when reading SMART self-test log.\n"
+ "To update Kingston branded drives, a modified Intel update\n"
+ "tool must be used. Search for \"kingston 40gb firmware\".",
+ "-v 192,raw48,Unsafe_Shutdown_Count "
+ "-v 225,raw48,Host_Writes_32MiB "
+ "-v 226,raw48,Workld_Media_Wear_Indic "
+ "-v 227,raw48,Workld_Host_Reads_Perc "
+ "-v 228,raw48,Workload_Minutes"
+ },
+ { "JMicron based SSDs", // JMicron JMF60x
+ "Kingston SSDNow V Series [0-9]*GB|" // tested with Kingston SSDNow V Series 64GB/B090522a
+ "TS(2|4|8|16|32|64|128|192)GSSD25S?-(M|S)", // Transcend IDE and SATA, tested with TS32GSSD25-M/V090331
+ "[BV].*", // other Transcend SSD versions will be catched by subsequent entry
+ "",
+ //"-v 9,raw48,Power_On_Hours " // raw value always 0?
+ //"-v 12,raw48,Power_Cycle_Count "
+ //"-v 194,tempminmax,Temperature_Celsius " // raw value always 0?
+ "-v 229,hex64:w012345r,Halt_System/Flash_ID " // Halt, Flash[7]
+ "-v 232,hex64:w012345r,Firmware_Version_Info " // "YYMMDD", #Channels, #Banks
+ "-v 233,hex48:w01234,ECC_Fail_Record " // Fail number, Row[3], Channel, Bank
+ "-v 234,raw24/raw24:w01234,Avg/Max_Erase_Ct "
+ "-v 235,raw24/raw24:w01z23,Good/Sys_Block_Ct"
+ // 1.....................................40 chars limit for smartmontools <= r3343
+ },
+ { "JMicron based SSDs", // JMicron JMF61x
+ "KINGSTON SNV425S2(64|128)GB|" // SSDNow V Series (2. Generation, JMF618),
+ // tested with KINGSTON SNV425S264GB/C091126a
+ "KINGSTON SS100S2(8|16)G|" // SSDNow S100 Series, tested with KINGSTON SS100S28G/D100309a
+ "KINGSTON SVP100S2B?(64|96|128|256|512)G|" // SSDNow V+100 Series,
+ // tested with KINGSTON SVP100S296G/CJR10202
+ "TOSHIBA THNS128GG4BBAA|" // Toshiba / Super Talent UltraDrive DX,
+ // tested with Toshiba 128GB 2.5" SSD (built in MacBooks)
+ "APPLE SSD TS.*|" // Toshiba?, tested with APPLE SSD TS064C/CJAA0201
+ "ADATA S596 Turbo|" // tested with ADATA S596 Turbo 256GB SATA SSD (JMicron JMF616)
+ "TS(8|16|32|64|128|192|256|512)GSSD25S-(MD?|S)", // Transcend SATA (JMF612), tested with TS256GSSD25S-M/101028
"", "",
"-v 3,raw48,Unknown_Attribute "
"-v 7,raw48,Unknown_Attribute "
"-v 8,raw48,Unknown_Attribute "
+ //"-v 9,raw48,Power_On_Hours "
"-v 10,raw48,Unknown_Attribute "
+ //"-v 12,raw48,Power_Cycle_Count "
+ "-v 168,raw48,SATA_Phy_Error_Count "
+ "-v 170,raw16,Bad_Block_Count "
+ "-v 173,raw16,Erase_Count "
+ "-v 175,raw48,Bad_Cluster_Table_Count "
+ "-v 192,raw48,Unexpect_Power_Loss_Ct "
"-v 240,raw48,Unknown_Attribute"
},
- { "Transcend IDE Solid State Drive",
- "TS(8|16|32|64|128)GSSD25-(M|S)",
- "", "", ""
- },
- { "Transcend SATA Solid State Drive",
- "TS(8|16|32|64|128|192)GSSD25S-(M|S)",
+ { "Samsung based SSDs",
+ "SAMSUNG SSD PM800 .*GB|" // SAMSUNG PM800 SSDs, tested with SAMSUNG SSD PM800 TH 64GB/VBM25D1Q
+ "SAMSUNG SSD PM810 .*GB|" // SAMSUNG PM810 (470 series) SSDs, tested with SAMSUNG SSD PM810 2.5" 128GB/AXM06D1Q
+ "SAMSUNG 470 Series SSD", // SAMSUNG 470 Series SSD, tested with SAMSUNG 470 Series SSD 64GB/AXM09B1Q
"", "",
- "-v 229,hex64,Halt_System_ID "
- "-v 232,hex64,Firmware_Version_information "
- "-v 233,hex64,ECC_Fail_Record "
- "-v 234,raw24/raw24,Erase_Count_Avg/Max "
- "-v 235,raw24/raw24,Block_Count_Good/System"
- },
- { "Transcend Ultra Series Solid State Drive (SATA II)",
- "TS(60|120)GSSD25D-M",
- "", "", ""
+ //"-v 9,raw48,Power_On_Hours "
+ //"-v 12,raw48,Power_Cycle_Count "
+ //"-v 175,raw48,Program_Fail_Count_Chip "
+ //"-v 176,raw48,Erase_Fail_Count_Chip "
+ //"-v 177,raw48,Wear_Leveling_Count Wear "
+ //"-v 178,raw48,Used_Rsvd_Blk_Cnt_Chip "
+ //"-v 179,raw48,Used_Rsvd_Blk_Cnt_Tot "
+ //"-v 180,raw48,Unused_Rsvd_Blk_Cnt_Tot "
+ //"-v 181,raw48,Program_Fail_Cnt_Total "
+ //"-v 182,raw48,Erase_Fail_Count_Total "
+ //"-v 183,raw48,Runtime_Bad_Block "
+ "-v 187,raw48,Uncorrectable_Error_Cnt "
+ //"-v 190,raw48,Temperature_Exceed_Cnt " // seems to be some sort of temperature value for 470 Series?
+ //"-v 194,raw48,Airflow_Temperature "
+ "-v 195,raw48,ECC_Rate "
+ //"-v 198,raw48,Offline_Uncorrectable "
+ "-v 199,raw48,CRC_Error_Count "
+ "-v 201,raw48,Supercap_Status "
+ "-v 202,raw48,Exception_Mode_Status"
},
{ "Transcend CompactFlash Cards", // tested with TRANSCEND/20080820, TS4GCF133/20100709
"TRANSCEND|TS4GCF133",
"MM0500EANCR",
"", "", ""
},
- { "IBM Deskstar 60GXP series", // ER60A46A firmware
+ { "HP 250GB SATA disk VB0250EAVER",
+ "VB0250EAVER",
+ "", "", ""
+ },
+ { "IBM Deskstar 60GXP", // ER60A46A firmware
"(IBM-|Hitachi )?IC35L0[12346]0AVER07.*",
"ER60A46A",
"", ""
},
- { "IBM Deskstar 60GXP series", // All other firmware
+ { "IBM Deskstar 60GXP", // All other firmware
"(IBM-|Hitachi )?IC35L0[12346]0AVER07.*",
"",
"IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
"http://www.ibm.com/pc/support/site.wss/MIGR-42215.html",
""
},
- { "IBM Deskstar 40GV & 75GXP series (A5AA/A6AA firmware)",
+ { "IBM Deskstar 40GV & 75GXP (A5AA/A6AA firmware)",
"(IBM-)?DTLA-30[57]0[123467][05].*",
"T[WX][123468AG][OF]A[56]AA",
"", ""
},
- { "IBM Deskstar 40GV & 75GXP series (all other firmware)",
+ { "IBM Deskstar 40GV & 75GXP (all other firmware)",
"(IBM-)?DTLA-30[57]0[123467][05].*",
"",
"IBM Deskstar 40GV and 75GXP drives may need upgraded SMART firmware.\n"
"",
"-v 9,seconds"
},
- { "Fujitsu MHG series",
+ { "Fujitsu MHG",
"FUJITSU MHG2...ATU?.*",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MHH series",
+ { "Fujitsu MHH",
"FUJITSU MHH2...ATU?.*",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MHJ series",
+ { "Fujitsu MHJ",
"FUJITSU MHJ2...ATU?.*",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MHK series",
+ { "Fujitsu MHK",
"FUJITSU MHK2...ATU?.*",
"",
"",
"checksum error bug.",
"-v 9,seconds"
},
- { "Fujitsu MHN series",
+ { "Fujitsu MHN",
"FUJITSU MHN2...AT",
"",
"",
"-v 9,seconds -v 192,emergencyretractcyclect "
"-v 198,offlinescanuncsectorct -v 200,writeerrorcount"
},
- { "Fujitsu MHSxxxxAT family",
+ { "Fujitsu MHS AT",
"FUJITSU MHS20[6432]0AT( .)?",
"",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MHU series",
+ { "Fujitsu MHU",
"FUJITSU MHU2...ATU?.*",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MHV series",
+ { "Fujitsu MHV",
"FUJITSU MHV2...(AH|AS|AT|BH|BS|BT).*",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MPA..MPG series",
+ { "Fujitsu MPA..MPG",
"FUJITSU MP[A-G]3...A[HTEV]U?.*",
"",
"",
"-v 9,seconds"
},
- { "Fujitsu MHY2 BH series",
+ { "Fujitsu MHY BH",
"FUJITSU MHY2(04|06|08|10|12|16|20|25)0BH.*",
"", "",
"-v 240,raw48,Transfer_Error_Rate"
},
- { "Fujitsu MHW2 AC", // tested with FUJITSU MHW2060AC/00900004
+ { "Fujitsu MHW AC", // tested with FUJITSU MHW2060AC/00900004
"FUJITSU MHW20(40|60)AC",
"", "", ""
},
- { "Fujitsu MHW2 BH series",
+ { "Fujitsu MHW BH",
"FUJITSU MHW2(04|06|08|10|12|16)0BH.*",
"", "", ""
},
- { "Fujitsu MHW2 BJ series",
+ { "Fujitsu MHW BJ",
"FUJITSU MHW2(08|12|16)0BJ.*",
"", "", ""
},
- { "Fujitsu MHZ2 BH series",
+ { "Fujitsu MHZ BH",
"FUJITSU MHZ2(04|08|12|16|20|25|32)0BH.*",
"", "", ""
},
- { "Fujitsu MHZ2 BJ series",
+ { "Fujitsu MHZ BJ",
"FUJITSU MHZ2(08|12|16|20|25|32)0BJ.*",
"",
"",
"-v 9,minutes"
},
- { "Fujitsu MHZ2 BS series",
+ { "Fujitsu MHZ BS",
"FUJITSU MHZ2(12|25)0BS.*",
"", "", ""
},
- { "Fujitsu MHZ2 BK series",
+ { "Fujitsu MHZ BK",
"FUJITSU MHZ2(08|12|16|25)0BK.*",
"", "", ""
},
- { "Fujitsu MJA2 BH series",
+ { "Fujitsu MJA BH",
"FUJITSU MJA2(08|12|16|25|32|40|50)0BH.*",
"", "", ""
},
"SAMSUNG SV0322A",
"", "", ""
},
- { "SAMSUNG SpinPoint V80 series", // tested with SV1604N/TR100-23
+ { "SAMSUNG SpinPoint V80", // tested with SV1604N/TR100-23
"SAMSUNG SV(0211|0401|0612|0802|1203|1604)N",
"",
"",
"",
"-v 9,halfminutes -F samsung"
},
- { "SAMSUNG SpinPoint F1 DT series", // tested with HD103UJ/1AA01113
+ { "SAMSUNG SpinPoint F1 DT", // tested with HD103UJ/1AA01113
"SAMSUNG HD(083G|16[12]G|25[12]H|32[12]H|50[12]I|642J|75[23]L|10[23]U)J",
"", "", ""
},
- { "SAMSUNG SpinPoint F1 RE series", // tested with HE103UJ/1AA01113
+ { "SAMSUNG SpinPoint F1 RE", // tested with HE103UJ/1AA01113
"SAMSUNG HE(252H|322H|502I|642J|753L|103U)J",
"", "", ""
},
- { "SAMSUNG SpinPoint F2 EG series", // tested with HD154UI/1AG01118
+ { "SAMSUNG SpinPoint F2 EG", // tested with HD154UI/1AG01118
"SAMSUNG HD(502H|10[23]S|15[34]U)I",
"", "", ""
},
- { "SAMSUNG SpinPoint F3 series", // tested with HD502HJ/1AJ100E4
+ { "SAMSUNG SpinPoint F3", // tested with HD502HJ/1AJ100E4
"SAMSUNG HD(502H|754J|103S)J",
"", "", ""
},
- { "SAMSUNG SpinPoint F3 EG series", // tested with HD503HI/1AJ100E4, HD153WI/1AN10002
+ { "SAMSUNG SpinPoint F3 EG", // tested with HD503HI/1AJ100E4, HD153WI/1AN10002
"SAMSUNG HD(253G|(324|503)H|754J|105S|(153|203)W)I",
"", "", ""
},
"http://sourceforge.net/apps/trac/smartmontools/wiki/SamsungF4EGBadBlocks",
""
},
- { "SAMSUNG SpinPoint S250 series", // tested with HD200HJ/KF100-06
+ { "SAMSUNG SpinPoint S250", // tested with HD200HJ/KF100-06
"SAMSUNG HD(162|200|250)HJ",
"", "", ""
},
- { "SAMSUNG SpinPoint T133 series", // tested with HD300LJ/ZT100-12, HD400LJ/ZZ100-14, HD401LJ/ZZ100-15
+ { "SAMSUNG SpinPoint T133", // tested with HD300LJ/ZT100-12, HD400LJ/ZZ100-14, HD401LJ/ZZ100-15
"SAMSUNG HD(250KD|(30[01]|320|40[01])L[DJ])",
"", "", ""
},
"", "",
"-v 197,increasing" // at least HD501LJ/CR100-11
},
- { "SAMSUNG SpinPoint P120 series", // VF100-37 firmware, tested with SP2514N/VF100-37
+ { "SAMSUNG SpinPoint P120", // VF100-37 firmware, tested with SP2514N/VF100-37
"SAMSUNG SP(16[01]3|2[05][01]4)[CN]",
"VF100-37",
"",
"-F samsung3"
},
- { "SAMSUNG SpinPoint P120 series", // other firmware, tested with SP2504C/VT100-33
+ { "SAMSUNG SpinPoint P120", // other firmware, tested with SP2504C/VT100-33
"SAMSUNG SP(16[01]3|2[05][01]4)[CN]",
"",
"May need -F samsung3 enabled; see manual for details.",
""
},
- { "SAMSUNG SpinPoint P80 SD series", // tested with HD160JJ/ZM100-33
+ { "SAMSUNG SpinPoint P80 SD", // tested with HD160JJ/ZM100-33
"SAMSUNG HD(080H|120I|160J)J",
"", "", ""
},
- { "SAMSUNG SpinPoint P80 series", // BH100-35 firmware, tested with SP0842N/BH100-35
+ { "SAMSUNG SpinPoint P80", // BH100-35 firmware, tested with SP0842N/BH100-35
"SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
"BH100-35",
"",
"-F samsung3"
},
- { "SAMSUNG SpinPoint P80 series", // firmware *-35 or later
+ { "SAMSUNG SpinPoint P80", // firmware *-35 or later
"SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
".*-3[5-9]",
"May need -F samsung3 enabled; see manual for details.",
""
},
- { "SAMSUNG SpinPoint P80 series", // firmware *-25...34, tested with SP1614C/SW100-25 and -34
+ { "SAMSUNG SpinPoint P80", // firmware *-25...34, tested with SP1614C/SW100-25 and -34
"SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
".*-(2[5-9]|3[0-4])",
"",
"-v 9,halfminutes -v 198,increasing"
},
- { "SAMSUNG SpinPoint P80 series", // firmware *-23...24, tested with
+ { "SAMSUNG SpinPoint P80", // firmware *-23...24, tested with
// SP0802N/TK100-23,
// SP1213N/TL100-23,
// SP1604N/TM100-23 and -24
"",
"-v 9,halfminutes -F samsung2"
},
- { "SAMSUNG SpinPoint P80 series", // unknown firmware
+ { "SAMSUNG SpinPoint P80", // unknown firmware
"SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]",
"",
"May need -F samsung2 or -F samsung3 enabled; see manual for details.",
""
},
- { "SAMSUNG SpinPoint M40/60/80 series", // tested with HM160JI/AD100-16
+ { "SAMSUNG SpinPoint M40/60/80", // tested with HM160JI/AD100-16
"SAMSUNG HM(0[468]0H|1[026]0J)[CI]",
"",
"",
"-v 9,halfminutes"
},
- { "SAMSUNG SpinPoint M5 series", // tested with HM160HI/HH100-12
- "SAMSUNG HM((061|080)G|(121|160)H|250J)I",
+ { "SAMSUNG SpinPoint M5", // tested with HM160HI/HH100-12
+ "SAMSUNG HM(((061|080)G|(121|160)H|250J)I|160HC)",
"", "", ""
},
{ "SAMSUNG SpinPoint M6", // tested with HM320JI/2SS00_01 M6
"SAMSUNG HM(251J|320[HJ]|[45]00L)I",
"", "", ""
},
- { "SAMSUNG SpinPoint M7 series", // tested with HM500JI/2AC101C4
+ { "SAMSUNG SpinPoint M7", // tested with HM500JI/2AC101C4
"SAMSUNG HM(250H|320I|[45]00J)I",
"", "", ""
},
"SAMSUNG HM(161G|(251|321)H|501I|641J)I",
"", "", ""
},
- { "SAMSUNG SpinPoint M series", // tested with MP0402H/UC100-11
+ { "SAMSUNG SpinPoint MT2", // tested with HM100UI/2AM10001
+ "SAMSUNG HM100UI",
+ "", "", ""
+ },
+ { "SAMSUNG HM100UX (S2 Portable)", // tested with HM100UX/2AM10001
+ "SAMSUNG HM100UX",
+ "", "", ""
+ },
+ { "SAMSUNG SpinPoint M", // tested with MP0402H/UC100-11
"SAMSUNG MP0(302|402|603|804)H",
"",
"",
"-v 9,halfminutes"
},
- { "SAMSUNG PM800 SSDs", // tested with SAMSUNG SSD PM800 TH 64GB/VBM25D1Q
- "SAMSUNG SSD PM800 .*GB",
- "", "", ""
- },
- { "SAMSUNG PM810 (470 series) SSDs", // tested with SAMSUNG SSD PM810 2.5" 128GB/AXM06D1Q
- "SAMSUNG SSD PM810 .*GB",
+ { "SAMSUNG SpinPoint N3U-3 (USB, 4KiB LLS)", // tested with HS25YJZ/3AU10-01
+ "SAMSUNG HS(122H|2[05]YJ)Z",
"", "", ""
},
/*
""
},
*/
- { "Maxtor Fireball 541DX family",
+ { "Maxtor Fireball 541DX",
"Maxtor 2B0(0[468]|1[05]|20)H1",
"",
"",
"-v 9,minutes -v 194,unknown"
},
- { "Maxtor Fireball 3 family",
+ { "Maxtor Fireball 3",
"Maxtor 2F0[234]0[JL]0",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 1280 ATA family", // no self-test log, ATA2-Fast
+ { "Maxtor DiamondMax 1280 ATA", // no self-test log, ATA2-Fast
"Maxtor 8(1280A2|2160A4|2560A4|3840A6|4000A6|5120A8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 2160 Ultra ATA family",
+ { "Maxtor DiamondMax 2160 Ultra ATA",
"Maxtor 8(2160D2|3228D3|3240D3|4320D4|6480D6|8400D8|8455D8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 2880 Ultra ATA family",
+ { "Maxtor DiamondMax 2880 Ultra ATA",
"Maxtor 9(0510D4|0576D4|0648D5|0720D5|0840D6|0845D6|0864D6|1008D7|1080D8|1152D8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 3400 Ultra ATA family",
+ { "Maxtor DiamondMax 3400 Ultra ATA",
"Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax D540X-4G family",
+ { "Maxtor DiamondMax D540X-4G",
"Maxtor 4G(120J6|160J[68])",
"",
"",
"-v 9,minutes -v 194,unknown"
},
- { "Maxtor DiamondMax D540X-4K family",
+ { "Maxtor DiamondMax D540X-4K",
"MAXTOR 4K(020H1|040H2|060H3|080H4)",
"", "", ""
},
- { "Maxtor DiamondMax Plus D740X family",
+ { "Maxtor DiamondMax Plus D740X",
"MAXTOR 6L0(20[JL]1|40[JL]2|60[JL]3|80[JL]4)",
"", "", ""
},
- { "Maxtor DiamondMax Plus 5120 Ultra ATA 33 family",
+ { "Maxtor DiamondMax Plus 5120 Ultra ATA 33",
"Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax Plus 6800 Ultra ATA 66 family",
+ { "Maxtor DiamondMax Plus 6800 Ultra ATA 66",
"Maxtor 9(2732U8|2390U7|204[09]U6|1707U5|1366U4|1024U3|0845U3|0683U2)",
"",
"",
"",
"-v 9,minutes -v 194,unknown"
},
- { "Maxtor DiamondMax 16 family",
+ { "Maxtor DiamondMax 16",
"Maxtor 4(R0[68]0[JL]0|R1[26]0L0|A160J0|R120L4)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 4320 Ultra ATA family",
+ { "Maxtor DiamondMax 4320 Ultra ATA",
"Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D[34]|90432D2)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 17 VL family",
+ { "Maxtor DiamondMax 17 VL",
"Maxtor 9(0431U1|0641U2|0871U2|1301U3|1741U4)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 20 VL family",
+ { "Maxtor DiamondMax 20 VL",
"Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax VL 30 family", // U: ATA66, H: ATA100
+ { "Maxtor DiamondMax VL 30", // U: ATA66, H: ATA100
"Maxtor (33073U4|32049U3|31536U2|30768U1|33073H4|32305H3|31536H2|30768H1)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 36 family",
+ { "Maxtor DiamondMax 36",
"Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 40 ATA 66 series",
+ { "Maxtor DiamondMax 40 ATA 66",
"Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax Plus 40 series (Ultra ATA 66 and Ultra ATA 100)",
+ { "Maxtor DiamondMax Plus 40 (Ultra ATA 66 and Ultra ATA 100)",
"Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 40 VL Ultra ATA 100 series",
+ { "Maxtor DiamondMax 40 VL Ultra ATA 100",
"Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax Plus 45 Ulta ATA 100 family",
+ { "Maxtor DiamondMax Plus 45 Ulta ATA 100",
"Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 60 ATA 66 family",
+ { "Maxtor DiamondMax 60 ATA 66",
"Maxtor 9(1023U2|1536U2|2049U3|2305U3|3073U4|4610U6|6147U8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 60 ATA 100 family",
+ { "Maxtor DiamondMax 60 ATA 100",
"Maxtor 9(1023H2|1536H2|2049H3|2305H3|3073H4|4098H6|4610H6|6147H8)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax Plus 60 family",
+ { "Maxtor DiamondMax Plus 60",
"Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 80 family",
+ { "Maxtor DiamondMax 80",
"Maxtor (98196H8|96147H6)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 536DX family",
+ { "Maxtor DiamondMax 536DX",
"Maxtor 4W(100H6|080H6|060H4|040H3|030H2)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax Plus 8 family",
+ { "Maxtor DiamondMax Plus 8",
"Maxtor 6(E0[234]|K04)0L0",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 10 family (ATA/133 and SATA/150)",
+ { "Maxtor DiamondMax 10 (ATA/133 and SATA/150)",
"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",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 10 family (SATA/300)",
+ { "Maxtor DiamondMax 10 (SATA/300)",
"Maxtor 6V(080E|160E|200E|250F|300F|320F)0",
"", "", ""
},
- { "Maxtor DiamondMax Plus 9 family",
+ { "Maxtor DiamondMax Plus 9",
"Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)",
"",
"",
"-v 9,minutes"
},
- { "Maxtor DiamondMax 11 family",
+ { "Maxtor DiamondMax 11",
"Maxtor 6H[45]00[FR]0",
"", "", ""
},
"",
"-v 9,minutes"
},
- { "Maxtor MaXLine II family",
+ { "Maxtor MaXLine II",
"Maxtor [45]A(25|30|32)0[JN]0",
"",
"",
"-v 9,minutes"
},
- { "Maxtor MaXLine III family (ATA/133 and SATA/150)",
+ { "Maxtor MaXLine III (ATA/133 and SATA/150)",
"Maxtor 7L(25|30)0[SR]0",
"",
"",
"-v 9,minutes"
},
- { "Maxtor MaXLine III family (SATA/300)",
+ { "Maxtor MaXLine III (SATA/300)",
"Maxtor 7V(25|30)0F0",
"", "", ""
},
- { "Maxtor MaXLine Pro 500 family", // There is also a 7H500R0 model, but I
+ { "Maxtor MaXLine Pro 500", // There is also a 7H500R0 model, but I
"Maxtor 7H500F0", // haven't added it because I suspect
"", // it might need vendoropts_9_minutes
"", "" // and nobody has submitted a report yet
"",
"-v 9,minutes -v 193,loadunload"
},
- { "HITACHI Travelstar DK23XX/DK23XXB series",
+ { "HITACHI Travelstar DK23XX/DK23XXB",
"HITACHI_DK23..-..B?",
"",
"",
"",
"-v 9,minutes -v 193,loadunload"
},
- { "Hitachi Travelstar C4K60 family", // 1.8" slim drive
+ { "Hitachi Travelstar C4K60", // 1.8" slim drive
"HTC4260[23]0G5CE00|HTC4260[56]0G8CE00",
"",
"",
"-v 9,minutes -v 193,loadunload"
},
- { "IBM Travelstar 4GT family",
+ { "IBM Travelstar 4GT",
"IBM-DTCA-2(324|409)0",
"", "", ""
},
- { "IBM Travelstar 6GN family",
+ { "IBM Travelstar 6GN",
"IBM-DBCA-20(324|486|648)0",
"", "", ""
},
- { "IBM Travelstar 25GS, 18GT, and 12GN family",
+ { "IBM Travelstar 25GS, 18GT, and 12GN",
"IBM-DARA-2(25|18|15|12|09|06)000",
"", "", ""
},
"IBM-DTNA-2(180|216)0",
"", "", ""
},
- { "IBM Travelstar 48GH, 30GN, and 15GN family",
+ { "IBM Travelstar 48GH, 30GN, and 15GN",
"(IBM-|Hitachi )?IC25(T048ATDA05|N0(30|20|15|12|10|07|06|05)ATDA04)-.",
"", "", ""
},
- { "IBM Travelstar 32GH, 30GT, and 20GN family",
+ { "IBM Travelstar 32GH, 30GT, and 20GN",
"IBM-DJSA-2(32|30|20|10|05)",
"", "", ""
},
- { "IBM Travelstar 4GN family",
+ { "IBM Travelstar 4GN",
"IBM-DKLA-2(216|324|432)0",
"", "", ""
},
- { "IBM/Hitachi Travelstar 60GH and 40GN family",
+ { "IBM/Hitachi Travelstar 60GH and 40GN",
"(IBM-|Hitachi )?IC25(T060ATC[SX]05|N0[4321]0ATC[SX]04)-.",
"", "", ""
},
- { "IBM/Hitachi Travelstar 40GNX family",
+ { "IBM/Hitachi Travelstar 40GNX",
"(IBM-|Hitachi )?IC25N0[42]0ATC[SX]05-.",
"", "", ""
},
- { "Hitachi Travelstar 80GN family",
+ { "Hitachi Travelstar 80GN",
"(Hitachi )?IC25N0[23468]0ATMR04-.",
"", "", ""
},
"(Hitachi )?HT[ES]7250(12|16|25|32|50)A9A36[45]",
"", "", ""
},
- { "IBM Deskstar 14GXP and 16GP series",
+ { "IBM Deskstar 14GXP and 16GP",
"IBM-DTTA-3(7101|7129|7144|5032|5043|5064|5084|5101|5129|5168)0",
"", "", ""
},
- { "IBM Deskstar 25GP and 22GXP family",
+ { "IBM Deskstar 25GP and 22GXP",
"IBM-DJNA-3(5(101|152|203|250)|7(091|135|180|220))0",
"", "", ""
},
- { "IBM Deskstar 37GP and 34GXP family",
+ { "IBM Deskstar 37GP and 34GXP",
"IBM-DPTA-3(5(375|300|225|150)|7(342|273|205|136))0",
"", "", ""
},
- { "IBM/Hitachi Deskstar 120GXP family",
+ { "IBM/Hitachi Deskstar 120GXP",
"(IBM-)?IC35L((020|040|060|080|120)AVVA|0[24]0AVVN)07-[01]",
"", "", ""
},
- { "IBM/Hitachi Deskstar GXP-180 family",
+ { "IBM/Hitachi Deskstar GXP-180",
"(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]",
"", "", ""
},
+ { "Hitachi Deskstar 5K3000",
+ "(Hitachi )?HDS5C30(15|20|30)ALA63[02].*",
+ "", "", ""
+ },
{ "Hitachi Deskstar 7K80",
"(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380).*",
"", "", ""
"(Hitachi )?HUA7220((50|10)C|20A)LA33[01]",
"", "", ""
},
- { "Toshiba 2.5\" HDD series (10-20 GB)",
+ { "Toshiba 2.5\" HDD (10-20 GB)",
"TOSHIBA MK(101[67]GAP|15[67]GAP|20(1[678]GAP|(18|23)GAS))",
"", "", ""
},
- { "Toshiba 2.5\" HDD series (30-60 GB)",
+ { "Toshiba 2.5\" HDD (30-60 GB)",
"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)",
"", "", ""
},
- { "Toshiba 2.5\" HDD series (80 GB and above)",
+ { "Toshiba 2.5\" HDD (80 GB and above)",
"TOSHIBA MK(80(25GAS|26GAX|32GAX|32GSX)|10(31GAS|32GAX)|12(33GAS|34G[AS]X)|2035GSS)",
"", "", ""
},
- { "Toshiba 2.5\" HDD MK..52GSX series",
+ { "Toshiba 2.5\" HDD MK..52GSX",
"TOSHIBA MK(80|12|16|25|32)52GSX",
"", "", ""
},
- { "Toshiba 2.5\" HDD MK..59GSXP series", // Adv. Format
+ { "Toshiba 2.5\" HDD MK..59GSXP (Adv. Format)", // Adv. Format
"TOSHIBA MK(32|50|64|75)59GSXP?",
"", "", ""
},
- { "Toshiba 2.5\" HDD MK..59GSM series", // Adv. Format
+ { "Toshiba 2.5\" HDD MK..59GSM (Adv. Format)", // Adv. Format
"TOSHIBA MK(75|10)59GSM",
"", "", ""
},
- { "Toshiba 2.5\" HDD MK..65GSX series", // tested with TOSHIBA MK5065GSX/GJ003A
+ { "Toshiba 2.5\" HDD MK..65GSX", // tested with TOSHIBA MK5065GSX/GJ003A
"TOSHIBA MK(16|25|32|50|64)65GSX",
"", "", ""
},
- { "Toshiba 1.8\" HDD series",
+ { "Toshiba 1.8\" HDD",
"TOSHIBA MK[23468]00[4-9]GA[HL]",
"", "", ""
},
"TOS MK[34]019GAXB SUN[34]0G",
"", "", ""
},
- { "Seagate Momentus family",
+ { "Seagate Momentus",
"ST9(20|28|40|48)11A",
"", "", ""
},
- { "Seagate Momentus 42 family",
+ { "Seagate Momentus 42",
"ST9(2014|3015|4019)A",
"", "", ""
},
- { "Seagate Momentus 4200.2 series",
+ { "Seagate Momentus 4200.2",
"ST9(100822|808210|60821|50212|402113|30219)A",
"", "", ""
},
- { "Seagate Momentus 5400.2 series",
+ { "Seagate Momentus 5400.2",
"ST9(808211|60822|408114|308110|120821|10082[34]|8823|6812|4813|3811)AS?",
"", "", ""
},
- { "Seagate Momentus 5400.3 series",
+ { "Seagate Momentus 5400.3",
"ST9(4081[45]|6081[35]|8081[15]|100828|120822|160821)AS?",
"", "", ""
},
- { "Seagate Momentus 5400.3 ED series",
+ { "Seagate Momentus 5400.3 ED",
"ST9(4081[45]|6081[35]|8081[15]|100828|120822|160821)AB",
"", "", ""
},
- { "Seagate Momentus 5400.4 series",
+ { "Seagate Momentus 5400.4",
"ST9(120817|(160|200|250)827)AS",
"", "", ""
},
- { "Seagate Momentus 5400.5 series",
+ { "Seagate Momentus 5400.5",
"ST9((80|120|160)310|(250|320)320)AS",
"", "", ""
},
- { "Seagate Momentus 5400.6 series",
+ { "Seagate Momentus 5400.6",
"ST9(80313|160(301|314)|(12|25)0315|250317|(320|500)325|500327|640320)ASG?",
"", "", ""
},
- { "Seagate Momentus 5400 PSD series", // Hybrid drives
+ { "Seagate Momentus 5400 PSD", // Hybrid drives
"ST9(808212|(120|160)8220)AS",
"", "", ""
},
- { "Seagate Momentus 7200.1 series",
+ { "Seagate Momentus 7200.1",
"ST9(10021|80825|6023|4015)AS?",
"", "", ""
},
- { "Seagate Momentus 7200.2 series",
+ { "Seagate Momentus 7200.2",
"ST9(80813|100821|120823|160823|200420)ASG?",
"", "", ""
},
- { "Seagate Momentus 7200.3 series",
+ { "Seagate Momentus 7200.3",
"ST9((80|120|160)411|(250|320)421)ASG?",
"", "", ""
},
- { "Seagate Momentus 7200.4 series",
+ { "Seagate Momentus 7200.4",
"ST9(160412|250410|320423|500420)ASG?",
"", "", ""
},
- { "Seagate Momentus 7200 FDE.2 series",
+ { "Seagate Momentus 7200 FDE.2",
"ST9((160413|25041[12]|320426|50042[12])AS|(16041[489]|2504[16]4|32042[67]|500426)ASG)",
"", "", ""
},
- { "Seagate Momentus XT series", // tested with ST95005620AS/SD22
+ { "Seagate Momentus XT", // tested with ST95005620AS/SD22
"ST9(2505610|3205620|5005620)AS",
"", "", ""
},
"ST3(2110|3221|4321|6531|8641)A",
"", "", ""
},
- { "Seagate U Series X family",
+ { "Seagate U Series X",
"ST3(10014A(CE)?|20014A)",
"", "", ""
},
- { "Seagate U8 family",
+ { "Seagate U8",
"ST3(4313|6811|8410|13021|17221)A",
"", "", ""
},
- { "Seagate U7 family",
+ { "Seagate U7",
"ST3(30012|40012|60012|80022|120020)A",
"", "", ""
},
- { "Seagate U Series 6 family",
+ { "Seagate U Series 6",
"ST3(8002|6002|4081|3061|2041)0A",
"", "", ""
},
- { "Seagate U Series 5 family",
+ { "Seagate U Series 5",
"ST3(40823|30621|20413|15311|10211)A",
"", "", ""
},
- { "Seagate U4 family",
+ { "Seagate U4",
"ST3(2112|4311|6421|8421)A",
"", "", ""
},
- { "Seagate U8 family",
+ { "Seagate U8",
"ST3(8410|4313|17221|13021)A",
"", "", ""
},
- { "Seagate U10 family",
+ { "Seagate U10",
"ST3(20423|15323|10212)A",
"", "", ""
},
- { "Seagate Barracuda ATA family",
+ { "Seagate Barracuda ATA",
"ST3(2804|2724|2043|1362|1022|681)0A",
"", "", ""
},
- { "Seagate Barracuda ATA II family",
+ { "Seagate Barracuda ATA II",
"ST3(3063|2042|1532|1021)0A",
"", "", ""
},
- { "Seagate Barracuda ATA III family",
+ { "Seagate Barracuda ATA III",
"ST3(40824|30620|20414|15310|10215)A",
"", "", ""
},
- { "Seagate Barracuda ATA IV family",
+ { "Seagate Barracuda ATA IV",
"ST3(20011|30011|40016|60021|80021)A",
"", "", ""
},
- { "Seagate Barracuda ATA V family",
+ { "Seagate Barracuda ATA V",
"ST3(12002(3A|4A|9A|3AS)|800(23A|15A|23AS)|60(015A|210A)|40017A)",
"", "", ""
},
"ST340015A",
"", "", ""
},
- { "Seagate Barracuda 7200.7 and 7200.7 Plus family",
+ { "Seagate Barracuda 7200.7 and 7200.7 Plus",
"ST3(200021A|200822AS?|16002[13]AS?|12002[26]AS?|1[26]082[78]AS|8001[13]AS?|8081[79]AS|60014A|40111AS|40014AS?)",
"", "", ""
},
- { "Seagate Barracuda 7200.8 family",
+ { "Seagate Barracuda 7200.8",
"ST3(400[68]32|300[68]31|250[68]23|200826)AS?",
"", "", ""
},
- { "Seagate Barracuda 7200.9 family",
+ { "Seagate Barracuda 7200.9",
"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?.*",
"", "", ""
},
- { "Seagate Barracuda 7200.10 family",
+ { "Seagate Barracuda 7200.10",
"ST3((80|160)[28]15|200820|250[34]10|(250|300|320|400)[68]20|360320|500[68]30|750[68]40)AS?",
"", "", ""
},
- { "Seagate Barracuda 7200.11 family", // unaffected firmware
+ { "Seagate Barracuda 7200.11", // unaffected firmware
"ST3(160813|320[68]13|500[368]20|640[36]23|640[35]30|750[36]30|1000(333|[36]40)|1500341)AS?",
"CC.?.?", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957
"", ""
},
- { "Seagate Barracuda 7200.11 family", // fixed firmware
+ { "Seagate Barracuda 7200.11", // fixed firmware
"ST3(500[368]20|750[36]30|1000340)AS?",
"SD1A", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207951
"", ""
},
- { "Seagate Barracuda 7200.11 family", // fixed firmware
+ { "Seagate Barracuda 7200.11", // fixed firmware
"ST3(160813|320[68]13|640[36]23|1000333|1500341)AS?",
"SD[12]B", // http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957
"", ""
},
- { "Seagate Barracuda 7200.11 family", // buggy firmware
+ { "Seagate Barracuda 7200.11", // buggy firmware
"ST3(500[368]20|640[35]30|750[36]30|1000340)AS?",
"(AD14|SD1[5-9]|SD81)",
"There are known problems with these drives,\n"
"http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207951",
""
},
- { "Seagate Barracuda 7200.11 family", // unknown firmware
+ { "Seagate Barracuda 7200.11", // unknown firmware
"ST3(160813|320[68]13|500[368]20|640[36]23|640[35]30|750[36]30|1000(333|[36]40)|1500341)AS?",
"",
"There are known problems with these drives,\n"
"http://seagate.custkb.com/seagate/crm/selfservice/search.jsp?DocId=207957",
""
},
- { "Seagate Barracuda 7200.12 family",
+ { "Seagate Barracuda 7200.12",
"ST3(160318|25031[18]|320418|50041[08]|750(518|52[38])|100052[38])AS",
"", "", ""
},
"ST3(500412|1000520|1500541|2000542)AS",
"", "", ""
},
+ { "Seagate Barracuda Green (Adv. Format)",
+ "ST(1000DL002|(15|20)00DL003)-.*",
+ "", "", ""
+ },
{ "Seagate Barracuda XT",
- "ST32000641AS",
+ "ST(32000641|33000651)AS",
"", "", ""
},
{ "Seagate Constellation (SATA)", // tested with ST9500530NS/SN03
"ST3(50051|100052|200064)4NS",
"", "", ""
},
- { "Seagate Pipeline HD 5900.1 family",
+ { "Seagate Pipeline HD 5900.1",
"ST3(160310|320[34]10|500(321|422))CS",
"", "", ""
},
- { "Seagate Pipeline HD 5900.2 family", // tested with ST31000322CS/SC13
+ { "Seagate Pipeline HD 5900.2", // tested with ST31000322CS/SC13
"ST3(160316|250[34]12|320(311|413)|500(312|414)|1000(322|424))CS",
"", "", ""
},
"ST3(1724|1303|1023|842|431)2A",
"", "", ""
},
- { "Seagate NL35 family",
+ { "Seagate NL35",
"ST3(250623|250823|400632|400832|250824|250624|400633|400833|500641|500841)NS",
"", "", ""
},
- { "Seagate SV35.2 Series",
+ { "Seagate SV35.2",
"ST3(160815|250820|320620|500630|750640)(A|S)V",
"", "", ""
},
- { "Seagate DB35.3 Series",
+ { "Seagate DB35.3",
"ST3(750640SCE|((80|160)215|(250|320|400)820|500830|750840)(A|S)CE)",
"", "", ""
},
"WDC WD([2468]00E|1[26]00A)B-.*",
"", "", ""
},
- { "Western Digital Caviar family",
+ { "Western Digital Caviar",
/* Western Digital drives with this comment all appear to use Attribute 9 in
* a non-standard manner. These entries may need to be updated when it
* is understood exactly how Attribute 9 should be interpreted.
"WDC WD(2|3|4|6|8|10|12|16|18|20|25)00BB-.*",
"", "", ""
},
- { "Western Digital Caviar WDxxxAB series",
+ { "Western Digital Caviar WDxxxAB",
/* Western Digital drives with this comment all appear to use Attribute 9 in
* a non-standard manner. These entries may need to be updated when it
* is understood exactly how Attribute 9 should be interpreted.
"WDC WD(3|4|6|8|25)00AB-.*",
"", "", ""
},
- { "Western Digital Caviar WDxxxAA series",
+ { "Western Digital Caviar WDxxxAA",
/* Western Digital drives with this comment all appear to use Attribute 9 in
* a non-standard manner. These entries may need to be updated when it
* is understood exactly how Attribute 9 should be interpreted.
"WDC WD...?AA(-.*)?",
"", "", ""
},
- { "Western Digital Caviar WDxxxBA series",
+ { "Western Digital Caviar WDxxxBA",
/* Western Digital drives with this comment all appear to use Attribute 9 in
* a non-standard manner. These entries may need to be updated when it
* is understood exactly how Attribute 9 should be interpreted.
"WDC WD...BA",
"", "", ""
},
- { "Western Digital Caviar AC series", // add only 5400rpm/7200rpm (ata33 and faster)
+ { "Western Digital Caviar AC", // add only 5400rpm/7200rpm (ata33 and faster)
"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]?.*",
"", "", ""
},
- { "Western Digital Caviar SE family",
+ { "Western Digital Caviar SE",
/* Western Digital drives with this comment all appear to use Attribute 9 in
* a non-standard manner. These entries may need to be updated when it
* is understood exactly how Attribute 9 should be interpreted.
"WDC WD(4|6|8|10|12|16|18|20|25|30|32|40|50)00(JB|PB)-.*",
"", "", ""
},
- { "Western Digital Caviar Blue EIDE family", // WD Caviar SE EIDE family
+ { "Western Digital Caviar Blue EIDE", // WD Caviar SE EIDE
/* not completely accurate: at least also WD800JB, WD(4|8|20|25)00BB sold as Caviar Blue */
"WDC WD(16|25|32|40|50)00AAJB-.*",
"", "", ""
},
- { "Western Digital Caviar Blue EIDE family", // WD Caviar SE16 EIDE family
+ { "Western Digital Caviar Blue EIDE", // WD Caviar SE16 EIDE
"WDC WD(25|32|40|50)00AAKB-.*",
"", "", ""
},
- { "Western Digital RE EIDE family",
+ { "Western Digital RE EIDE",
"WDC WD(12|16|25|32)00SB-.*",
"", "", ""
},
- { "Western Digital Caviar Serial ATA family",
+ { "Western Digital Caviar Serial ATA",
"WDC WD(4|8|20|32)00BD-.*",
"", "", ""
},
- { "Western Digital Caviar SE Serial ATA family",
+ { "Western Digital Caviar SE Serial ATA",
"WDC WD(4|8|12|16|20|25|32|40)00(JD|KD|PD)-.*",
"", "", ""
},
- { "Western Digital Caviar SE Serial ATA family",
+ { "Western Digital Caviar SE Serial ATA",
"WDC WD(8|12|16|20|25|30|32|40|50)00JS-.*",
"", "", ""
},
- { "Western Digital Caviar SE16 Serial ATA family",
+ { "Western Digital Caviar SE16 Serial ATA",
"WDC WD(16|20|25|32|40|50|75)00KS-.*",
"", "", ""
},
- { "Western Digital Caviar Blue Serial ATA family", // WD Caviar SE Serial ATA family
+ { "Western Digital Caviar Blue Serial ATA", // WD Caviar SE Serial ATA
/* not completely accurate: at least also WD800BD, (4|8)00JD sold as Caviar Blue */
"WDC WD((8|12|16|25|32)00AABS|(8|12|16|25|32|40|50)00AAJS)-.*",
"", "", ""
},
- { "Western Digital Caviar Blue Serial ATA family", // WD Caviar SE16 Serial ATA family
+ { "Western Digital Caviar Blue Serial ATA", // WD Caviar SE16 Serial ATA
"WDC WD((16|20|25|32|40|50|64|75)00AAKS|10EALS)-.*",
"", "", ""
},
- { "Western Digital Caviar Blue Serial ATA family", // SATA 3.0 variants
+ { "Western Digital Caviar Blue Serial ATA", // SATA 3.0 variants
"WDC WD((25|32|50)00AAKX|7500AALX|10EALX)-.*",
"", "", ""
},
- { "Western Digital RE Serial ATA family",
+ { "Western Digital RE Serial ATA",
"WDC WD(12|16|25|32)00(SD|YD|YS)-.*",
"", "", ""
},
- { "Western Digital RE2 Serial ATA family",
+ { "Western Digital RE2 Serial ATA",
"WDC WD((40|50|75)00(YR|YS|AYYS)|(16|32|40|50)0[01]ABYS)-.*",
"", "", ""
},
- { "Western Digital RE2-GP family",
+ { "Western Digital RE2-GP",
"WDC WD(5000AB|7500AY|1000FY)PS-.*",
"", "", ""
},
- { "Western Digital RE3 Serial ATA family",
+ { "Western Digital RE3 Serial ATA",
"WDC WD((25|32|50)02A|(75|10)02F)BYS-.*",
"", "", ""
},
- { "Western Digital Caviar Green family",
+ { "Western Digital RE4 Serial ATA",
+ "WDC WD((((25|50)03A|1003F)BYX)|((15|20)03FYYS))-.*",
+ "", "", ""
+ },
+ { "Western Digital Caviar Green",
"WDC WD((50|64|75)00AA(C|V)S|(50|64|75)00AADS|10EA(C|V)S|(10|15|20)EADS)-.*",
"", "", ""
},
- { "Western Digital Caviar Green (Adv. Format) family",
- "WDC WD((64|75|80)00AA|(10|15|20)EA|(25|30)EZ)RS-.*",
+ { "Western Digital Caviar Green (Adv. Format)",
+ "WDC WD(((64|75|80)00AA|(10|15|20)EA|(25|30)EZ)R|20EAC)S-.*",
"", "", ""
},
- { "Western Digital Caviar Black family",
+ { "Western Digital Caviar Black",
"WDC WD((500|640|750)1AAL|1001FA[EL]|2001FAS)S-.*",
"", "", ""
},
- { "Western Digital AV ATA family", // tested with WDC WD3200AVJB-63J5A0/01.03E01
+ { "Western Digital Caviar Black", // SATA 3.0 variants
+ "WDC WD(5002AAL|(64|75)02AAE|(10|15|20)02FAE)X-.*",
+ "", "", ""
+ },
+ { "Western Digital AV ATA", // tested with WDC WD3200AVJB-63J5A0/01.03E01
"WDC WD(8|16|25|32|50)00AV[BJ]B-.*",
"", "", ""
},
- { "Western Digital AV SATA family",
+ { "Western Digital AV SATA",
"WDC WD(16|25|32)00AVJS-.*",
"", "", ""
},
- { "Western Digital AV-GP family",
+ { "Western Digital AV-GP",
"WDC WD((16|25|32|50|64|75)00AVVS|(50|75)00AVCS|10EVVS|(10|20)EVCS|(10|15|20)EVDS)-.*",
"", "", ""
},
- { "Western Digital Raptor family",
+ { "Western Digital AV-25",
+ "WDC WD((16|25|32|50)00BUD|5000BUC)T-.*",
+ "", "", ""
+ },
+ { "Western Digital Raptor",
"WDC WD((360|740|800)GD|(360|740|800|1500)ADF[DS])-.*",
"", "", ""
},
"WDC WD1500AHFD-.*",
"", "", ""
},
- { "Western Digital VelociRaptor family",
+ { "Western Digital VelociRaptor",
"WDC WD(((800H|(1500|3000)[BH]|1600H|3000G)LFS)|((4500|6000)[BH]LHX))-.*",
"", "", ""
},
- { "Western Digital Scorpio EIDE family",
+ { "Western Digital Scorpio EIDE",
"WDC WD(4|6|8|10|12|16)00(UE|VE)-.*",
"", "", ""
},
"WDC WD(4|6|8|10|12|16|25|32)00BEVE-.*",
"", "", ""
},
- { "Western Digital Scorpio Serial ATA family",
+ { "Western Digital Scorpio Serial ATA",
"WDC WD(4|6|8|10|12|16|25)00BEAS-.*",
"", "", ""
},
- { "Western Digital Scorpio Blue Serial ATA family",
+ { "Western Digital Scorpio Blue Serial ATA",
"WDC WD((4|6|8|10|12|16|25)00BEVS|(8|12|16|25|32|40|50|64)00BEVT|7500KEVT|10TEVT)-.*",
"", "", ""
},
- { "Western Digital Scorpio Black Serial ATA family",
+ { "Western Digital Scorpio Blue Serial ATA (Adv. Format)",
+ "WDC WD((16|25|32|50|64|75)00BPVT|10TPVT)-.*",
+ "", "", ""
+ },
+ { "Western Digital Scorpio Black Serial ATA",
"WDC WD(8|12|16|25|32)00B[EJ]KT-.*",
"", "", ""
},
"WDC WD(3200BMVV|5000BMVW)-.*",
"", "", ""
},
- { "Quantum Bigfoot series", // tested with TS10.0A/A21.0G00, TS12.7A/A21.0F00
+ { "Quantum Bigfoot", // tested with TS10.0A/A21.0G00, TS12.7A/A21.0F00
"QUANTUM BIGFOOT TS(10\\.0|12\\.7)A",
"", "", ""
},
- { "Quantum Fireball lct15 series",
+ { "Quantum Fireball lct15",
"QUANTUM FIREBALLlct15 ([123]0|22)",
"", "", ""
},
- { "Quantum Fireball lct20 series",
- "QUANTUM FIREBALLlct20 [234]0",
+ { "Quantum Fireball lct20",
+ "QUANTUM FIREBALLlct20 [1234]0",
"", "", ""
},
- { "Quantum Fireball CX series",
+ { "Quantum Fireball CX",
"QUANTUM FIREBALL CX10.2A",
"", "", ""
},
- { "Quantum Fireball CR series",
+ { "Quantum Fireball CR",
"QUANTUM FIREBALL CR(4.3|6.4|8.4|13.0)A",
"", "", ""
},
- { "Quantum Fireball EX series",
+ { "Quantum Fireball EX",
"QUANTUM FIREBALL EX(3.2|6.4)A",
"", "", ""
},
- { "Quantum Fireball ST series",
+ { "Quantum Fireball ST",
"QUANTUM FIREBALL ST(3.2|4.3|4300)A",
"", "", ""
},
- { "Quantum Fireball SE series",
+ { "Quantum Fireball SE",
"QUANTUM FIREBALL SE4.3A",
"", "", ""
},
- { "Quantum Fireball Plus LM series",
+ { "Quantum Fireball Plus LM",
"QUANTUM FIREBALLP LM(10.2|15|20.[45]|30)",
"", "", ""
},
- { "Quantum Fireball Plus AS series",
- "QUANTUM FIREBALLP AS(10.2|20.5|30.0|40.0)",
+ { "Quantum Fireball Plus AS",
+ "QUANTUM FIREBALLP AS(10.2|20.5|30.0|40.0|60.0)",
"", "", ""
},
- { "Quantum Fireball Plus KX series",
+ { "Quantum Fireball Plus KX",
"QUANTUM FIREBALLP KX27.3",
"", "", ""
},
- { "Quantum Fireball Plus KA series",
+ { "Quantum Fireball Plus KA",
"QUANTUM FIREBALLP KA(9|10).1",
"", "", ""
},
"",
"-d usbjmicron"
},
+ { "USB: Samsung S1 Portable; JMicron",
+ "0x04e8:0x2f03",
+ "",
+ "",
+ "-d usbjmicron"
+ },
{ "USB: Samsung Story Station; ",
"0x04e8:0x5f06",
"",
"",
"-d usbjmicron,x"
},
+ { "USB: LaCie Little Disk USB2; JMicron",
+ "0x059f:0x1021",
+ "",
+ "",
+ "-d usbjmicron"
+ },
+ { "USB: LaCie hard disk; ",
+ "0x059f:0x1029",
+ "", // 0x0100
+ "",
+ "-d sat"
+ },
{ "USB: Lacie rikiki; JMicron",
"0x059f:0x102a",
"",
"",
"-d usbjmicron,x"
},
+ { "USB: LaCie rikiki USB 3.0; ",
+ "0x059f:0x1049",
+ "",
+ "",
+ "-d sat"
+ },
// In-System Design
{ "USB: ; In-System/Cypress ISD-300A1",
"0x05ab:0x0060",
"",
"-d usbsunplus"
},
+ // Oxford Semiconductor, Ltd
+ { "USB: ; Oxford OXU921DS",
+ "0x0928:0x0002",
+ "",
+ "",
+ "" // unsupported
+ },
{ "USB: Toshiba PX1396E-3T01; Sunplus", // similar to Dura Micro 501
"0x0930:0x0b09",
"",
"",
"-d usbsunplus"
},
- { "USB: Toshiba Stor.E Steel series; Sunplus",
+ { "USB: Toshiba Stor.E Steel; Sunplus",
"0x0930:0x0b11",
"",
"",
"",
"-d sat"
},
- { "USB: Seagate FreeAgent Go Flex; ",
+ { "USB: Seagate Expansion External; ", // 2TB
+ "0x0bc2:0x3300",
+ "",
+ "",
+ "-d sat"
+ },
+ { "USB: Seagate FreeAgent GoFlex USB 2.0; ",
"0x0bc2:0x5021",
"",
"",
"-d sat"
},
- { "USB: Seagate FreeAgent Go Flex Desk USB 3.0; ",
+ { "USB: Seagate FreeAgent GoFlex USB 3.0; ",
+ "0x0bc2:0x5031",
+ "",
+ "",
+ "-d sat,12"
+ },
+ { "USB: Seagate FreeAgent GoFlex Desk USB 3.0; ",
"0x0bc2:0x50a1",
"",
"",
"-d usbsunplus"
},
// Maxtor
+ { "USB: Maxtor OneTouch 200GB; ",
+ "0x0d49:0x7010",
+ "",
+ "",
+ "" // unsupported
+ },
{ "USB: Maxtor OneTouch; ",
"0x0d49:0x7300",
"", // 0x0121
"",
"-d sat"
},
+ // Cowon Systems, Inc.
+ { "USB: Cowon iAudio X5; ",
+ "0x0e21:0x0510",
+ "",
+ "",
+ "-d usbcypress"
+ },
// iRiver
{ "USB: iRiver iHP-120/140 MP3 Player; Cypress",
"0x1006:0x3002",
"",
"-d sat"
},
+ { "USB: WD My Book Office Edition; ", // 1TB
+ "0x1058:0x1101",
+ "", // 0x0165
+ "",
+ "-d sat"
+ },
{ "USB: WD My Book; ",
"0x1058:0x1102",
"", // 0x1028
"-d usbcypress"
},
// JMicron
+ { "USB: ; JMicron USB 3.0",
+ "0x152d:0x0539",
+ "", // 0x0100
+ "",
+ "-d usbjmicron"
+ },
{ "USB: ; JMicron ", // USB->SATA->4xSATA (port multiplier)
"0x152d:0x0551",
"", // 0x0100
"",
"-d sat"
},
+ { "USB: ; ASMedia USB 3.0", // BYTECC T-200U3
+ "0x174c:0x55aa",
+ "",
+ "",
+ "" // unsupported
+ },
// LucidPort
{ "USB: RaidSonic ICY BOX IB-110StU3-B; LucidPORT USB300",
"0x1759:0x500[02]",
"",
"-d usbsunplus"
},
+ { "USB: Verbatim Pocket Hard Drive; JMicron", // SAMSUNG SpinPoint N3U-3 (USB, 4KiB LLS)
+ "0x18a5:0x0227",
+ "",
+ "",
+ "-d usbjmicron" // "-d usbjmicron,x" does not work
+ },
// Silicon Image
{ "USB: Vantec NST-400MX-SR; Silicon Image 5744",
"0x1a4a:0x1670",
#include <stdexcept>
-const char * knowndrives_cpp_cvsid = "$Id: knowndrives.cpp 3289 2011-03-09 19:52:04Z chrfranke $"
+const char * knowndrives_cpp_cvsid = "$Id: knowndrives.cpp 3343 2011-05-25 20:18:17Z chrfranke $"
KNOWNDRIVES_H_CVSID;
#define MODEL_STRING_LENGTH 40
i += strspn(presets+i, " \t");
if (!presets[i])
break;
- char opt, arg[40+1+13]; int len = -1;
- if (!(sscanf(presets+i, "-%c %40[^ ]%n", &opt, arg, &len) >= 2 && len > 0))
+ char opt, arg[80+1+13]; int len = -1;
+ if (!(sscanf(presets+i, "-%c %80[^ ]%n", &opt, arg, &len) >= 2 && len > 0))
return false;
if (opt == 'v' && defs) {
// Parse "-v N,format[,name]"
#define PATHINQ_SETTINGS_SIZE 128
#endif
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3264 2011-02-21 15:52:04Z chrfranke $" \
+const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3335 2011-05-21 17:32:16Z samm2 $" \
ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
#define NO_RETURN 0
ccb.cdm.match_buf_len = bufsize;
// TODO: Use local buffer instead of malloc() if possible
ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
+ bzero(ccb.cdm.matches,bufsize); // clear ccb.cdm.matches structure
+
if (ccb.cdm.matches == NULL) {
close(fd);
throw std::bad_alloc();
ata_device * atadev = get_ata_device(atanames[i], type);
if (atadev)
devlist.push_back(atadev);
+ free(atanames[i]);
}
+ if(numata) free(atanames);
for (i = 0; i < (int)scsinames.size(); i++) {
if(!*type) { // try USB autodetection if no type specified
struct cam_device *cam_dev;
union ccb ccb;
int bus=-1;
- int i;
+ int i,c;
int len;
// if dev_name null, or string length zero
// check ATA/ATAPI devices
for (i = 0; i < numata; i++) {
if(!strcmp(atanames[i],name)) {
+ for (c = i; c < numata; c++) free(atanames[c]);
+ free(atanames);
return new freebsd_ata_device(this, name, "");
}
+ else free(atanames[i]);
}
+ if(numata) free(atanames);
}
else {
if (numata < 0)
#define ARGUSED(x) ((void)(x))
-const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3293 2011-03-09 21:55:15Z chrfranke $"
+const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3317 2011-04-19 19:42:54Z chrfranke $"
OS_LINUX_H_CVSID;
std::string linux_smart_interface::get_os_version_str()
{
struct utsname u;
- return strprintf("%s-%s", SMARTMONTOOLS_BUILD_HOST,
- (!uname(&u) ? u.release : "?"));
+ if (!uname(&u))
+ return strprintf("%s-linux-%s", u.machine, u.release);
+ else
+ return SMARTMONTOOLS_BUILD_HOST;
}
std::string linux_smart_interface::get_app_examples(const char * appname)
#define SELECT_WIN_32_64(x32, x64) (x64)
#endif
-const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3292 2011-03-09 21:12:03Z chrfranke $";
+const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3358 2011-06-06 19:04:20Z chrfranke $";
// Disable Win9x/ME specific code if no longer supported by compiler.
#ifdef _WIN64
bool m_usr_options; // options set by user?
bool m_admin; // open with admin access?
bool m_id_is_cached; // ata_identify_is_cached() return value.
+ bool m_is_3ware; // AMCC/3ware controller detected?
int m_drive, m_port;
int m_smartver_state;
};
if (data.desc.ProductIdOffset) {
while (i > 1 && model[i-2] == ' ') // Keep last blank from VendorId
i--;
+ // Ignore VendorId "ATA"
+ if (i <= 4 && !strncmp(model, "ATA", 3) && (i == 3 || model[3] == ' '))
+ i = 0;
for (unsigned j = 0; i < sizeof(model)-1 && data.raw[data.desc.ProductIdOffset+j]; i++, j++)
model[i] = data.raw[data.desc.ProductIdOffset+j];
}
m_usr_options(false),
m_admin(false),
m_id_is_cached(false),
+ m_is_3ware(false),
m_drive(0),
m_port(-1),
m_smartver_state(0)
// Win9X/ME: Get drive map
// RAID: Get port map
GETVERSIONINPARAMS_EX vers_ex;
- int devmap = smart_get_version(h, (port >= 0 ? &vers_ex : 0));
+ int devmap = smart_get_version(h, &vers_ex);
+
+ // 3ware RAID if vendor id present
+ m_is_3ware = (vers_ex.wIdentifier == SMART_VENDOR_3WARE);
unsigned long portmap = 0;
if (port >= 0 && devmap >= 0) {
// 3ware RAID: check vendor id
- if (vers_ex.wIdentifier != SMART_VENDOR_3WARE) {
- pout("SMART_GET_VERSION returns unknown Identifier = %04x\n"
+ if (!m_is_3ware) {
+ pout("SMART_GET_VERSION returns unknown Identifier = 0x%04x\n"
"This is no 3ware 9000 controller or driver has no SMART support.\n",
vers_ex.wIdentifier);
devmap = -1;
)
return false;
+ // 3ware RAID: SMART DISABLE without port number disables SMART functions
+ if ( m_is_3ware && m_port < 0
+ && in.in_regs.command == ATA_SMART_CMD
+ && in.in_regs.features == ATA_SMART_DISABLE)
+ return set_err(ENOSYS, "SMART DISABLE requires 3ware port number");
+
// Determine ioctl functions valid for this ATA cmd
const char * valid_options = 0;
}
if (!m_smartver_state) {
assert(m_port == -1);
- if (smart_get_version(get_fh()) < 0) {
+ GETVERSIONINPARAMS_EX vers_ex;
+ if (smart_get_version(get_fh(), &vers_ex) < 0) {
if (!failuretest_permissive) {
m_smartver_state = 2;
rc = -1; errno = ENOSYS;
}
failuretest_permissive--;
}
+ else {
+ // 3ware RAID if vendor id present
+ m_is_3ware = (vers_ex.wIdentifier == SMART_VENDOR_3WARE);
+ }
+
m_smartver_state = 1;
}
rc = smart_ioctl(get_fh(), m_drive, ®s, data, datasize, m_port);
memcpy(iop->sensep, sb.ucSenseBuf, slen);
iop->resp_sense_len = slen;
if (report) {
+ if (report > 1) {
+ pout(" >>> Sense buffer, len=%d:\n", slen);
+ dStrHex(iop->sensep, slen , 1);
+ }
if ((iop->sensep[0] & 0x7f) > 0x71)
pout(" status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
iop->scsi_status, iop->sensep[1] & 0xf,
; You should have received a copy of the GNU General Public License
; (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
;
-; $Id: installer.nsi 3296 2011-03-16 22:17:51Z chrfranke $
+; $Id: installer.nsi 3298 2011-03-22 18:36:44Z chrfranke $
;
LicenseData "${INPDIR}\doc\COPYING.txt"
+!include "FileFunc.nsh"
+!include "Sections.nsh"
+
+!insertmacro GetParameters
+!insertmacro GetOptions
+
+RequestExecutionLevel admin
+
;--------------------------------------------------------------------
; Pages
SectionIn 1
+ SetShellVarContext all
+
CreateDirectory "$SMPROGRAMS\smartmontools"
; smartctl
DeleteRegKey HKCR "Drive\shell\smartctl5"
!macroend
- Section "Remove existing entries first"
+ Section "Remove existing entries first" DRIVE_REMOVE_SECTION
SectionIn 3
!insertmacro DriveMenuRemove
SectionEnd
Delete "$INSTDIR\uninst-smartmontools.exe"
; Remove shortcuts
+ SetShellVarContext all
Delete "$SMPROGRAMS\smartmontools\*.*"
Delete "$SMPROGRAMS\smartmontools\Documentation\*.*"
Delete "$SMPROGRAMS\smartmontools\smartctl Examples\*.*"
IfFileExists "$WINDIR\system32\cmd.exe" +2 0
SectionSetText ${PATH_SECTION} ""
+ Call ParseCmdLine
+FunctionEnd
+
+; Command line parsing
+!macro CheckCmdLineOption name section
+ StrCpy $allopts "$allopts,${name}"
+ Push ",$opts,"
+ Push ",${name},"
+ Call StrStr
+ Pop $0
+ StrCmp $0 "" 0 sel_${name}
+ !insertmacro UnselectSection ${section}
+ Goto done_${name}
+sel_${name}:
+ !insertmacro SelectSection ${section}
+ StrCpy $nomatch ""
+done_${name}:
+!macroend
+
+Function ParseCmdLine
+ ; get /SO option
+ Var /global opts
+ ${GetParameters} $R0
+ ${GetOptions} $R0 "/SO" $opts
+ IfErrors 0 +2
+ Return
+ Var /global allopts
+ StrCpy $allopts ""
+ Var /global nomatch
+ StrCpy $nomatch "t"
+ ; turn sections on or off
+ !insertmacro CheckCmdLineOption "smartctl" ${SMARTCTL_SECTION}
+ !insertmacro CheckCmdLineOption "smartd" ${SMARTD_SECTION}
+ !insertmacro CheckCmdLineOption "smartctlnc" ${SMARTCTL_NC_SECTION}
+ !insertmacro CheckCmdLineOption "drivedb" ${DRIVEDB_SECTION}
+ !insertmacro CheckCmdLineOption "doc" ${DOC_SECTION}
+ !insertmacro CheckCmdLineOption "uninst" ${UNINST_SECTION}
+ !insertmacro CheckCmdLineOption "menu" ${MENU_SECTION}
+ !insertmacro CheckCmdLineOption "path" ${PATH_SECTION}
+ !insertmacro CheckCmdLineOption "driveremove" ${DRIVE_REMOVE_SECTION}
+ !insertmacro CheckCmdLineOption "drive0" ${DRIVE_0_SECTION}
+ !insertmacro CheckCmdLineOption "drive1" ${DRIVE_1_SECTION}
+ !insertmacro CheckCmdLineOption "drive2" ${DRIVE_2_SECTION}
+ !insertmacro CheckCmdLineOption "drive3" ${DRIVE_3_SECTION}
+ !insertmacro CheckCmdLineOption "drive4" ${DRIVE_4_SECTION}
+ !insertmacro CheckCmdLineOption "drive5" ${DRIVE_5_SECTION}
+ !insertmacro CheckCmdLineOption "ubcd" ${UBCD_SECTION}
+ StrCmp $opts "-" done
+ StrCmp $nomatch "" done
+ StrCpy $0 "$allopts,-" "" 1
+ MessageBox MB_OK "Usage: smartmontools-VERSION.win32-setup [/S] [/SO component,...] [/D=INSTDIR]$\n$\ncomponents:$\n $0"
+ Abort
+done:
FunctionEnd
; Directory page callbacks
#include "dev_interface.h"
#include "utility.h"
-const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3258 2011-02-14 22:31:01Z manfred99 $"
+const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3302 2011-03-25 23:04:36Z dpgilbert $"
SCSICMDS_H_CVSID;
// Print SCSI debug messages?
struct scsi_opcode_name * onp;
if (opcode >= 0xc0)
- return vendor_specific;
+ return vendor_specific;
for (k = 0; k < len; ++k) {
onp = &opcode_name_arr[k];
if (opcode == onp->opcode)
}
}
+/* Iterates to next designation descriptor in the device identification
+ * VPD page. The 'initial_desig_desc' should point to start of first
+ * descriptor with 'page_len' being the number of valid bytes in that
+ * and following descriptors. To start, 'off' should point to a negative
+ * value, thereafter it should point to the value yielded by the previous
+ * call. If 0 returned then 'initial_desig_desc + *off' should be a valid
+ * descriptor; returns -1 if normal end condition and -2 for an abnormal
+ * termination. Matches association, designator_type and/or code_set when
+ * any of those values are greater than or equal to zero. */
+int scsi_vpd_dev_id_iter(const unsigned char * initial_desig_desc,
+ int page_len, int * off, int m_assoc,
+ int m_desig_type, int m_code_set)
+{
+ const unsigned char * ucp;
+ int k, c_set, assoc, desig_type;
+
+ for (k = *off, ucp = initial_desig_desc ; (k + 3) < page_len; ) {
+ k = (k < 0) ? 0 : (k + ucp[k + 3] + 4);
+ if ((k + 4) > page_len)
+ break;
+ c_set = (ucp[k] & 0xf);
+ if ((m_code_set >= 0) && (m_code_set != c_set))
+ continue;
+ assoc = ((ucp[k + 1] >> 4) & 0x3);
+ if ((m_assoc >= 0) && (m_assoc != assoc))
+ continue;
+ desig_type = (ucp[k + 1] & 0xf);
+ if ((m_desig_type >= 0) && (m_desig_type != desig_type))
+ continue;
+ *off = k;
+ return 0;
+ }
+ return (k == page_len) ? -1 : -2;
+}
+
+/* Decode VPD page 0x83 logical unit designator into a string. If both
+ * numeric address and SCSI name string present, prefer the former.
+ * Returns 0 on success, -1 on error with error string in s. */
+int scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s,
+ int slen, int * transport)
+{
+ int m, c_set, assoc, desig_type, i_len, naa, off, u, have_scsi_ns;
+ const unsigned char * ucp;
+ const unsigned char * ip;
+ char * orig_s = s;
+
+ if (transport)
+ *transport = -1;
+ if (slen < 32) {
+ if (slen > 0)
+ s[0] = '\0';
+ return -1;
+ }
+ have_scsi_ns = 0;
+ s[0] = '\0';
+ off = -1;
+ while ((u = scsi_vpd_dev_id_iter(b, blen, &off, -1, -1, -1)) == 0) {
+ ucp = b + off;
+ i_len = ucp[3];
+ if ((off + i_len + 4) > blen) {
+ s += sprintf(s, "error: designator length");
+ return -1;
+ }
+ assoc = ((ucp[1] >> 4) & 0x3);
+ if (transport && assoc && (ucp[1] & 0x80) && (*transport < 0))
+ *transport = (ucp[0] >> 4) & 0xf;
+ if (0 != assoc)
+ continue;
+ ip = ucp + 4;
+ c_set = (ucp[0] & 0xf);
+ desig_type = (ucp[1] & 0xf);
+
+ switch (desig_type) {
+ case 0: /* vendor specific */
+ case 1: /* T10 vendor identification */
+ break;
+ case 2: /* EUI-64 based */
+ if ((8 != i_len) && (12 != i_len) && (16 != i_len)) {
+ s += sprintf(s, "error: EUI-64 length");
+ return -1;
+ }
+ if (have_scsi_ns)
+ s = orig_s;
+ s += sprintf(s, "0x");
+ for (m = 0; m < i_len; ++m)
+ s += sprintf(s, "%02x", (unsigned int)ip[m]);
+ break;
+ case 3: /* NAA */
+ if (1 != c_set) {
+ s += sprintf(s, "error: NAA bad code_set");
+ return -1;
+ }
+ naa = (ip[0] >> 4) & 0xff;
+ if ((naa < 2) || (naa > 6) || (4 == naa)) {
+ s += sprintf(s, "error: unexpected NAA");
+ return -1;
+ }
+ if (have_scsi_ns)
+ s = orig_s;
+ if (2 == naa) { /* NAA IEEE Extended */
+ if (8 != i_len) {
+ s += sprintf(s, "error: NAA 2 length");
+ return -1;
+ }
+ s += sprintf(s, "0x");
+ for (m = 0; m < 8; ++m)
+ s += sprintf(s, "%02x", (unsigned int)ip[m]);
+ } else if ((3 == naa ) || (5 == naa)) {
+ /* NAA=3 Locally assigned; NAA=5 IEEE Registered */
+ if (8 != i_len) {
+ s += sprintf(s, "error: NAA 3 or 5 length");
+ return -1;
+ }
+ s += sprintf(s, "0x");
+ for (m = 0; m < 8; ++m)
+ s += sprintf(s, "%02x", (unsigned int)ip[m]);
+ } else if (6 == naa) { /* NAA IEEE Registered extended */
+ if (16 != i_len) {
+ s += sprintf(s, "error: NAA 6 length");
+ return -1;
+ }
+ s += sprintf(s, "0x");
+ for (m = 0; m < 16; ++m)
+ s += sprintf(s, "%02x", (unsigned int)ip[m]);
+ }
+ break;
+ case 4: /* Relative target port */
+ case 5: /* (primary) Target port group */
+ case 6: /* Logical unit group */
+ case 7: /* MD5 logical unit identifier */
+ break;
+ case 8: /* SCSI name string */
+ if (3 != c_set) {
+ s += sprintf(s, "error: SCSI name string");
+ return -1;
+ }
+ /* does %s print out UTF-8 ok?? */
+ if (orig_s == s) {
+ s += sprintf(s, "%s", (const char *)ip);
+ ++have_scsi_ns;
+ }
+ break;
+ default: /* reserved */
+ break;
+ }
+ }
+ if (-2 == u) {
+ s += sprintf(s, "error: bad structure");
+ return -1;
+ }
+ return 0;
+}
+
/* Sends LOG SENSE command. Returns 0 if ok, 1 if device NOT READY, 2 if
command not supported, 3 if field (within command) not supported or
returns negated errno. SPC-3 sections 6.6 and 7.2 (rec 22a).
return scsiSimpleSenseFilter(&sinfo);
}
+/* READ CAPACITY (10) command. Returns 0 if ok, 1 if NOT READY, 2 if
+ * command not supported, 3 if field in command not supported or returns
+ * negated errno. SBC-3 section 5.15 (rev 26) */
+int scsiReadCapacity10(scsi_device * device, unsigned int * last_lbap,
+ unsigned int * lb_sizep)
+{
+ int res;
+ struct scsi_cmnd_io io_hdr;
+ struct scsi_sense_disect sinfo;
+ UINT8 cdb[10];
+ UINT8 sense[32];
+ UINT8 resp[8];
+
+ memset(&io_hdr, 0, sizeof(io_hdr));
+ memset(cdb, 0, sizeof(cdb));
+ memset(resp, 0, sizeof(resp));
+ io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
+ io_hdr.dxfer_len = sizeof(resp);
+ io_hdr.dxferp = resp;
+ cdb[0] = READ_CAPACITY_10;
+ io_hdr.cmnd = cdb;
+ io_hdr.cmnd_len = sizeof(cdb);
+ io_hdr.sensep = sense;
+ io_hdr.max_sense_len = sizeof(sense);
+ io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
+
+ if (!device->scsi_pass_through(&io_hdr))
+ return -device->get_errno();
+ scsi_do_sense_disect(&io_hdr, &sinfo);
+ res = scsiSimpleSenseFilter(&sinfo);
+ if (res)
+ return res;
+ if (last_lbap)
+ *last_lbap = (resp[0] << 24) | (resp[1] << 16) | (resp[2] << 8) |
+ resp[3];
+ if (lb_sizep)
+ *lb_sizep = (resp[4] << 24) | (resp[5] << 16) | (resp[6] << 8) |
+ resp[7];
+ return 0;
+}
+
+/* READ CAPACITY (16) command. The bufLen argument should be 32. Returns 0
+ * if ok, 1 if NOT READY, 2 if command not supported, 3 if field in command
+ * not supported or returns negated errno. SBC-3 section 5.16 (rev 26) */
+int scsiReadCapacity16(scsi_device * device, UINT8 *pBuf, int bufLen)
+{
+ struct scsi_cmnd_io io_hdr;
+ struct scsi_sense_disect sinfo;
+ UINT8 cdb[16];
+ UINT8 sense[32];
+
+ memset(&io_hdr, 0, sizeof(io_hdr));
+ memset(cdb, 0, sizeof(cdb));
+ io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
+ io_hdr.dxfer_len = bufLen;
+ io_hdr.dxferp = pBuf;
+ cdb[0] = READ_CAPACITY_16;
+ cdb[1] = SAI_READ_CAPACITY_16;
+ cdb[10] = (bufLen >> 24) & 0xff;
+ cdb[11] = (bufLen >> 16) & 0xff;
+ cdb[12] = (bufLen >> 8) & 0xff;
+ cdb[13] = bufLen & 0xff;
+ io_hdr.cmnd = cdb;
+ io_hdr.cmnd_len = sizeof(cdb);
+ io_hdr.sensep = sense;
+ io_hdr.max_sense_len = sizeof(sense);
+ io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
+
+ if (!device->scsi_pass_through(&io_hdr))
+ return -device->get_errno();
+ scsi_do_sense_disect(&io_hdr, &sinfo);
+ return scsiSimpleSenseFilter(&sinfo);
+}
+
+/* Return number of bytes of storage in 'device' or 0 if error. If
+ * successful and lb_sizep is not NULL then the logical block size
+ * in bytes is written to the location pointed to by lb_sizep. */
+uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep)
+{
+ unsigned int last_lba, lb_size;
+ int k, res;
+ uint64_t ret_val = 0;
+ UINT8 rc16resp[32];
+
+ res = scsiReadCapacity10(device, &last_lba, &lb_size);
+ if (res) {
+ if (scsi_debugmode)
+ pout("scsiGetSize: READ CAPACITY(10) failed, res=%d\n", res);
+ return ret_val;
+ }
+ if (0xffffffff == last_lba) {
+ res = scsiReadCapacity16(device, rc16resp, sizeof(rc16resp));
+ if (res) {
+ if (scsi_debugmode)
+ pout("scsiGetSize: READ CAPACITY(16) failed, res=%d\n", res);
+ return ret_val;
+ }
+ for (k = 0; k < 8; ++k) {
+ if (k > 0)
+ ret_val <<= 8;
+ ret_val |= rc16resp[k + 0];
+ }
+ } else
+ ret_val = last_lba;
+ if (lb_sizep)
+ *lb_sizep = lb_size;
+ ++ret_val; /* last_lba is origin 0 so need to bump to get number of */
+ return ret_val * lb_size;
+}
+
+
/* Offset into mode sense (6 or 10 byte) response that actual mode page
* starts at (relative to resp[0]). Returns -1 if problem */
int scsiModePageOffset(const UINT8 * resp, int len, int modese_len)
#ifndef SCSICMDS_H_
#define SCSICMDS_H_
-#define SCSICMDS_H_CVSID "$Id: scsicmds.h 3258 2011-02-14 22:31:01Z manfred99 $\n"
+#define SCSICMDS_H_CVSID "$Id: scsicmds.h 3302 2011-03-25 23:04:36Z dpgilbert $\n"
#include <stdio.h>
#include <stdlib.h>
#define READ_CAPACITY_10 0x25
#endif
#ifndef READ_CAPACITY_16
-#define READ_CAPACITY_16 0x9e /* service action 0x10 */
+#define READ_CAPACITY_16 0x9e
+#endif
+#ifndef SAI_READ_CAPACITY_16 /* service action for READ_CAPACITY_16 */
+#define SAI_READ_CAPACITY_16 0x10
#endif
#ifndef SAT_ATA_PASSTHROUGH_12
const char * scsiErrString(int scsiErr);
+int scsi_vpd_dev_id_iter(const unsigned char * initial_desig_desc,
+ int page_len, int * off, int m_assoc,
+ int m_desig_type, int m_code_set);
+
+int scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s,
+ int slen, int * transport);
+
+
/* STANDARD SCSI Commands */
int scsiTestUnitReady(scsi_device * device);
int scsiReadDefect10(scsi_device * device, int req_plist, int req_glist, int dl_format,
UINT8 *pBuf, int bufLen);
+int scsiReadCapacity10(scsi_device * device, unsigned int * last_lbp,
+ unsigned int * lb_sizep);
+
+int scsiReadCapacity16(scsi_device * device, UINT8 *pBuf, int bufLen);
+
+uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep);
+
+
/* SMART specific commands */
int scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage, UINT8 *asc,
UINT8 *ascq, UINT8 *currenttemp, UINT8 *triptemp);
int scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len);
int scsiFetchTransportProtocol(scsi_device * device, int modese_len);
-/* T10 Standard IE Additional Sense Code strings taken from t10.org */
+/* T10 Standard IE Additional Sense Code strings taken from t10.org */
const char* scsiGetIEString(UINT8 asc, UINT8 ascq);
int scsiGetTemp(scsi_device * device, UINT8 *currenttemp, UINT8 *triptemp);
#define GBUF_SIZE 65535
-const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3256 2011-02-08 22:13:41Z chrfranke $"
+const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3307 2011-03-31 14:54:58Z dpgilbert $"
SCSIPRINT_H_CVSID;
/* Returns 0 on success, 1 on general error and 2 for early, clean exit */
static int scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
{
- char manufacturer[9];
- char product[17];
- char revision[5];
char timedatetz[DATEANDEPOCHLEN];
struct scsi_iec_mode_page iec;
- int err, iec_err, len, req_len, avail_len, val;
+ int err, iec_err, len, req_len, avail_len;
int is_tape = 0;
int peri_dt = 0;
- int returnval=0;
+ int returnval = 0;
+ int transport = -1;
memset(gBuf, 0, 96);
req_len = 36;
print_off();
return 1;
}
- memset(manufacturer, 0, sizeof(manufacturer));
- strncpy(manufacturer, (char *)&gBuf[8], 8);
-
- memset(product, 0, sizeof(product));
- strncpy(product, (char *)&gBuf[16], 16);
-
- memset(revision, 0, sizeof(revision));
- strncpy(revision, (char *)&gBuf[32], 4);
- if (all && (0 != strncmp(manufacturer, "ATA", 3)))
- pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
+ if (all && (0 != strncmp((char *)&gBuf[8], "ATA", 3))) {
+ pout("Vendor: %.8s\n", (char *)&gBuf[8]);
+ pout("Product: %.16s\n", (char *)&gBuf[16]);
+ if (gBuf[32] >= ' ')
+ pout("Revision: %.4s\n", (char *)&gBuf[32]);
+ }
if (!*device->get_req_type()/*no type requested*/ &&
- (0 == strncmp(manufacturer, "ATA", 3))) {
+ (0 == strncmp((char *)&gBuf[8], "ATA", 3))) {
pout("\nProbable ATA device behind a SAT layer\n"
"Try an additional '-d ata' or '-d sat' argument.\n");
return 2;
if (! all)
return 0;
+ unsigned int lb_size;
+ char cap_str[64];
+ char si_str[64];
+ char lb_str[16];
+ uint64_t capacity = scsiGetSize(device, &lb_size);
+
+ if (capacity) {
+ format_with_thousands_sep(cap_str, sizeof(cap_str), capacity);
+ format_capacity(si_str, sizeof(si_str), capacity);
+ pout("User Capacity: %s bytes [%s]\n", cap_str, si_str);
+ snprintf(lb_str, sizeof(lb_str) - 1, "%u", lb_size);
+ pout("Logical block size: %s bytes\n", lb_str);
+ }
+
/* Do this here to try and detect badly conforming devices (some USB
keys) that will lock up on a InquiryVpd or log sense or ... */
if ((iec_err = scsiFetchIECmpage(device, &iec, modese_len))) {
} else
modese_len = iec.modese_len;
- if (!dont_print_serial_number) {
- if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
- /* should use VPD page 0x83 and fall back to this page (0x80)
- * if 0x83 not supported. NAA requires a lot of decoding code */
+ if (! dont_print_serial_number) {
+ if (0 == (err = scsiInquiryVpd(device, 0x83, gBuf, 200))) {
+ char s[256];
+
len = gBuf[3];
- gBuf[4 + len] = '\0';
- pout("Serial number: %s\n", &gBuf[4]);
+ scsi_decode_lu_dev_id(gBuf + 4, len, s, sizeof(s), &transport);
+ if (strlen(s) > 0)
+ pout("Logical Unit id: %s\n", s);
+ } else if (scsi_debugmode > 0) {
+ print_on();
+ if (SIMPLE_ERR_BAD_RESP == err)
+ pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
+ else
+ pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
+ print_off();
}
- else if (scsi_debugmode > 0) {
+ if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
+ len = gBuf[3];
+ gBuf[4 + len] = '\0';
+ pout("Serial number: %s\n", &gBuf[4]);
+ } else if (scsi_debugmode > 0) {
print_on();
if (SIMPLE_ERR_BAD_RESP == err)
pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
// print SCSI peripheral device type
if (peri_dt < (int)(sizeof(peripheral_dt_arr) /
sizeof(peripheral_dt_arr[0])))
- pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
+ pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
else
- pout("Device type: <%d>\n", peri_dt);
+ pout("Device type: <%d>\n", peri_dt);
// See if transport protocol is known
- val = scsiFetchTransportProtocol(device, modese_len);
- if ((val >= 0) && (val <= 0xf))
- pout("Transport protocol: %s\n", transport_proto_arr[val]);
+ if (transport < 0)
+ transport = scsiFetchTransportProtocol(device, modese_len);
+ if ((transport >= 0) && (transport <= 0xf))
+ pout("Transport protocol: %s\n", transport_proto_arr[transport]);
// print current time and date and timezone
dateandtimezone(timedatetz);
- pout("Local Time is: %s\n", timedatetz);
+ pout("Local Time is: %s\n", timedatetz);
if ((SCSI_PT_SEQUENTIAL_ACCESS == *peripheral_type) ||
(SCSI_PT_MEDIUM_CHANGER == *peripheral_type))
.ig
Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- $Id: smartctl.8.in 3283 2011-03-04 20:13:57Z chrfranke $
+ $Id: smartctl.8.in 3320 2011-04-30 20:44:55Z chrfranke $
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Prints all SMART and non-SMART information about the device. For ATA
devices this is equivalent to
.nf
-\'\-H \-i \-c \-A \-l xerror,error \-l xselftest,selftest \-l selective
-\-l directory \-l scttemp \-l scterc \-l sataphy\'.
+\'\-H \-i \-c \-A \-f brief \-l xerror,error \-l xselftest,selftest
+\-l selective \-l directory \-l scttemp \-l scterc \-l sataphy\'.
.fi
and for SCSI, this is equivalent to
.nf
attributes are listed if recognised. The attributes are output in a
relatively free format (compared with ATA disk attributes).
.TP
+.B \-f FORMAT, \-\-format=FORMAT
+[ATA only] Selects the output format of the attributes to one of:
+
+.I old
+\- Old smartctl format. This is the default unless the \'\-x\' option is
+specified.
+
+.I brief
+\- New format which fits into 80 colums (except in some rare cases).
+This format also decodes four additional attribute flags.
+This is the default if the '\-x\' option is specified.
+.TP
.B \-l TYPE, \-\-log=TYPE
Prints either the SMART Error Log, the SMART Self\-Test Log, the SMART
Selective Self\-Test Log [ATA only], the Log Directory [ATA only], or
.I vendor,N
\- [ATA only] issues the ATA command SMART EXECUTE OFF-LINE IMMEDIATE
with subcommand N in LBA LOW register. The subcommand is specified as
-a hex value in the range 0x00 to 0xff. Subcommands 0x40-0x7f and
+a hex value in the range 0x00 to 0xff. Subcommands 0x40-0x7e and
0x90-0xff are reserved for vendor specific use, see table 61 of
-T13/1699-D Revision 6a (ATA8-ACS).
+T13/1699-D Revision 6a (ATA8-ACS). Note that the subcommands
+0x00-0x04,0x7f,0x81-0x84 are supported by other smartctl options
+(e.g. 0x01: \'\-t short\', 0x7f: \'\-X\', 0x82: \'\-C \-t long\').
\fBWARNING: Only run subcommands documented by the vendor of the
device.\fP
-Example for Intel X18\-M/X25\-M G2 SSDs only: The subcommand 0x40
-(\'\-t vendor,0x40\') clears the timed workload related SMART
-attributes (226, 227, 228).
+Example for Intel (X18\-M/X25\-M G2 and 320 Series) SSDs only:
+The subcommand 0x40 (\'\-t vendor,0x40\') clears the timed workload
+related SMART attributes (226, 227, 228). Note that the raw values of
+these attributes are held at 65535 (0xffff) until the workload timer
+reaches 60 minutes.
.TP
.B \-C, \-\-captive
[ATA] Runs self\-tests in captive mode. This has no effect with \'\-t
.SH
SVN ID OF THIS PAGE:
-$Id: smartctl.8.in 3283 2011-03-04 20:13:57Z chrfranke $
+$Id: smartctl.8.in 3320 2011-04-30 20:44:55Z chrfranke $
#include "smartctl.h"
#include "utility.h"
-const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3283 2011-03-04 20:13:57Z chrfranke $"
+const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3316 2011-04-19 19:34:57Z chrfranke $"
CONFIG_H_CVSID SMARTCTL_H_CVSID;
// Globals to control printing
" Show device SMART health status\n\n"
" -c, --capabilities (ATA)\n"
" Show device SMART capabilities\n\n"
-" -A, --attributes \n"
+" -A, --attributes\n"
" Show device SMART vendor-specific Attributes and values\n\n"
+" -f FORMAT, --format=FORMAT (ATA)\n"
+" Set output format for attributes to one of: old, brief\n\n"
" -l TYPE, --log=TYPE\n"
" Show device log. TYPE: error, selftest, selective, directory[,g|s],\n"
" background, sasphy[,reset], sataphy[,reset],\n"
return "none, samsung, samsung2, samsung3, swapid";
case 'n':
return "never, sleep, standby, idle";
+ case 'f':
+ return "old, brief";
case 'v':
default:
return "";
scsi_print_options & scsiopts)
{
// Please update getvalidarglist() if you edit shortopts
- const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iaxv:P:t:CXF:n:B:";
+ const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iaxv:P:t:CXF:n:B:f:";
// Please update getvalidarglist() if you edit longopts
enum { opt_scan = 1000, opt_scan_open = 1001 };
struct option longopts[] = {
{ "firmwarebug", required_argument, 0, 'F' },
{ "nocheck", required_argument, 0, 'n' },
{ "drivedb", required_argument, 0, 'B' },
+ { "format", required_argument, 0, 'f' },
{ "scan", no_argument, 0, opt_scan },
{ "scan-open", no_argument, 0, opt_scan_open },
{ 0, 0, 0, 0 }
const char * type = 0; // set to -d optarg
bool no_defaultdb = false; // set true on '-B FILE'
+ bool output_format_set = false; // set true on '-f FORMAT'
int scan = 0; // set by --scan, --scan-open
bool badarg = false, captive = false;
int testcnt = 0; // number of self-tests requested
ataopts.sataphy = true;
scsiopts.smart_background_log = true;
scsiopts.sasphy = true;
+ if (!output_format_set)
+ ataopts.output_format = 1; // '-f brief'
break;
case 'v':
// parse vendor-specific definitions of attributes
else
badarg = true;
break;
+ case 'f':
+ output_format_set = true;
+ if (!strcmp(optarg,"old")) {
+ ataopts.output_format = 0;
+ } else if (!strcmp(optarg,"brief")) {
+ ataopts.output_format = 1;
+ } else {
+ badarg = true;
+ }
+ break;
case 'B':
{
const char * path = optarg;
#define ARGUSED(x) ((void)(x))
-const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3288 2011-03-09 18:40:36Z chrfranke $"
+const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3349 2011-05-27 21:46:31Z chrfranke $"
CONFIG_H_CVSID;
// smartd exit codes
newadd = address.c_str();
}
-#ifdef _MSC_VER
- _set_printf_count_output(1); // "%n" disabled by default
-#endif
// Message for mail [0...] and messagebox [boxmsgoffs...]
snprintf(stdinbuf, sizeof(stdinbuf),
"This email was generated by the smartd daemon running on:\n\n"
" host name: %s\n"
" DNS domain: %s\n"
// " NIS domain: %s\n"
- "\n%n"
+ "\n",
+ hostname, /*domainname, */ nisdomain);
+ boxmsgoffs = strlen(stdinbuf);
+ snprintf(stdinbuf+boxmsgoffs, sizeof(stdinbuf)-boxmsgoffs,
"The following warning/error was logged by the smartd daemon:\n\n"
"%s\n\n"
"For details see the event log or log file of smartd.\n\n"
"%s%s%s"
"\n",
- hostname, /*domainname, */ nisdomain, &boxmsgoffs, message, further, original, additional);
+ message, further, original, additional);
}
else
snprintf(command, sizeof(command), "%s", executable);
#define SELFTEST_ERRORCOUNT(x) (x & 0xff)
#define SELFTEST_ERRORHOURS(x) ((x >> 8) & 0xffff)
+// Log offline data collection status
+static void log_offline_data_coll_status(const char * name, unsigned char status)
+{
+ const char * msg;
+ switch (status & 0x7f) {
+ case 0x00: msg = "was never started"; break;
+ case 0x02: msg = "was completed without error"; break;
+ case 0x03: msg = (status == 0x03 ? "is in progress" : 0); break;
+ case 0x04: msg = "was suspended by an interrupting command from host"; break;
+ case 0x05: msg = "was aborted by an interrupting command from host"; break;
+ case 0x06: msg = "was aborted by the device with a fatal error"; break;
+ default: msg = 0;
+ }
+
+ if (msg)
+ PrintOut(((status & 0x7f) == 0x06 ? LOG_CRIT : LOG_INFO),
+ "Device: %s, offline data collection %s%s\n", name, msg,
+ ((status & 0x80) ? " (auto:on)" : ""));
+ else
+ PrintOut(LOG_INFO, "Device: %s, unknown offline data collection status 0x%02x\n",
+ name, status);
+}
+
// Log self-test execution status
static void log_self_test_exec_status(const char * name, unsigned char status)
{
ata_format_id_string(model, drive.model, sizeof(model)-1);
ata_format_id_string(serial, drive.serial_no, sizeof(serial)-1);
ata_format_id_string(firmware, drive.fw_rev, sizeof(firmware)-1);
- state.num_sectors = get_num_sectors(&drive);
- PrintOut(LOG_INFO, "Device: %s, %s, S/N:%s, FW:%s, %"PRIu64" sectors\n", name,
- model, serial, firmware, state.num_sectors);
+
+ ata_size_info sizes;
+ ata_get_size_info(&drive, sizes);
+ state.num_sectors = sizes.sectors;
+
+ char wwn[30]; wwn[0] = 0;
+ unsigned oui = 0; uint64_t unique_id = 0;
+ int naa = ata_get_wwn(&drive, oui, unique_id);
+ if (naa >= 0)
+ snprintf(wwn, sizeof(wwn), "WWN:%x-%06x-%09"PRIx64", ", naa, oui, unique_id);
+
+ char cap[32];
+ PrintOut(LOG_INFO, "Device: %s, %s, S/N:%s, %sFW:%s, %s\n", name,
+ model, serial, wwn, firmware,
+ format_capacity(cap, sizeof(cap), sizes.capacity, "."));
// Show if device in database, and use preset vendor attribute
// options unless user has requested otherwise.
}
-static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device * atadev, bool allow_selftests)
+static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device * atadev,
+ bool firstpass, bool allow_selftests)
{
const char * name = cfg.name.c_str();
}
if (cfg.selftest) {
- // Log changes of self-test execution status
+ // Log changes of offline data collection and self-test execution status
+ if ( curval.offline_data_collection_status
+ != state.smartval.offline_data_collection_status
+ || (firstpass && (debugmode || (curval.offline_data_collection_status & 0x7d))))
+ log_offline_data_coll_status(name, curval.offline_data_collection_status);
+
if ( curval.self_test_exec_status != state.smartval.self_test_exec_status
- || (!allow_selftests && curval.self_test_exec_status != 0x00) )
+ || (firstpass && (debugmode || curval.self_test_exec_status != 0x00)))
log_self_test_exec_status(name, curval.self_test_exec_status);
}
// Checks the SMART status of all ATA and SCSI devices
static void CheckDevicesOnce(const dev_config_vector & configs, dev_state_vector & states,
- smart_device_list & devices, bool allow_selftests)
+ smart_device_list & devices, bool firstpass, bool allow_selftests)
{
for (unsigned i = 0; i < configs.size(); i++) {
const dev_config & cfg = configs.at(i);
dev_state & state = states.at(i);
smart_device * dev = devices.at(i);
if (dev->is_ata())
- ATACheckDevice(cfg, state, dev->to_ata(), allow_selftests);
+ ATACheckDevice(cfg, state, dev->to_ata(), firstpass, allow_selftests);
else if (dev->is_scsi())
SCSICheckDevice(cfg, state, dev->to_scsi(), allow_selftests);
}
// check all devices once,
// self tests are not started in first pass unless '-q onecheck' is specified
- CheckDevicesOnce(configs, states, devices, (!firstpass || quit==3));
+ CheckDevicesOnce(configs, states, devices, firstpass, (!firstpass || quit==3));
// Write state files
if (!state_path_prefix.empty())
--- /dev/null
+#!/bin/sh
+# $FreeBSD: ports/sysutils/smartmontools/files/smartd.in,v 1.2 2010/03/27 00:15:05 dougb Exp $
+
+# PROVIDE: smartd
+# REQUIRE: DAEMON
+# BEFORE: LOGIN
+# KEYWORD: shutdown nojail
+
+# Define these smartd_* variables in one of these files:
+# /etc/rc.conf
+# /etc/rc.conf.local
+# /etc/rc.conf.d/smartd
+#
+# DO NOT CHANGE THESE DEFAULT VALUES HERE
+#
+smartd_enable="${smartd_enable-NO}"
+smartd_pidfile="/var/run/smartd.pid"
+
+. /etc/rc.subr
+
+name="smartd"
+rcvar=`set_rcvar`
+command="/usr/local/sbin/smartd"
+extra_commands="reload report"
+reload_cmd="smartd_reload"
+report_cmd="smartd_report"
+
+smartd_reload()
+{
+ rc_pid=$(check_pidfile $pidfile $command)
+ if [ -z "$rc_pid" ]; then
+ [ -n "$rc_fast" ] && return 0
+ _run_rc_notrunning
+ return 1
+ fi
+ echo 'Reloading smartd.'
+ kill -HUP $rc_pid
+}
+
+smartd_report()
+{
+ rc_pid=$(check_pidfile $pidfile $command)
+ if [ -z "$rc_pid" ]; then
+ [ -n "$rc_fast" ] && return 0
+ _run_rc_notrunning
+ return 1
+ fi
+ echo 'Checking SMART devices now.'
+ kill -USR1 $rc_pid
+}
+
+load_rc_config $name
+
+: ${smartd_config="/usr/local/etc/smartd.conf"}
+: ${smartd_flags="-c ${smartd_config}"}
+
+pidfile="${smartd_pidfile}"
+required_files="${smartd_config}"
+
+case "${smartd_flags}" in
+*-p\ *)
+ echo "ERROR: \$smartd_flags includes -p option." \
+ "Please use \$smartd_pidfile instead."
+ exit 1
+ ;;
+*)
+ smartd_flags="-p ${pidfile} ${smartd_flags}"
+ ;;
+esac
+
+run_rc_command "$1"
# smartmontools init file for smartd
# Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-# $Id: smartd.initd.in 3003 2009-12-19 18:47:47Z chrfranke $
+# $Id: smartd.initd.in 3360 2011-06-06 19:25:36Z chrfranke $
# For RedHat and cousins:
# chkconfig: 2345 40 40
# For SuSE and cousins
### BEGIN INIT INFO
# Provides: smartd
-# Required-Start: $syslog
-# X-UnitedLinux-Should-Start: $sendmail
-# Should-Start: $sendmail
-# Required-Stop: $syslog
-# X-UnitedLinux-Should-Stop:
+# Required-Start: $syslog $remote_fs
+# Should-Start: sendmail
+# Required-Stop: $syslog $remote_fs
+# Should-Stop: sendmail
# Default-Start: 2 3 5
# Default-Stop:
# Short-Description: Monitors disk and tape health via S.M.A.R.T.
# Red Hat or Yellow Dog or Mandrake
if [ -f /etc/redhat-release -o -f /etc/yellowdog-release -o -f /etc/mandrake-release -o -f /etc/whitebox-release -o -f /etc/trustix-release -o -f /etc/tinysofa-release ] ; then
-
-# Source function library
+
+ # Source function library
. /etc/rc.d/init.d/functions
-# Source configuration file. This should define the shell variable smartd_opts
+ # Source configuration file. This should define the shell variable smartd_opts
[ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
-
+
RETVAL=0
-
+
prog=smartd
-
+ pidfile=/var/lock/subsys/smartd
+ config=/etc/smartd.conf
+
+ start()
+ {
+ [ $UID -eq 0 ] || exit 4
+ [ -x $SMARTD_BIN ] || exit 5
+ [ -f $config ] || exit 6
+ echo -n $"Starting $prog: "
+ daemon $SMARTD_BIN $smartd_opts
+ RETVAL=$?
+ echo
+ [ $RETVAL = 0 ] && touch $pidfile
+ return $RETVAL
+ }
+
+ stop()
+ {
+ [ $UID -eq 0 ] || exit 4
+ echo -n $"Shutting down $prog: "
+ killproc $SMARTD_BIN
+ RETVAL=$?
+ echo
+ rm -f $pidfile
+ return $RETVAL
+ }
+
+ reload()
+ {
+ echo -n $"Reloading $prog daemon configuration: "
+ killproc $SMARTD_BIN -HUP
+ RETVAL=$?
+ echo
+ return $RETVAL
+ }
+
+ report()
+ {
+ echo -n $"Checking SMART devices now: "
+ killproc $SMARTD_BIN -USR1
+ RETVAL=$?
+ echo
+ return $RETVAL
+ }
+
case "$1" in
start)
- echo -n $"Starting $prog: "
- daemon $SMARTD_BIN $smartd_opts
- touch /var/lock/subsys/smartd
- echo
- ;;
+ start
+ ;;
stop)
- echo -n $"Shutting down $prog: "
- killproc $SMARTD_BIN
- rm -f /var/lock/subsys/smartd
- echo
- ;;
+ stop
+ ;;
reload)
- echo -n $"Reloading $prog daemon configuration: "
- killproc $SMARTD_BIN -HUP
- RETVAL=$?
- echo
- ;;
+ reload
+ ;;
report)
- echo -n $"Checking SMART devices now: "
- killproc $SMARTD_BIN -USR1
- RETVAL=$?
- echo
- ;;
+ report
+ ;;
restart)
- $0 stop
- $0 start
- ;;
+ stop
+ start
+ ;;
+ condrestart|try-restart)
+ if [ -f $pidfile ]; then
+ stop
+ start
+ fi
+ ;;
+ force-reload)
+ reload || (stop; start)
+ ;;
status)
- status $prog
- ;;
+ status $prog
+ RETVAL=$?
+ ;;
*)
- echo $"Usage: $0 {start|stop|reload|report|restart|status}"
- RETVAL=1
+ echo $"Usage: $0 {start|stop|restart|status|condrestart|try-restart|reload|force-reload|report}"
+ RETVAL=2
+ [ "$1" = 'usage' ] && RETVAL=0
esac
-
exit $RETVAL
# Slackware
elif [ -f /etc/slackware-version ] ; then
-
-# Source configuration file. This should define the shell variable smartd_opts.
-# Email smartmontools-support@lists.sourceforge.net if there is a better choice
-# of path for Slackware.
+
+ # Source configuration file. This should define the shell variable smartd_opts.
+ # Email smartmontools-support@lists.sourceforge.net if there is a better choice
+ # of path for Slackware.
[ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
+ RETVAL=0
case "$1" in
start)
echo -n "Starting smartd: "
$SMARTD_BIN $smartd_opts
+ RETVAL=$?
echo
;;
stop)
echo -n "Shutting down smartd: "
killall $SMARTD_BIN
+ RETVAL=$?
echo
;;
restart)
$0 stop
sleep 1
$0 start
+ RETVAL=$?
+ ;;
+ try-restart)
+ if pidof $SMARTD_BIN >/dev/null; then
+ $0 restart
+ RETVAL=$?
+ fi
+ ;;
+ force-reload)
+ $0 reload || $0 restart
+ RETVAL=$?
+ ;;
+ reload)
+ echo -n "Reloading smartd configuration: "
+ killall -s HUP $SMARTD_BIN
+ RETVAL=$?
+ echo
+ ;;
+ report)
+ echo -n "Checking SMART devices now: "
+ killall -s USR1 $SMARTD_BIN
+ RETVAL=$?
+ echo
+ ;;
+ status)
+ if pidof $SMARTD_BIN >/dev/null; then
+ echo "$SMARTD_BIN is running."
+ else
+ echo "$SMARTD_BIN is not running."
+ RETVAL=1
+ fi
;;
*)
- echo "Usage: smartd {start|stop|restart}"
- exit 1
+ echo "Usage: $0 {start|stop|restart|try-restart|force-reload|reload|report|status}"
+ RETVAL=1
esac
-
- exit 0
-
+ exit $RETVAL
+
# SuSE
elif [ -f /etc/SuSE-release ] ; then
test -x $SMARTD_BIN || exit 5
-
+
# Existence of config file is optional
SMARTD_CONFIG=/etc/smartd.conf
-# source configuration file. This should set the shell variable smartd_opts
- [ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
+ # source configuration file.
+ [ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
+ smartd_opts=
+ if test -n "$SMARTD_CHECK_INTERVAL" -a "$SMARTD_CHECK_INTERVAL" != 1800 ; then
+ smartd_opts=" -i $SMARTD_CHECK_INTERVAL"
+ fi
+ if test -n "$SMARTD_LOG_FACILITY" -a "$SMARTD_LOG_FACILITY" != "daemon" ; then
+ smartd_opts="$smartd_opts -l $SMARTD_LOG_FACILITY"
+ fi
+ if test -n "$SMARTD_DRIVEDB" ; then
+ smartd_opts="$smartd_opts -B $SMARTD_DRIVEDB"
+ fi
- # Shell functions sourced from /etc/rc.status:
- # rc_check check and set local and overall rc status
- # rc_status check and set local and overall rc status
- # rc_status -v ditto but be verbose in local rc status
- # rc_status -v -r ditto and clear the local rc status
- # rc_failed set local and overall rc status to failed
- # rc_reset clear local rc status (overall remains)
- # rc_exit exit appropriate to overall rc status
+ # Shell functions sourced from /etc/rc.status:
+ # rc_check check and set local and overall rc status
+ # rc_status check and set local and overall rc status
+ # rc_status -v be verbose in local rc status and clear it afterwards
+ # rc_status -v -r ditto and clear both the local and overall rc status
+ # rc_status -s display "skipped" and exit with status 3
+ # rc_status -u display "unused" and exit with status 3
+ # rc_failed set local and overall rc status to failed
+ # rc_failed <num> set local and overall rc status to <num>
+ # rc_reset clear both the local and overall rc status
+ # rc_exit exit appropriate to overall rc status
+ # rc_active checks whether a service is activated by symlinks
. /etc/rc.status
-
- # First reset status of this service
+
+ # Reset status of this service
rc_reset
-
- # Return values acc. to LSB for all commands but status:
- # 0 - success
- # 1 - misc error
- # 2 - invalid or excess args
- # 3 - unimplemented feature (e.g. reload)
- # 4 - insufficient privilege
- # 5 - program not installed
- # 6 - program not configured
- #
- # Note that starting an already running service, stopping
- # or restarting a not-running service as well as the restart
- # with force-reload (in case signalling is not supported) are
- # considered a success.
+
+ # Return values acc. to LSB for all commands but status:
+ # 0 - success
+ # 1 - generic or unspecified error
+ # 2 - invalid or excess argument(s)
+ # 3 - unimplemented feature (e.g. "reload")
+ # 4 - user had insufficient privileges
+ # 5 - program is not installed
+ # 6 - program is not configured
+ # 7 - program is not running
+ # 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
+ #
+ # Note that starting an already running service, stopping
+ # or restarting a not-running service as well as the restart
+ # with force-reload (in case signaling is not supported) are
+ # considered a success.
+
case "$1" in
start)
echo -n "Starting smartd "
- ## Start daemon with startproc(8). If this fails
- ## the echo return value is set appropriate.
-
- # startproc should return 0, even if service is
- # already running to match LSB spec.
- startproc $SMARTD_BIN $smartd_opts
-
- # Remember status and be verbose
- rc_status -v
+ ## Start daemon with startproc(8). If this fails
+ ## the return value is set appropriately by startproc.
+
+ # We don't use startproc - we need to check for return code 17.
+ if ! /sbin/checkproc $SMARTD_BIN ; then
+ $SMARTD_BIN $smartd_opts
+ # Remember status and be verbose
+ if test $? -ne 17 ; then
+ rc_status -v
+ else
+ rc_status -u
+ fi
+ else
+ rc_reset
+ rc_status -v
+ fi
;;
stop)
echo -n "Shutting down smartd "
- killproc -TERM $SMARTD_BIN
-
- # Remember status and be verbose
- rc_status -v
+ /sbin/killproc -TERM $SMARTD_BIN
+ # Remember status and be verbose
+ rc_status -v
;;
- try-restart|condrestart)
+ try-restart)
## Do a restart only if the service was active before.
## Note: try-restart is now part of LSB (as of 1.9).
- ## RH has a similar command named condrestart.
- if test "$1" = "condrestart"; then
- echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
- fi
$0 status
if test $? = 0; then
- $0 restart
- else
- rc_reset # Not running is not a failure.
+ $0 restart
+ else
+ rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
- restart | force-reload)
+ restart)
$0 stop
$0 start
+ # Remember status and be quiet
+ rc_status
;;
- reload)
- ## Like force-reload, but if daemon does not support
- ## signaling, do nothing (!)
- rc_failed 3
+ force-reload|reload)
+ echo -n "Reload service smartd "
+ /sbin/killproc -HUP $SMARTD_BIN
rc_status -v
;;
- status)
- echo -n "Checking for service smartd "
- ## Check status with checkproc(8), if process is running
- ## checkproc will return with exit status 0.
-
- # Status has a slightly different for the status command:
- # 0 - service running
- # 1 - service dead, but /var/run/ pid file exists
- # 2 - service dead, but /var/lock/ lock file exists
- # 3 - service not running
-
- # NOTE: checkproc returns LSB compliant status values.
- checkproc $SMARTD_BIN
- rc_status -v
- ;;
- probe)
+ report)
+ ## Checking SMART devices now (smartd specific function)
+ echo -n "Checking SMART devices now "
+ /sbin/killproc -USR1 $SMARTD_BIN
+ rc_status -v
+ ;;
+ status)
+ echo -n "Checking for service smartd "
+ ## Check status with checkproc(8), if process is running
+ ## checkproc will return with exit status 0.
+
+ # Return value is slightly different for the status command:
+ # 0 - service up and running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running (unused)
+ # 4 - service status unknown :-(
+ # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
+
+ # NOTE: checkproc returns LSB compliant status values.
+ /sbin/checkproc $SMARTD_BIN
+ rc_status -v
+ ;;
+ probe)
## Optional: Probe for the necessity of a reload, print out the
## argument to this init script which is required for a reload.
- ## Note: probe is not (yet) part of LSB (as of 1.2)
+ ## Note: probe is not (yet) part of LSB (as of 1.9)
test $SMARTD_CONFIG -nt /var/run/smartd.pid && echo reload
;;
*)
- echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
+ echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|report|probe}"
exit 1
- ;;
esac
-
rc_exit
# Debian case
elif [ -f /etc/debian_version ] ; then
- PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
- SMARTDPID=/var/run/smartd.pid
- [ -x $SMARTD_BIN ] || exit 0
- RET=0
+ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+ SMARTDPID=/var/run/smartd.pid
+ [ -x $SMARTD_BIN ] || exit 0
+ RET=0
+
+ # source configuration file
+ [ -r /etc/default/rcS ] && . /etc/default/rcS
+ [ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
-# source configuration file
- [ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
+ smartd_opts="--pidfile $SMARTDPID $smartd_opts"
- smartd_opts="--pidfile $SMARTDPID $smartd_opts"
-
- case "$1" in
+ case "$1" in
start)
echo -n "Starting S.M.A.R.T. daemon: smartd"
if start-stop-daemon --start --quiet --pidfile $SMARTDPID \
- --exec $SMARTD_BIN -- $smartd_opts; then
- echo "."
+ --exec $SMARTD_BIN -- $smartd_opts; then
+ echo "."
else
- echo " (failed)"
+ echo " (failed)"
RET=1
- fi
- ;;
+ fi
+ ;;
stop)
echo -n "Stopping S.M.A.R.T. daemon: smartd"
start-stop-daemon --stop --quiet --oknodo --pidfile $SMARTDPID
echo "."
- ;;
- restart|force-reload)
- $0 stop
- $0 start
- ;;
- *)
- echo "Usage: /etc/init.d/smartmontools {start|stop|restart|force-reload}"
+ ;;
+ restart)
+ $0 stop
+ $0 start
+ ;;
+ force-reload)
+ $0 reload || $0 restart
+ ;;
+ reload)
+ echo -n "Reload S.M.A.R.T. daemon: smartd"
+ if start-stop-daemon --stop --quiet --signal 1 \
+ --pidfile $SMARTDPID; then
+ echo "."
+ else
+ echo " (failed)"
+ RET=1
+ fi
+ ;;
+ report)
+ echo -n "Checking SMART devices now"
+ if start-stop-daemon --stop --quiet --signal 10 \
+ --pidfile $SMARTDPID; then
+ echo "."
+ else
+ echo " (failed)"
+ RET=1
+ fi
+ ;;
+ status)
+ if pidof $SMARTD_BIN >/dev/null; then
+ echo "$SMARTD_BIN is running."
+ else
+ echo "$SMARTD_BIN is not running."
+ RET=1
+ fi
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|force-reload|reload|report|status}"
exit 1
- esac
- exit $RET
+ esac
+ exit $RET
elif [ -f /etc/gentoo-release ] ; then
report_unsupported "Gentoo"
# PLEASE ADD OTHER LINUX DISTRIBUTIONS JUST BEFORE THIS LINE, USING elif
elif uname -a | grep FreeBSD > /dev/null 2>&1 ; then
-# following is replaced by port install
+ # following is replaced by port install
PREFIX=@@PREFIX@@
-
-# Updated to try both the RCNG version of things from 5.x, or fallback to
-# oldfashioned rc.conf
- if [ -r /etc/rc.subr ]; then
-# This is RC-NG, pick up our values
+ # Updated to try both the RCNG version of things from 5.x, or fallback to
+ # oldfashioned rc.conf
+
+ if [ -r /etc/rc.subr ]; then
+ # This is RC-NG, pick up our values
. /etc/rc.subr
- name="smartd"
- rcvar="smartd_enable"
- command="$SMARTD_BIN"
+ name="smartd"
+ rcvar="smartd_enable"
+ command="$SMARTD_BIN"
load_rc_config $name
elif [ -r /etc/defaults/rc.conf ]; then
-# Not a 5.x system, try the default location for variables
+ # Not a 5.x system, try the default location for variables
. /etc/defaults/rc.conf
source_rc_confs
elif [ -r /etc/rc.conf ]; then
-# Worst case, fallback to system config file
+ # Worst case, fallback to system config file
. /etc/rc.conf
fi
- if [ -r /etc/rc.subr ]; then
-# Use new functionality from RC-NG
+ if [ -r /etc/rc.subr ]; then
+ # Use new functionality from RC-NG
run_rc_command "$1"
else
PID_FILE=/var/run/smartd.pid
sleep 1
$0 start
;;
+ reload)
+ kill -s HUP `cat $PID_FILE`
+ ;;
+ report)
+ kill -s USR1 `cat $PID_FILE`
+ ;;
*)
- echo "Usage: smartd {start|stop|restart}"
+ echo "Usage: $0 {start|stop|restart|reload|report}"
exit 1
esac
-
exit 0
fi
+
elif uname -a | grep SunOS > /dev/null 2>&1 ; then
-
-# Source configuration file. This should define the shell variable smartd_opts.
-# Email smartmontools-support@lists.sourceforge.net if there is a better choice
-# of path for Solaris
+
+ # Source configuration file. This should define the shell variable smartd_opts.
+ # Email smartmontools-support@lists.sourceforge.net if there is a better choice
+ # of path for Solaris
[ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
PID_FILE=/var/run/smartd.pid
-
+
case "$1" in
start)
$SMARTD_BIN -p $PID_FILE $smartd_opts
sleep 1
$0 start
;;
+ reload)
+ kill -s HUP `cat $PID_FILE`
+ ;;
+ report)
+ kill -s USR1 `cat $PID_FILE`
+ ;;
*)
- echo "Usage: smartd {start|stop|restart}"
+ echo "Usage: $0 {start|stop|restart|reload|report}"
exit 1
esac
-
exit 0
# Cygwin
elif uname | grep -i CYGWIN > /dev/null 2>&1 ; then
-# The following settings may be changed by the configuration file below
+ # The following settings may be changed by the configuration file below
# Service Name (must be unique)
smartd_svcname=smartd
# Service display name
built into ATA and SCSI Hard Drives. \
http://smartmontools.sourceforge.net/"
-# Source configuration file. This should define the shell variable smartd_opts.
-# Email smartmontools-support@lists.sourceforge.net if there is a better choice
-# of path for Cygwin
+ # Source configuration file. This should define the shell variable smartd_opts.
+ # Email smartmontools-support@lists.sourceforge.net if there is a better choice
+ # of path for Cygwin
[ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
fi
# One should NEVER arrive here, except for a badly written case above,
-# that fails to exit.
+# that fails to exit.
echo "SOMETHING IS WRONG WITH THE SMARTD STARTUP SCRIPT"
echo "PLEASE CONTACT smartmontools-support@lists.sourceforge.net"
exit 1
--- /dev/null
+[Unit]
+Description=Self Monitoring and Reporting Technology (SMART) Daemon
+After=syslog.target
+
+[Service]
+EnvironmentFile=/usr/local/etc/sysconfig/smartmontools
+ExecStart=/usr/local/sbin/smartd -n $smartd_opts
+
+[Install]
+WantedBy=multi-user.target
// BOTH SCSI AND ATA DEVICES, AND THAT MAY BE USED IN SMARTD,
// SMARTCTL, OR BOTH.
+#include "config.h"
+
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
-#include <syslog.h>
#include <stdarg.h>
#include <sys/stat.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
#ifdef _WIN32
#include <mbstring.h> // _mbsinc()
#endif
#include <stdexcept>
-#include "config.h"
#include "svnversion.h"
#include "int64.h"
#include "utility.h"
#include "atacmds.h"
#include "dev_interface.h"
-const char * utility_cpp_cvsid = "$Id: utility.cpp 3285 2011-03-04 22:08:49Z chrfranke $"
+const char * utility_cpp_cvsid = "$Id: utility.cpp 3305 2011-03-30 21:32:05Z chrfranke $"
UTILITY_H_CVSID INT64_H_CVSID;
const char * packet_types[] = {
return;
}
+// Format integer with thousands separator
+const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
+ const char * thousands_sep /* = 0 */)
+{
+ if (!thousands_sep) {
+ thousands_sep = ",";
+#ifdef HAVE_LOCALE_H
+ setlocale(LC_ALL, "");
+ const struct lconv * currentlocale = localeconv();
+ if (*(currentlocale->thousands_sep))
+ thousands_sep = currentlocale->thousands_sep;
+#endif
+ }
+
+ char num[64];
+ snprintf(num, sizeof(num), "%"PRIu64, val);
+ int numlen = strlen(num);
+
+ int i = 0, j = 0;
+ do
+ str[j++] = num[i++];
+ while (i < numlen && (numlen - i) % 3 != 0 && j < strsize-1);
+ str[j] = 0;
+
+ while (i < numlen && j < strsize-1) {
+ j += snprintf(str+j, strsize-j, "%s%.3s", thousands_sep, num+i);
+ i += 3;
+ }
+
+ return str;
+}
+
+// Format capacity with SI prefixes
+const char * format_capacity(char * str, int strsize, uint64_t val,
+ const char * decimal_point /* = 0 */)
+{
+ if (!decimal_point) {
+ decimal_point = ".";
+#ifdef HAVE_LOCALE_H
+ setlocale(LC_ALL, "");
+ const struct lconv * currentlocale = localeconv();
+ if (*(currentlocale->decimal_point))
+ decimal_point = currentlocale->decimal_point;
+#endif
+ }
+
+ const unsigned factor = 1000; // 1024 for KiB,MiB,...
+ static const char prefixes[] = " KMGTP";
+
+ // Find d with val in [d, d*factor)
+ unsigned i = 0;
+ uint64_t d = 1;
+ for (uint64_t d2 = d * factor; val >= d2; d2 *= factor) {
+ d = d2;
+ if (++i >= sizeof(prefixes)-2)
+ break;
+ }
+
+ // Print 3 digits
+ uint64_t n = val / d;
+ if (i == 0)
+ snprintf(str, strsize, "%u B", (unsigned)n);
+ else if (n >= 100) // "123 xB"
+ snprintf(str, strsize, "%"PRIu64" %cB", n, prefixes[i]);
+ else if (n >= 10) // "12.3 xB"
+ snprintf(str, strsize, "%"PRIu64"%s%u %cB", n, decimal_point,
+ (unsigned)(((val % d) * 10) / d), prefixes[i]);
+ else // "1.23 xB"
+ snprintf(str, strsize, "%"PRIu64"%s%02u %cB", n, decimal_point,
+ (unsigned)(((val % d) * 100) / d), prefixes[i]);
+
+ return str;
+}
+
// return (v)sprintf() formatted std::string
std::string vstrprintf(const char * fmt, va_list ap)
#ifndef UTILITY_H_
#define UTILITY_H_
-#define UTILITY_H_CVSID "$Id: utility.h 3285 2011-03-04 22:08:49Z chrfranke $"
+#define UTILITY_H_CVSID "$Id: utility.h 3305 2011-03-30 21:32:05Z chrfranke $"
#include <time.h>
#include <sys/types.h> // for regex.h (according to POSIX)
// convert time in msec to a text string
void MsecToText(unsigned int msec, char *txt);
+// Format integer with thousands separator
+const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
+ const char * thousands_sep = 0);
+
+// Format capacity with SI prefixes
+const char * format_capacity(char * str, int strsize, uint64_t val,
+ const char * decimal_point = 0);
+
// Wrapper class for a raw data buffer
class raw_buffer
{