Skip to content
Snippets Groups Projects
Commit a64eaf49 authored by (no author)'s avatar (no author)
Browse files

This commit was manufactured by cvs2svn to create tag 'RELEASE_5_22'.

parent c8bcef18
No related branches found
No related tags found
No related merge requests found
Showing with 0 additions and 7919 deletions
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
# [<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list
# of files to check. A non-zero exit of the filter program will
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
# Set this to "no" if pserver shouldn't check system users/passwords
#SystemAuth=no
# Put CVS lock files in this directory rather than directly in the repository.
#LockDir=/var/lock/cvs
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no
# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
# history file, or a subset as needed (ie `TMAR' logs all write operations)
#LogHistory=TOFEWGCMAR
# This file affects handling of files based on their names.
#
# The -t/-f options allow one to treat directories of files
# as a single file, or to transform a file in other ways on
# its way in and out of CVS.
#
# The -m option specifies whether CVS attempts to merge files.
#
# The -k option specifies keyword expansion (e.g. -kb for binary).
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
# wildcard [option value][option value]...
#
# where option is one of
# -f from cvs filter value: path to filter
# -t to cvs filter value: path to filter
# -m update methodology value: MERGE or COPY
# -k expansion mode value: b, o, kkv, &c
#
# and value is a single-quote delimited value.
# For example:
#*.gif -k 'b'
# The "editinfo" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.
# The "loginfo" file controls where "cvs commit" log information
# is sent. The first entry on a line is a regular expression which must match
# the directory that the change is being made to, relative to the
# $CVSROOT. If a match is found, then the remainder of the line is a filter
# program that should expect log information on its standard input.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name ALL appears as a regular expression it is always used
# in addition to the first matching regex or DEFAULT.
#
# You may specify a format string as part of the
# filter. The string is composed of a `%' followed
# by a single format character, or followed by a set of format
# characters surrounded by `{' and `}' as separators. The format
# characters are:
#
# s = file name
# V = old version number (pre-checkin)
# v = new version number (post-checkin)
#
# For example:
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
# or
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
^sm5$ /cvsroot/sitedocs/CVSROOT/cvstools/syncmail -u %{sVv} smartmontools-cvs@lists.sourceforge.net
^www$ /cvsroot/sitedocs/CVSROOT/cvstools/syncmail -u %{sVv} ballen4705@users.sourceforge.net
# Three different line formats are valid:
# key -a aliases...
# key [options] directory
# key [options] directory files...
#
# Where "options" are composed of:
# -i prog Run "prog" on "cvs commit" from top-level of module.
# -o prog Run "prog" on "cvs checkout" of module.
# -e prog Run "prog" on "cvs export" of module.
# -t prog Run "prog" on "cvs rtag" of module.
# -u prog Run "prog" on "cvs update" of module.
# -d dir Place module in directory "dir" instead of module name.
# -l Top-level directory only -- do not recurse.
#
# NOTE: If you change any of the "Run" options above, you'll have to
# release and re-checkout any working directories of these modules.
#
# And "directory" is a path to a directory relative to $CVSROOT.
#
# The "-a" option specifies an alias. An alias is interpreted as if
# everything on the right of the "-a" had been typed on the command line.
#
# You can encode a module within a module by using the special '&'
# character to interpose another module into the current module. This
# can be useful for creating a module that consists of many directories
# spread out over the entire source repository.
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT. If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4-> file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
# The "verifymsg" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.
/*
* atacmdnames.c
*
* This module is based on the T13/1532D Volume 1 Revision 3 (ATA/ATAPI-7)
* specification, which is available from http://www.t13.org/#FTP_site
*
* Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
*
* Copyright (C) 2003 Philip Williams
*
* 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 Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "atacmdnames.h"
#include <stdlib.h>
#include <stdio.h>
#define COMMAND_TABLE_SIZE 256
const char *atacmdnames_c_cvsid="$Id: atacmdnames.cpp,v 1.9 2003/08/13 12:33:22 ballen4705 Exp $" ATACMDNAMES_H_CVSID;
const char cmd_reserved[] = "[RESERVED]";
const char cmd_vendor_specific[] = "[VENDOR SPECIFIC]";
const char cmd_reserved_sa[] = "[RESERVED FOR SERIAL ATA]";
const char cmd_reserved_cf[] = "[RESERVED FOR COMPACTFLASH ASSOCIATION]";
const char cmd_reserved_mcpt[] = "[RESERVED FOR MEDIA CARD PASS THROUGH]";
const char cmd_recalibrate_ret4[]= "RECALIBRATE [RET-4]";
const char cmd_seek_ret4[] = "SEEK [RET-4]";
const char *command_table[COMMAND_TABLE_SIZE] = {
/*-------------------------------------------------- 00h-0Fh -----*/
"NOP",
cmd_reserved,
cmd_reserved,
"CFA REQUEST EXTENDED ERROR CODE",
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
"DEVICE RESET",
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
/*-------------------------------------------------- 10h-1Fh -----*/
"RECALIBRATE [OBS-4]",
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
cmd_recalibrate_ret4,
/*-------------------------------------------------- 20h-2Fh -----*/
"READ SECTOR(S)",
"READ SECTOR(S) [OBS-5]",
"READ LONG (w/ retry) [OBS-4]",
"READ LONG (w/o retry) [OBS-4]",
"READ SECTOR(S) EXT",
"READ DMA EXT",
"READ DMA QUEUED EXT",
"READ NATIVE MAX ADDRESS EXT",
cmd_reserved,
"READ MULTIPLE EXT",
"READ STREAM DMA",
"READ STREAM PIO",
cmd_reserved,
cmd_reserved,
cmd_reserved,
"READ LOG EXT",
/*-------------------------------------------------- 30h-3Fh -----*/
"WRITE SECTOR(S)",
"WRITE SECTOR(S) [OBS-5]",
"WRITE LONG(w/ retry) [OBS-4]",
"WRITE LONG(w/o retry) [OBS-4]",
"WRITE SECTORS(S) EXT",
"WRITE DMA EXT",
"WRITE DMA QUEUED EXT",
"SET MAX ADDRESS EXT",
"CFA WRITE SECTORS WITHOUT ERASE",
"WRITE MULTIPLE EXT",
"WRITE STREAM DMA",
"WRITE STREAM PIO",
"WRITE VERIFY [OBS-4]",
"WRITE DMA FUA EXT",
"WRITE DMA QUEUED FUA EXT",
"WRITE LOG EXT",
/*-------------------------------------------------- 40h-4Fh -----*/
"READ VERIFY SECTOR(S)",
"READ VERIFY SECTOR(S) [OBS-5]",
"READ VERIFY SECTOR(S) EXT",
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
/*-------------------------------------------------- 50h-5Fh -----*/
"FORMAT TRACK [OBS-4]",
"CONFIGURE STREAM",
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
/*-------------------------------------------------- 60h-6Fh -----*/
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved_sa,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
/*-------------------------------------------------- 70h-7Fh -----*/
"SEEK [OBS-7]",
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
cmd_seek_ret4,
/*-------------------------------------------------- 80h-8Fh -----*/
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
"CFA TRANSLATE SECTOR [VS IF NO CFA]",
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
/*-------------------------------------------------- 90h-9Fh -----*/
"EXECUTE DEVICE DIAGNOSTIC",
"INITIALIZE DEVICE PARAMETERS [OBS-6]",
"DOWNLOAD MICROCODE",
cmd_reserved,
"STANDBY IMMEDIATE [RET-4]",
"IDLE IMMEDIATE [RET-4]",
"STANDBY [RET-4]",
"IDLE [RET-4]",
"CHECK POWER MODE [RET-4]",
"SLEEP [RET-4]",
cmd_vendor_specific,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
/*-------------------------------------------------- A0h-AFh -----*/
"PACKET",
"IDENTIFY PACKET DEVICE",
"SERVICE",
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
/*-------------------------------------------------- B0h-BFh -----*/
"SMART",
"DEVICE CONFIGURATION",
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved_cf,
cmd_reserved_cf,
cmd_reserved_cf,
cmd_reserved_cf,
cmd_reserved_cf,
cmd_reserved_cf,
cmd_reserved_cf,
cmd_reserved_cf,
/*-------------------------------------------------- C0h-CFh -----*/
"CFA ERASE SECTORS [VS IF NO CFA]",
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
"READ MULTIPLE",
"WRITE MULTIPLE",
"SET MULTIPLE MODE",
"READ DMA QUEUED",
"READ DMA",
"READ DMA [OBS-5]",
"WRITE DMA",
"WRITE DMA [OBS-5]",
"WRITE DMA QUEUED",
"CFA WRITE MULTIPLE WITHOUT ERASE",
"WRITE MULTIPLE FUA EXT",
cmd_reserved,
/*-------------------------------------------------- D0h-DFh -----*/
cmd_reserved,
"CHECK MEDIA CARD TYPE",
cmd_reserved_mcpt,
cmd_reserved_mcpt,
cmd_reserved_mcpt,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
cmd_reserved,
"GET MEDIA STATUS",
"ACKNOWLEDGE MEDIA CHANGE [RET-4]",
"BOOT POST-BOOT [RET-4]",
"BOOT PRE-BOOT [RET-4]",
"MEDIA LOCK",
"MEDIA UNLOCK",
/*-------------------------------------------------- E0h-EFh -----*/
"STANDBY IMMEDIATE",
"IDLE IMMEDIATE",
"STANDBY",
"IDLE",
"READ BUFFER",
"CHECK POWER MODE",
"SLEEP",
"FLUSH CACHE",
"WRITE BUFFER",
"WRITE SAME [RET-4]", /* Warning! This command is retired but the value of
f_reg is used in look_up_ata_command(). If this
command code is reclaimed in a future standard then
be sure to update look_up_ata_command(). */
"FLUSH CACHE EXIT",
cmd_reserved,
"IDENTIFY DEVICE",
"MEDIA EJECT",
"IDENTIFY DEVICE DMA [OBS-4]",
"SET FEATURES",
/*-------------------------------------------------- F0h-FFh -----*/
cmd_vendor_specific,
"SECURITY SET PASSWORD",
"SECURITY UNLOCK",
"SECURITY ERASE PREPARE",
"SECURITY ERASE UNIT",
"SECURITY FREEZE LOCK",
"SECURITY DISABLE PASSWORD",
cmd_vendor_specific,
"READ NATIVE MAX ADDRESS",
"SET MAX",
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific,
cmd_vendor_specific
};
/* Returns the name of the command (and possibly sub-command) with the given
command code and feature register values. For most command codes this
simply returns the corresponding entry in the command_table array, but for
others the value of the feature register specifies a subcommand or
distinguishes commands. */
const char *look_up_ata_command(unsigned char c_code, unsigned char f_reg) {
// check that command table not messed up. The compiler will issue
// warnings if there are too many array elements, but won't issue
// warnings if there are not enough of them.
if (sizeof(command_table) != sizeof(char *)*COMMAND_TABLE_SIZE){
fprintf(stderr,
"Problem in atacmdnames.c. Command Table command_table[] does\n"
"not have %d entries! It has %d entries. Please fix it.\n",
COMMAND_TABLE_SIZE, (int)(sizeof(command_table)/sizeof(char *)));
abort();
}
switch (c_code) {
case 0x00: /* NOP */
switch (f_reg) {
case 0x00:
return "NOP [Abort queued commands]";
case 0x01:
return "NOP [Don't abort queued commands]";
default:
return "NOP [Reserved subcommand]";
}
case 0x92: /* DOWNLOAD MICROCODE */
switch (f_reg) {
case 0x01:
return "DOWNLOAD MICROCODE [Temporary]";
case 0x07:
return "DOWNLOAD MICROCODE [Save]";
default:
return "DOWNLOAD MICROCODE [Reserved subcommand]";
}
case 0xB0: /* SMART */
switch (f_reg) {
case 0xD0:
return "SMART READ DATA";
case 0xD1:
return "SMART READ ATTRIBUTE THRESHOLDS [OBS-4]";
case 0xD2:
return "SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE";
case 0xD3:
return "SMART SAVE ATTRIBUTE VALUES [OBS-6]";
case 0xD4:
return "SMART EXECUTE OFF-LINE IMMEDIATE";
case 0xD5:
return "SMART READ LOG";
case 0xD6:
return "SMART WRITE LOG";
case 0xD7:
return "SMART WRITE ATTRIBUTE THRESHOLDS [NS, OBS-4]";
case 0xD8:
return "SMART ENABLE OPERATIONS";
case 0xD9:
return "SMART DISABLE OPERATIONS";
case 0xDA:
return "SMART RETURN STATUS";
case 0xDB:
return "SMART EN/DISABLE AUTO OFFLINE [NS (SFF-8035i)]";
default:
if (f_reg >= 0xE0)
return "[Vendor specific SMART command]";
else
return "[Reserved SMART command]";
}
case 0xB1: /* DEVICE CONFIGURATION */
switch (f_reg) {
case 0xC0:
return "DEVICE CONFIGURATION RESTORE";
case 0xC1:
return "DEVICE CONFIGURATION FREEZE LOCK";
case 0xC2:
return "DEVICE CONFIGURATION IDENTIFY";
case 0xC3:
return "DEVICE CONFIGURATION SET";
default:
return "DEVICE CONFIGURATION [Reserved command]";
}
case 0xE9: /* WRITE SAME */
switch (f_reg) {
case 0x22:
return "WRITE SAME [Start specified] [RET-4]";
case 0xDD:
return "WRITE SAME [Start unspecified] [RET-4]";
default:
return "WRITE SAME [Invalid subcommand] [RET-4]";
}
case 0xEF: /* SET FEATURES */
switch (f_reg) {
case 0x01:
return "SET FEATURES [Enable 8-bit PIO]";
case 0x02:
return "SET FEATURES [Enable write cache]";
case 0x03:
return "SET FEATURES [Set transfer mode]";
case 0x04:
return "SET FEATURES [Enable auto DR] [OBS-4]";
case 0x05:
return "SET FEATURES [Enable APM]";
case 0x06:
return "SET FEATURES [Enable Pwr-Up In Standby]";
case 0x07:
return "SET FEATURES [Set device spin-up]";
case 0x09:
return "SET FEATURES [Reserved (address offset)]";
case 0x0A:
return "SET FEATURES [Enable CFA power mode 1]";
case 0x10:
return "SET FEATURES [Reserved for Serial ATA]";
case 0x20:
return "SET FEATURES [Set Time-ltd R/W WCT]";
case 0x21:
return "SET FEATURES [Set Time-ltd R/W EH]";
case 0x31:
return "SET FEATURES [Disable Media Status Notf]";
case 0x33:
return "SET FEATURES [Disable retry] [OBS-4]";
case 0x42:
return "SET FEATURES [Enable AAM]";
case 0x43:
return "SET FEATURES [Set Max Host I/F S Times]";
case 0x44:
return "SET FEATURES [Length of VS data] [OBS-4]";
case 0x54:
return "SET FEATURES [Set cache segs] [OBS-4]";
case 0x55:
return "SET FEATURES [Disable read look-ahead]";
case 0x5D:
return "SET FEATURES [Enable release interrupt]";
case 0x5E:
return "SET FEATURES [Enable SERVICE interrupt]";
case 0x66:
return "SET FEATURES [Disable revert defaults]";
case 0x77:
return "SET FEATURES [Disable ECC] [OBS-4]";
case 0x81:
return "SET FEATURES [Disable 8-bit PIO]";
case 0x82:
return "SET FEATURES [Disable write cache]";
case 0x84:
return "SET FEATURES [Disable auto DR] [OBS-4]";
case 0x85:
return "SET FEATURES [Disable APM]";
case 0x86:
return "SET FEATURES [Disable Pwr-Up In Standby]";
case 0x88:
return "SET FEATURES [Disable ECC] [OBS-4]";
case 0x89:
return "SET FEATURES [Reserved (address offset)]";
case 0x8A:
return "SET FEATURES [Disable CFA power mode 1]";
case 0x90:
return "SET FEATURES [Reserved for Serial ATA]";
case 0x95:
return "SET FEATURES [Enable Media Status Notf]";
case 0x99:
return "SET FEATURES [Enable retries] [OBS-4]";
case 0x9A:
return "SET FEATURES [Set max avg curr] [OBS-4]";
case 0xAA:
return "SET FEATURES [Enable read look-ahead]";
case 0xAB:
return "SET FEATURES [Set max prefetch] [OBS-4]";
case 0xBB:
return "SET FEATURES [4 bytes VS data] [OBS-4]";
case 0xC2:
return "SET FEATURES [Disable AAM]";
case 0xCC:
return "SET FEATURES [Enable revert to defaults]";
case 0xDD:
return "SET FEATURES [Disable release interrupt]";
case 0xDE:
return "SET FEATURES [Disable SERVICE interrupt]";
case 0xE0:
return "SET FEATURES [Obsolete subcommand]";
default:
if (f_reg >= 0xF0)
return "SET FEATURES [Reserved for CFA]";
else
return "SET FEATURES [Reserved subcommand]";
}
case 0xF9: /* SET MAX */
switch (f_reg) {
case 0x00:
return "SET MAX ADDRESS [OBS-6]";
case 0x01:
return "SET MAX SET PASSWORD";
case 0x02:
return "SET MAX LOCK";
case 0x03:
return "SET MAX UNLOCK";
case 0x04:
return "SET MAX FREEZE LOCK";
default:
return "[Reserved SET MAX command]";
}
default:
return command_table[c_code];
}
}
This diff is collapsed.
This diff is collapsed.
/*
* knowndrives.c
*
* Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
*
* Copyright (C) 2003 Philip Williams, Bruce Allen
*
* 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 Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <regex.h>
#include "atacmds.h"
#include "ataprint.h"
#include "extern.h"
#include "knowndrives.h"
#include "utility.h"
#include "config.h"
const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.51 2003/10/27 18:57:24 pjwilliams Exp $"
ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
#define MODEL_STRING_LENGTH 40
#define FIRMWARE_STRING_LENGTH 8
#define TABLEPRINTWIDTH 19
// See vendorattributeargs[] array in atacmds.c for definitions.
#define PRESET_9_MINUTES { 9, 1 }
#define PRESET_9_TEMP { 9, 2 }
#define PRESET_9_SECONDS { 9, 3 }
#define PRESET_9_HALFMINUTES { 9, 4 }
#define PRESET_192_EMERGENCYRETRACTCYCLECT { 192, 1 }
#define PRESET_193_LOADUNLOAD { 193, 1 }
#define PRESET_194_10XCELSIUS { 194, 1 }
#define PRESET_194_UNKNOWN { 194, 2 }
#define PRESET_198_OFFLINESCANUNCSECTORCT { 198, 1 }
#define PRESET_200_WRITEERRORCOUNT { 200, 1 }
#define PRESET_201_DETECTEDTACOUNT { 201, 1 }
#define PRESET_220_TEMP { 220, 1 }
/* Arrays of preset vendor-specific attribute options for use in
* knowndrives[]. */
extern long long bytes;
// to hold onto exit code for atexit routine
extern int exitstatus;
// These two are common to several models.
const unsigned char vendoropts_9_minutes[][2] = {
PRESET_9_MINUTES,
{0,0}
};
const unsigned char vendoropts_9_seconds[][2] = {
PRESET_9_SECONDS,
{0,0}
};
const unsigned char vendoropts_Maxtor_4D080H4[][2] = {
PRESET_9_MINUTES,
PRESET_194_UNKNOWN,
{0,0}
};
const unsigned char vendoropts_Fujitsu_MHS2020AT[][2] = {
PRESET_9_SECONDS,
PRESET_192_EMERGENCYRETRACTCYCLECT,
PRESET_198_OFFLINESCANUNCSECTORCT,
PRESET_200_WRITEERRORCOUNT,
PRESET_201_DETECTEDTACOUNT,
{0,0}
};
const unsigned char vendoropts_Fujitsu_MHR2040AT[][2] = {
PRESET_9_SECONDS,
PRESET_192_EMERGENCYRETRACTCYCLECT,
PRESET_198_OFFLINESCANUNCSECTORCT,
PRESET_200_WRITEERRORCOUNT,
{0,0}
};
const unsigned char vendoropts_Samsung_SV4012H[][2] = {
PRESET_9_HALFMINUTES,
{0,0}
};
const unsigned char vendoropts_Samsung_SV1204H[][2] = {
PRESET_9_HALFMINUTES,
PRESET_194_10XCELSIUS,
{0,0}
};
const unsigned char vendoropts_Hitachi_DK23EA[][2] = {
PRESET_9_MINUTES,
PRESET_193_LOADUNLOAD,
{0,0}
};
const char same_as_minus_F[]="Fixes byte order in some SMART data (same as -F samsung)";
const char same_as_minus_F2[]="Fixes byte order in some SMART data (same as -F samsung2)";
const char may_need_minus_F_disabled[]="Contact developers at " PACKAGE_BUGREPORT "; may need -F samsung disabled";
const char may_need_minus_F2_disabled[]="Contact developers at " PACKAGE_BUGREPORT "; may need -F samsung2 disabled";
/* Special-purpose functions for use in knowndrives[]. */
void specialpurpose_reverse_samsung(smartmonctrl *con)
{
con->fixfirmwarebug = FIX_SAMSUNG;
}
void specialpurpose_reverse_samsung2(smartmonctrl *con)
{
con->fixfirmwarebug = FIX_SAMSUNG2;
}
/* Table of settings for known drives terminated by an element containing all
* zeros. The drivesettings structure is described in knowndrives.h. Note
* that lookupdrive() will search knowndrives[] from the start to end or
* until it finds the first match, so the order in knowndrives[] is important
* for distinct entries that could match the same drive. */
// Note that the table just below uses EXTENDED REGULAR EXPRESSIONS.
// A good on-line reference for these is:
// http://www.zeus.com/extra/docsystem/docroot/apps/web/docs/modules/access/regex.html
const drivesettings knowndrives[] = {
{ // IBM Deskstar 60GXP series
"IC35L0[12346]0AVER07",
".*",
"IBM Deskstar 60GXP drives may need upgraded SMART firmware.\n"
"Please see http://www.geocities.com/dtla_update/index.html#rel",
NULL, NULL, NULL
},
{ // IBM Deskstar 40GV & 75GXP series
"(IBM-)?DTLA-30[57]0[123467][05]$",
".*",
"IBM Deskstar 40GV and 75GXP drives may need upgraded SMART firmware.\n"
"Please see http://www.geocities.com/dtla_update/",
NULL, NULL, NULL
},
{ // Fujitsu MPD and MPE series
"^FUJITSU MP[DE]....A[HT]$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ // Fujitsu MHN2300AT
"^FUJITSU MHN2300AT$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ // Fujitsu MHR2040AT
"^FUJITSU MHR2040AT$",
".*", // Tested on 40BA
NULL,
vendoropts_Fujitsu_MHR2040AT,
NULL, NULL
},
{ // Fujitsu MHS2020AT
"^FUJITSU MHS2020AT$",
".*", // Tested on 8004
NULL,
vendoropts_Fujitsu_MHS2020AT,
NULL, NULL
},
{ // Fujitsu MHM2200AT
"^FUJITSU MHM2200AT$",
".*", // Tested with firmware version 3822
"The FUJITSU MHM2200AT firmware has a harmless Drive Identity\n"
"Structure checksum error bug.",
vendoropts_9_seconds,
NULL, NULL
},
{ // Samsung SV4012H (known firmware)
"^SAMSUNG SV4012H$",
"^RM100-08$",
NULL,
vendoropts_Samsung_SV4012H,
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ // Samsung SV4012H (match revision *-23 firmware)
"^SAMSUNG .*$",
".*-23$",
may_need_minus_F2_disabled,
vendoropts_Samsung_SV4012H,
specialpurpose_reverse_samsung2,
same_as_minus_F2
},
{ // Samsung SV4012H (all other firmware)
"^SAMSUNG SV4012H$",
".*",
may_need_minus_F_disabled,
vendoropts_Samsung_SV4012H,
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ // Samsung SV1204H (known firmware)
"^SAMSUNG SV1204H$",
"^RK100-1[3-5]$",
NULL,
vendoropts_Samsung_SV1204H,
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ //Samsung SV1204H (all other firmware)
"^SAMSUNG SV1204H$",
".*",
may_need_minus_F_disabled,
vendoropts_Samsung_SV1204H,
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ // Samsung SV0412H (known firmware)
"^SAMSUNG SV0412H$",
"^SK100-01$",
NULL,
vendoropts_Samsung_SV1204H,
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ // Samsung SV0412H (all other firmware)
"^SAMSUNG SV0412H$",
".*",
may_need_minus_F_disabled,
vendoropts_Samsung_SV1204H,
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ //Samsung SP1604N, tested with FW TM100-23
"^SAMSUNG SP1604N$",
".*",
NULL,
vendoropts_Samsung_SV4012H,
NULL,NULL
},
{ //SAMSUNG SV0322A with FW JK200-35
"^SAMSUNG SV0322A$",
".*",
NULL,
NULL,
NULL,
NULL
},
{ // Samsung ALL OTHER DRIVES
"^SAMSUNG.*",
".*",
"Contact developers at " PACKAGE_BUGREPORT "; may need -F samsung[2] enabled.\n",
NULL, NULL, NULL
},
{ // Maxtor 6L080J4 and 4K080H4
"^MAXTOR (6L080J4|4K080H4)$",
".*",
NULL, NULL, NULL, NULL
},
{ // Maxtor 4D080H4
"^Maxtor (4D080H4|4G120J6)$",
".*",
NULL,
vendoropts_Maxtor_4D080H4,
NULL, NULL
},
{ // Maxtor 4R080J0
"^Maxtor (4R080J0|4R080L0|6Y0[6|8]0L0|6Y1[2|6]0P0)$",
".*",
NULL,
vendoropts_9_minutes,
NULL, NULL
},
{ // Maxtor 6Y120P0 (known firmware)
"^Maxtor 6Y120P0$",
"^YAR41VW0$",
NULL,
vendoropts_9_minutes,
NULL, NULL
},
{ // Maxtor 6Y120P0 (any other firmware)
"^Maxtor 6Y120P0$",
".*",
"Contact developers at " PACKAGE_BUGREPORT "; may need -v 9,minutes enabled.\n",
NULL,
NULL, NULL
},
{ // HITACHI_DK23BA-20
"^HITACHI_DK23BA-20$",
".*",
NULL,
vendoropts_9_minutes,
NULL, NULL
},
{ // HITACHI_DK23EA-30
"^HITACHI_DK23EA-30$",
".*",
NULL,
vendoropts_Hitachi_DK23EA,
NULL, NULL
},
{ // IBM GXP-180
"^IC35L120AVV207-[01]$",
".*",
NULL, NULL, NULL, NULL
},
{
// IBM Deskstar 120GXP [Phil -- use for testing]
"^IC35L060AVVA07-[01]$",
".*",
NULL,
NULL,
NULL,
NULL,
},
{ // TOSHIBA MK4025GAS
"^TOSHIBA MK4025GAS$",
".*",
NULL, NULL, NULL, NULL
},
{
// TOSHIBA MK6021GAS [Bruce -- use for testing on laptop]
"^TOSHIBA MK6021GAS$",
".*",
NULL,
NULL,
NULL,
NULL,
},
/*------------------------------------------------------------
* End of table. Do not add entries below this marker.
*------------------------------------------------------------ */
{NULL, NULL, NULL, NULL, NULL, NULL}
};
// Searches knowndrives[] for a drive with the given model number and firmware
// string. If either the drive's model or firmware strings are not set by the
// manufacturer then values of NULL may be used. Returns the index of the
// first match in knowndrives[] or -1 if no match if found.
int lookupdrive(const char *model, const char *firmware)
{
regex_t regex;
int i, index;
const char *empty = "";
model = model ? model : empty;
firmware = firmware ? firmware : empty;
for (i = 0, index = -1; index == -1 && knowndrives[i].modelregexp; i++) {
// Attempt to compile regular expression.
if (compileregex(&regex, knowndrives[i].modelregexp, REG_EXTENDED))
goto CONTINUE;
// Check whether model matches the regular expression in knowndrives[i].
if (!regexec(&regex, model, 0, NULL, 0)) {
// model matches, now check firmware.
if (!knowndrives[i].firmwareregexp)
// The firmware regular expression in knowndrives[i] is NULL, which is
// considered a match.
index = i;
else {
// Compare firmware against the regular expression in knowndrives[i].
regfree(&regex); // Recycle regex.
if (compileregex(&regex, knowndrives[i].firmwareregexp, REG_EXTENDED))
goto CONTINUE;
if (!regexec(&regex, firmware, 0, NULL, 0))
index = i;
}
}
CONTINUE:
regfree(&regex);
}
return index;
}
// Shows all presets for drives in knowndrives[].
void showonepreset(const drivesettings *drivetable){
const unsigned char (* presets)[2] = drivetable->vendoropts;
int first_preset = 1;
// Basic error check
if (!drivetable || !drivetable->modelregexp){
pout("Null known drive table pointer. Please report\n"
"this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
return;
}
// print model and firmware regular expressions
pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", drivetable->modelregexp);
pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", drivetable->firmwareregexp ?
drivetable->firmwareregexp : "");
// if there are any presets, then show them
if (presets && (*presets)[0]) while (1) {
char out[256];
const int attr = (*presets)[0], val = (*presets)[1];
unsigned char fakearray[MAX_ATTRIBUTE_NUM];
// if we are at the end of the attribute list, break out
if (!attr)
break;
// This is a hack. ataPrintSmartAttribName() needs a pointer to an
// "array" to dereference, so we provide such a pointer.
fakearray[attr]=val;
ataPrintSmartAttribName(out, attr, fakearray);
// Use leading zeros instead of spaces so that everything lines up.
out[0] = (out[0] == ' ') ? '0' : out[0];
out[1] = (out[1] == ' ') ? '0' : out[1];
pout("%-*s %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "", out);
first_preset = 0;
presets++;
}
else
pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
// Is a special purpose function defined? If so, describe it
if (drivetable->specialpurpose){
pout("%-*s ", TABLEPRINTWIDTH, "OTHER PRESETS:");
pout("%s\n", drivetable->functiondesc ?
drivetable->functiondesc : "A special purpose function "
"is defined for this drive");
}
// Print any special warnings
if (drivetable->warningmsg){
pout("%-*s ", TABLEPRINTWIDTH, "WARNINGS:");
pout("%s\n", drivetable->warningmsg);
}
return;
}
void showallpresets(void){
int i;
// loop over all entries in the knowndrives[] table, printing them
// out in a nice format
for (i=0; knowndrives[i].modelregexp; i++){
showonepreset(&knowndrives[i]);
pout("\n");
}
return;
}
// Shows the presets (if any) that are available for the given drive.
void showpresets(const struct ata_identify_device *drive){
int i;
char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
// get the drive's model/firmware strings
formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
// and search to see if they match values in the table
if ((i = lookupdrive(model, firmware)) < 0) {
// no matches found
pout("No presets are defined for this drive. Its identity strings:\n"
"MODEL: %s\n"
"FIRMWARE: %s\n"
"do not match any of the known regular expressions.\n"
"Use -P showall to list all known regular expressions.\n",
model, firmware);
return;
}
// We found a matching drive. Print out all information about it.
pout("Drive found in smartmontools Database. Drive identity strings:\n"
"%-*s %s\n"
"%-*s %s\n"
"match smartmontools Drive Database entry:\n",
TABLEPRINTWIDTH, "MODEL:", model, TABLEPRINTWIDTH, "FIRMWARE:", firmware);
showonepreset(&knowndrives[i]);
return;
}
// Sets preset vendor attribute options in opts by finding the entry
// (if any) for the given drive in knowndrives[]. Values that have
// already been set in opts will not be changed. Returns <0 if drive
// not recognized else index >=0 into drive database.
int applypresets(const struct ata_identify_device *drive, unsigned char **optsptr,
smartmonctrl *con) {
int i;
unsigned char *opts;
char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
if (*optsptr==NULL)
bytes+=MAX_ATTRIBUTE_NUM;
if (*optsptr==NULL && !(*optsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM,1))){
pout("Unable to allocate memory in applypresets()");
bytes-=MAX_ATTRIBUTE_NUM;
EXIT(1);
}
opts=*optsptr;
// get the drive's model/firmware strings
formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
// Look up the drive in knowndrives[] and check vendoropts is non-NULL.
if ((i = lookupdrive(model, firmware)) >= 0 && knowndrives[i].vendoropts) {
const unsigned char (* presets)[2];
// For each attribute in list of attribute/val pairs...
presets = knowndrives[i].vendoropts;
while (1) {
const int attr = (*presets)[0];
const int val = (*presets)[1];
if (!attr)
break;
// ... set attribute if user hasn't already done so.
if (!opts[attr])
opts[attr] = val;
presets++;
}
// If a function is defined for this drive then call it.
if (knowndrives[i].specialpurpose)
(*knowndrives[i].specialpurpose)(con);
}
// return <0 if drive wasn't recognized, or index>=0 into database
// if it was
return i;
}
This diff is collapsed.
/*
* os_generic.c
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2003 NAME HERE <smartmontools-support@lists.sourceforge.net>
*
* 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 Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* This code was originally developed as a Senior Thesis by Michael Cornwell
* at the Concurrent Systems Laboratory (now part of the Storage Systems
* Research Center), Jack Baskin School of Engineering, University of
* California, Santa Cruz. http://ssrc.soe.ucsc.edu/
*
*/
/* PORTING NOTES AND COMMENTS
To port smartmontools to the OS of your choice, you need to:
[0] Contact smartmontools-support@lists.sourceforge.net to check that
it's not already been done.
[1] Make copies of os_generic.[hc] called os_myOS.[hc]
[2] Modify configure.in so that case "${host}" include myOS
[3] Verify that ./autogen.sh && ./configure && make compiles the code.
If not, fix any compilation problems.
[4] Provide the functions defined in this file: flesh out the
skeletons below. Note that for Darwin much of this already
exists. See some partially developed but incomplete code at:
http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5_Darwin/
[5] Contact smartmontools-support@lists.sourceforge.net to see about
checking your code into the smartmontools CVS archive.
*/
// These are needed to define prototypes for the functions defined below
#include "atacmds.h"
#include "scsicmds.h"
#include "utility.h"
// This is to include whatever prototypes you define in os_generic.h
#include "os_generic.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_generic.cpp,v 1.3 2003/10/17 05:14:33 ballen4705 Exp $" \
ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// tries to guess device type given the name (a path). See utility.h
// for return values.
int guess_device_type (const char* dev_name) {
return GUESS_DEVTYPE_DONT_KNOW;
}
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
// smartd. Returns number N of devices, or -1 if out of
// memory. Allocates N+1 arrays: one of N pointers (devlist), the
// others each contain null-terminated character strings.
int make_device_names (char*** devlist, const char* name) {
return 0;
}
// Like open(). Return positive integer handle, only used by
// functions below. type="ATA" or "SCSI". If you need to store extra
// information about your devices, create a private internal array
// within this file (see os_freebsd.c for an example).
int deviceopen(const char *pathname, char *type){
return -1;
}
// Like close(). Acts only on handles returned by above function.
int deviceclose(int fd){
return 0;
}
// Interface to ATA devices. See os_linux.c
int ata_command_interface(int fd, smart_command_set command, int select, char *data){
return -1;
}
// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
int escalade_command_interface(int fd, int disknum, smart_command_set command, int select, char *data){
return -1;
}
#include <errno.h>
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
return -ENOSYS;
}
This diff is collapsed.
/*
* os_solaris.c
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2003 Casper Dik <smartmontools-support@lists.sourceforge.net>
*
* 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 Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* This code was originally developed as a Senior Thesis by Michael Cornwell
* at the Concurrent Systems Laboratory (now part of the Storage Systems
* Research Center), Jack Baskin School of Engineering, University of
* California, Santa Cruz. http://ssrc.soe.ucsc.edu/
*
*/
/*
If you want to do a solaris port, some sample code, showing how to
access SCSI data under solaris, can be found here:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=2003721.204932.21807%40cable.prodigy.com
Please contact the smartmontools developers at:
smartmontools-support@lists.sourceforge.net
*/
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
// These are needed to define prototypes for the functions defined below
#include "config.h"
#include "atacmds.h"
#include "scsicmds.h"
#include "utility.h"
// This is to include whatever prototypes you define in os_solaris.h
#include "os_solaris.h"
extern long long bytes;
const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.8 2003/10/26 02:20:40 ballen4705 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// The printwarning() function warns about unimplemented functions
int printedout[2];
char *unimplemented[2]={
"ATA command routine ata_command_interface()",
"3ware Escalade Controller command routine escalade_command_interface()",
};
int printwarning(int which){
if (!unimplemented[which])
return 0;
if (printedout[which])
return 1;
printedout[which]=1;
pout("\n"
"#######################################################################\n"
"%s NOT IMPLEMENTED under Solaris.\n"
"Please contact " PACKAGE_BUGREPORT " if\n"
"you want to help in porting smartmontools to Solaris.\n"
"#######################################################################\n"
"\n",
unimplemented[which]);
return 1;
}
static const char *uscsidrvrs[] = {
"sd",
"ssd",
"st"
};
static const char *atadrvrs[] = {
"cmdk",
"dad",
};
static int
isdevtype(const char *dev_name, const char *table[], int tsize)
{
char devpath[MAXPATHLEN];
int i;
char *basename;
if (realpath(dev_name, devpath) == NULL)
return 0;
if ((basename = strrchr(devpath, '/')) == NULL)
return 0;
basename++;
for (i = 0; i < tsize; i++) {
int l = strlen(table[i]);
if (strncmp(basename, table[i], l) == 0 && basename[l] == '@')
return 1;
}
return 0;
}
static int
isscsidev(const char *path)
{
return isdevtype(path, uscsidrvrs, sizeof (uscsidrvrs) / sizeof (char *));
}
static int
isatadev(const char *path)
{
return isdevtype(path, atadrvrs, sizeof (atadrvrs) / sizeof (char *));
}
// tries to guess device type given the name (a path)
int guess_device_type (const char* dev_name) {
if (isscsidev(dev_name))
return GUESS_DEVTYPE_SCSI;
else if (isatadev(dev_name))
return GUESS_DEVTYPE_ATA;
else
return GUESS_DEVTYPE_DONT_KNOW;
}
struct pathlist {
char **names;
int nnames;
int maxnames;
};
static int
addpath(const char *path, struct pathlist *res)
{
if (++res->nnames > res->maxnames) {
res->maxnames += 16;
res->names = realloc(res->names, res->maxnames * sizeof (char *));
if (res->names == NULL)
return -1;
bytes += 16*sizeof(char *);
}
if (!(res->names[res->nnames-1] = CustomStrDup((char *)path, 1, __LINE__, __FILE__)))
return -1;
return 0;
}
static int
grokdir(const char *dir, struct pathlist *res, int testfun(const char *))
{
char pathbuf[MAXPATHLEN];
size_t len;
DIR *dp;
struct dirent *de;
int isdisk = strstr(dir, "dsk") != NULL;
char *p;
len = snprintf(pathbuf, sizeof (pathbuf), "%s/", dir);
if (len >= sizeof (pathbuf))
return -1;
dp = opendir(dir);
if (dp == NULL)
return 0;
while ((de = readdir(dp)) != NULL) {
if (de->d_name[0] == '.')
continue;
if (strlen(de->d_name) + len >= sizeof (pathbuf))
continue;
if (isdisk) {
/* Disk represented by slice 0 */
p = strstr(de->d_name, "s0");
/* String doesn't end in "s0\0" */
if (p == NULL || p[2] != '\0')
continue;
} else {
/* Tape drive represented by the all-digit device */
for (p = de->d_name; *p; p++)
if (!isdigit((int)(*p)))
break;
if (*p != '\0')
continue;
}
strcpy(&pathbuf[len], de->d_name);
if (testfun(pathbuf)) {
if (addpath(pathbuf, res) == -1) {
closedir(dp);
return -1;
}
}
}
closedir(dp);
return 0;
}
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
// smartd. Returns number of devices, or -1 if out of memory.
int make_device_names (char*** devlist, const char* name) {
struct pathlist res;
res.nnames = res.maxnames = 0;
res.names = NULL;
if (strcmp(name, "SCSI") == 0) {
if (grokdir("/dev/rdsk", &res, isscsidev) == -1)
return -1;
if (grokdir("/dev/rmt", &res, isscsidev) == -1)
return -1;
// shrink array to min possible size
res.names = realloc(res.names, res.nnames * sizeof (char *));
bytes -= sizeof(char *)*(res.maxnames-res.nnames);
// pass list back
*devlist = res.names;
return res.nnames;
}
// ATA case not implemented
*devlist=NULL;
return 0;
}
// Like open(). Return integer handle, used by functions below only.
// type="ATA" or "SCSI".
int deviceopen(const char *pathname, char *type){
if (!strcmp(type,"SCSI"))
return open(pathname, O_RDWR | O_NONBLOCK);
else if (!strcmp(type,"ATA"))
return open(pathname, O_RDONLY | O_NONBLOCK);
else
return -1;
}
// Like close(). Acts on handles returned by above function.
int deviceclose(int fd){
return close(fd);
}
// Interface to ATA devices. See os_linux.c
int ata_command_interface(int fd, smart_command_set command, int select, char *data){
if (printwarning(0))
return -1;
return -1;
}
// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
int escalade_command_interface(int fd, int disknum, smart_command_set command, int select, char *data){
if (printwarning(1))
return -1;
return -1;
}
#include <errno.h>
#include <sys/scsi/generic/commands.h>
#include <sys/scsi/generic/status.h>
#include <sys/scsi/impl/types.h>
#include <sys/scsi/impl/uscsi.h>
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
struct uscsi_cmd uscsi;
if (report > 0) {
int k;
const unsigned char * ucp = iop->cmnd;
const char * np;
np = scsi_get_opcode_name(ucp[0]);
pout(" [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < iop->cmnd_len; ++k)
pout("%02x ", ucp[k]);
if ((report > 1) &&
(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
else
pout("]");
}
memset(&uscsi, 0, sizeof (uscsi));
uscsi.uscsi_cdb = (void *)iop->cmnd;
uscsi.uscsi_cdblen = iop->cmnd_len;
if (iop->timeout == 0)
uscsi.uscsi_timeout = 60; /* XXX */
else
uscsi.uscsi_timeout = iop->timeout;
uscsi.uscsi_bufaddr = (void *)iop->dxferp;
uscsi.uscsi_buflen = iop->dxfer_len;
uscsi.uscsi_rqbuf = (void *)iop->sensep;
uscsi.uscsi_rqlen = iop->max_sense_len;
switch (iop->dxfer_dir) {
case DXFER_NONE:
case DXFER_FROM_DEVICE:
uscsi.uscsi_flags = USCSI_READ;
break;
case DXFER_TO_DEVICE:
uscsi.uscsi_flags = USCSI_WRITE;
break;
default:
return -EINVAL;
}
uscsi.uscsi_flags |= USCSI_ISOLATE;
if (ioctl(fd, USCSICMD, &uscsi))
return -errno;
iop->scsi_status = uscsi.uscsi_status;
iop->resid = uscsi.uscsi_resid;
iop->resp_sense_len = iop->max_sense_len - uscsi.uscsi_rqresid;
if (report > 0) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout(" status=0\n");
pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
return (0);
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment