From b98a5559670d5ff1904221d71ec507419894f5e4 Mon Sep 17 00:00:00 2001 From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Mon, 29 Sep 2008 19:13:49 +0000 Subject: [PATCH] Add '-d sat+TYPE' to use SAT with controllers which require '-d TYPE'. git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@2655 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 6 ++++- sm5/dev_interface.cpp | 55 +++++++++++++++++++++++++++++++++---------- sm5/dev_interface.h | 4 ++-- sm5/scsiata.cpp | 9 ++----- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index 8195c379f..ecf041116 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.737 2008/09/27 17:04:36 chrfranke Exp $ +$Id: CHANGELOG,v 1.738 2008/09/29 19:13:49 chrfranke Exp $ The most recent version of this file is: http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup @@ -40,6 +40,10 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [CF] Add option '-d sat+TYPE' to use SAT with controllers which + require option '-d TYPE'. Should work with '-d sat+megaraid,N'. + As a side effect, '-d usbcypress+TYPE' is also supported. + [CF] Add parser to read drive database from a file. Add '-B' option to smartctl and smartd to specify database file name. File syntax is identical to the C/C++ syntax used to inialize the internal diff --git a/sm5/dev_interface.cpp b/sm5/dev_interface.cpp index 52a37ff16..d16e8ab04 100644 --- a/sm5/dev_interface.cpp +++ b/sm5/dev_interface.cpp @@ -25,7 +25,7 @@ #include <stdexcept> -const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp,v 1.3 2008/08/23 19:56:18 chrfranke Exp $" +const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp,v 1.4 2008/09/29 19:13:49 chrfranke Exp $" DEV_INTERFACE_H_CVSID; ///////////////////////////////////////////////////////////////////////////// @@ -224,18 +224,17 @@ const char * smart_interface::get_os_version_str() const char * smart_interface::get_valid_dev_types_str() { - static char buf[80+1]; - if (buf[0]) - return buf; + static std::string buf; + if (!buf.empty()) + return buf.c_str(); // default - strcpy(buf, "ata, scsi, sat[,N]"); + buf = "ata, scsi, sat[,N][+TYPE]"; // append custom const char * add = get_valid_custom_dev_types_str(); if (!add || !*add) - return buf; - strcat(buf, ", "); - strcat(buf, add); - return buf; + return buf.c_str(); + buf += ", "; buf += add; + return buf.c_str(); } const char * smart_interface::get_app_examples(const char * /*appname*/) @@ -294,9 +293,41 @@ smart_device * smart_interface::get_smart_device(const char * name, const char * dev = get_ata_device(name, type); else if (!strcmp(type, "scsi")) dev = get_scsi_device(name, type); - else if ( (!strncmp(type, "sat", 3) && (!type[3] || type[3] == ',')) - || (!strncmp(type, "usb", 3))) - dev = get_sat_device(name, type /*, 0*/); + + else if ( (!strncmp(type, "sat", 3) && (!type[3] || strchr(",+", type[3])) + || (!strncmp(type, "usb", 3)))) { + // Split "sat...+base..." -> ("sat...", "base...") + unsigned satlen = strcspn(type, "+"); + std::string sattype(type, satlen); + const char * basetype = (type[satlen] ? type+satlen+1 : ""); + // Recurse to allocate base device, default is standard SCSI + if (!*basetype) + basetype = "scsi"; + dev = get_smart_device(name, basetype); + if (!dev) { + set_err(EINVAL, "Type '%s+...': %s", sattype.c_str(), get_errmsg()); + return 0; + } + // Result must be SCSI + if (!dev->is_scsi()) { + delete dev; + set_err(EINVAL, "Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype); + return 0; + } + // Attach SAT tunnel + try { + ata_device * satdev = get_sat_device(sattype.c_str(), dev->to_scsi()); + if (!satdev) { + delete dev; + return 0; + } + return satdev; + } + catch (...) { + delete dev; throw; + } + } + else { set_err(EINVAL, "Unknown device type '%s'", type); return 0; diff --git a/sm5/dev_interface.h b/sm5/dev_interface.h index d10fadc8e..35e7afd80 100644 --- a/sm5/dev_interface.h +++ b/sm5/dev_interface.h @@ -18,7 +18,7 @@ #ifndef DEV_INTERFACE_H #define DEV_INTERFACE_H -#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h,v 1.6 2008/08/29 20:07:36 chrfranke Exp $\n" +#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h,v 1.7 2008/09/29 19:13:49 chrfranke Exp $\n" #include <stdarg.h> #include <string> @@ -674,7 +674,7 @@ protected: /// Return ATA->SCSI filter for SAT or USB. /// Override only if platform needs special handling. - virtual ata_device * get_sat_device(const char * name, const char * type, scsi_device * scsidev = 0); + virtual ata_device * get_sat_device(const char * type, scsi_device * scsidev); //{ implemented in scsiata.cpp } public: diff --git a/sm5/scsiata.cpp b/sm5/scsiata.cpp index bff27d946..c2590b9af 100644 --- a/sm5/scsiata.cpp +++ b/sm5/scsiata.cpp @@ -50,7 +50,7 @@ #include "dev_ata_cmd_set.h" // ata_device_with_command_set #include "dev_tunnelled.h" // tunnelled_device<> -const char *scsiata_c_cvsid="$Id: scsiata.cpp,v 1.18 2008/09/12 19:26:09 chrfranke Exp $" +const char *scsiata_c_cvsid="$Id: scsiata.cpp,v 1.19 2008/09/29 19:13:49 chrfranke Exp $" CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID; /* for passing global control variables */ @@ -790,13 +790,8 @@ using namespace sat; // Return ATA->SCSI filter for SAT or USB. -ata_device * smart_interface::get_sat_device(const char * name, const char * type, scsi_device * scsidev /* = 0*/) +ata_device * smart_interface::get_sat_device(const char * type, scsi_device * scsidev) { - if (!scsidev) { - scsidev = get_scsi_device(name, "scsi"); - if (!scsidev) - return 0; - } if (!strncmp(type, "sat", 3)) { int ptlen = 0, n1 = -1, n2 = -1; if (!(((sscanf(type, "sat%n,%d%n", &n1, &ptlen, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type)) -- GitLab