Annotation of embedaddon/smartmontools/scsicmds.h, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * scsicmds.h
                      3:  *
                      4:  * Home page of code is: http://smartmontools.sourceforge.net
                      5:  *
                      6:  * Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
                      7:  * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
                      8:  *
                      9:  * Additional SCSI work:
                     10:  * Copyright (C) 2003-11 Douglas Gilbert <dgilbert@interlog.com>
                     11:  *
                     12:  * This program is free software; you can redistribute it and/or modify
                     13:  * it under the terms of the GNU General Public License as published by
                     14:  * the Free Software Foundation; either version 2, or (at your option)
                     15:  * any later version.
                     16:  *
                     17:  * You should have received a copy of the GNU General Public License
                     18:  * (for example COPYING); if not, write to the Free
                     19:  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20:  *
                     21:  * This code was originally developed as a Senior Thesis by Michael Cornwell
                     22:  * at the Concurrent Systems Laboratory (now part of the Storage Systems
                     23:  * Research Center), Jack Baskin School of Engineering, University of
                     24:  * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
                     25:  *
                     26:  * N.B. What was formerly known as "SMART" are now called "informational
                     27:  * exceptions" in recent t10.org drafts (i.e. recent SCSI).
                     28:  *
                     29:  */
                     30: 
                     31: 
                     32: #ifndef SCSICMDS_H_
                     33: #define SCSICMDS_H_
                     34: 
                     35: #define SCSICMDS_H_CVSID "$Id: scsicmds.h 3413 2011-09-06 21:23:00Z dpgilbert $\n"
                     36: 
                     37: #include <stdio.h>
                     38: #include <stdlib.h>
                     39: #include <string.h>
                     40: 
                     41: /* #define SCSI_DEBUG 1 */ /* Comment out to disable command debugging */
                     42: 
                     43: /* Following conditional defines just in case OS already has them defined.
                     44:  * If they are defined we hope they are defined correctly (for SCSI). */
                     45: #ifndef TEST_UNIT_READY
                     46: #define TEST_UNIT_READY 0x0
                     47: #endif
                     48: #ifndef LOG_SELECT
                     49: #define LOG_SELECT 0x4c
                     50: #endif
                     51: #ifndef LOG_SENSE
                     52: #define LOG_SENSE 0x4d
                     53: #endif
                     54: #ifndef MODE_SENSE
                     55: #define MODE_SENSE 0x1a
                     56: #endif
                     57: #ifndef MODE_SENSE_10
                     58: #define MODE_SENSE_10 0x5a
                     59: #endif
                     60: #ifndef MODE_SELECT
                     61: #define MODE_SELECT 0x15
                     62: #endif
                     63: #ifndef MODE_SELECT_10
                     64: #define MODE_SELECT_10 0x55
                     65: #endif
                     66: #ifndef INQUIRY
                     67: #define INQUIRY 0x12
                     68: #endif
                     69: #ifndef REQUEST_SENSE
                     70: #define REQUEST_SENSE  0x03
                     71: #endif
                     72: #ifndef RECEIVE_DIAGNOSTIC
                     73: #define RECEIVE_DIAGNOSTIC  0x1c
                     74: #endif
                     75: #ifndef SEND_DIAGNOSTIC
                     76: #define SEND_DIAGNOSTIC  0x1d
                     77: #endif
                     78: #ifndef READ_DEFECT_10
                     79: #define READ_DEFECT_10  0x37
                     80: #endif
                     81: #ifndef START_STOP_UNIT
                     82: #define START_STOP_UNIT  0x1b
                     83: #endif
                     84: #ifndef REPORT_LUNS
                     85: #define REPORT_LUNS  0xa0
                     86: #endif
                     87: #ifndef READ_CAPACITY_10
                     88: #define READ_CAPACITY_10  0x25
                     89: #endif
                     90: #ifndef READ_CAPACITY_16
                     91: #define READ_CAPACITY_16  0x9e
                     92: #endif
                     93: #ifndef SAI_READ_CAPACITY_16    /* service action for READ_CAPACITY_16 */
                     94: #define SAI_READ_CAPACITY_16  0x10
                     95: #endif
                     96: 
                     97: #ifndef SAT_ATA_PASSTHROUGH_12
                     98: #define SAT_ATA_PASSTHROUGH_12 0xa1
                     99: #endif
                    100: #ifndef SAT_ATA_PASSTHROUGH_16
                    101: #define SAT_ATA_PASSTHROUGH_16 0x85
                    102: #endif
                    103: 
                    104: typedef unsigned char UINT8;
                    105: typedef signed char INT8;
                    106: typedef unsigned int UINT32;
                    107: typedef int INT32;
                    108: 
                    109: #define DXFER_NONE        0
                    110: #define DXFER_FROM_DEVICE 1
                    111: #define DXFER_TO_DEVICE   2
                    112: 
                    113: struct scsi_cmnd_io
                    114: {
                    115:     UINT8 * cmnd;       /* [in]: ptr to SCSI command block (cdb) */
                    116:     size_t  cmnd_len;   /* [in]: number of bytes in SCSI command */
                    117:     int dxfer_dir;      /* [in]: DXFER_NONE, DXFER_FROM_DEVICE, or 
                    118:                                  DXFER_TO_DEVICE */
                    119:     UINT8 * dxferp;     /* [in]: ptr to outgoing or incoming data buffer */
                    120:     size_t dxfer_len;   /* [in]: bytes to be transferred to/from dxferp */
                    121:     UINT8 * sensep;     /* [in]: ptr to sense buffer, filled when 
                    122:                                  CHECK CONDITION status occurs */
                    123:     size_t max_sense_len; /* [in]: max number of bytes to write to sensep */
                    124:     unsigned timeout;   /* [in]: seconds, 0-> default timeout (60 seconds?) */
                    125:     size_t resp_sense_len;  /* [out]: sense buffer length written */
                    126:     UINT8 scsi_status;  /* [out]: 0->ok, 2->CHECK CONDITION, etc ... */
                    127:     int resid;          /* [out]: Number of bytes requested to be transferred
                    128:                                   less actual number transferred (0 if not
                    129:                                    supported) */
                    130: };
                    131: 
                    132: struct scsi_sense_disect {
                    133:     UINT8 error_code;
                    134:     UINT8 sense_key;
                    135:     UINT8 asc; 
                    136:     UINT8 ascq;
                    137: };
                    138: 
                    139: /* Useful data from Informational Exception Control mode page (0x1c) */
                    140: #define SCSI_IECMP_RAW_LEN 64
                    141: struct scsi_iec_mode_page {
                    142:     UINT8 requestedCurrent;
                    143:     UINT8 gotCurrent;
                    144:     UINT8 requestedChangeable;
                    145:     UINT8 gotChangeable;
                    146:     UINT8 modese_len;   /* 0 (don't know), 6 or 10 */
                    147:     UINT8 raw_curr[SCSI_IECMP_RAW_LEN];
                    148:     UINT8 raw_chg[SCSI_IECMP_RAW_LEN];
                    149: };
                    150: 
                    151: /* Carrier for Error counter log pages (e.g. read, write, verify ...) */
                    152: struct scsiErrorCounter {
                    153:     UINT8 gotPC[7];
                    154:     UINT8 gotExtraPC;
                    155:     uint64_t counter[8];
                    156: };
                    157: 
                    158: /* Carrier for Non-medium error log page */
                    159: struct scsiNonMediumError {
                    160:     UINT8 gotPC0;
                    161:     UINT8 gotExtraPC;
                    162:     uint64_t counterPC0;
                    163:     UINT8 gotTFE_H;
                    164:     uint64_t counterTFE_H; /* Track following errors [Hitachi] */
                    165:     UINT8 gotPE_H;
                    166:     uint64_t counterPE_H;  /* Positioning errors [Hitachi] */
                    167: };
                    168: 
                    169: /* SCSI Peripheral types (of interest) */
                    170: #define SCSI_PT_DIRECT_ACCESS           0x0
                    171: #define SCSI_PT_SEQUENTIAL_ACCESS       0x1
                    172: #define SCSI_PT_CDROM                   0x5
                    173: #define SCSI_PT_MEDIUM_CHANGER          0x8
                    174: #define SCSI_PT_ENCLOSURE               0xd
                    175: 
                    176: /* ANSI SCSI-3 Log Pages retrieved by LOG SENSE. */
                    177: #define SUPPORTED_LPAGES                        0x00
                    178: #define BUFFER_OVERRUN_LPAGE                    0x01
                    179: #define WRITE_ERROR_COUNTER_LPAGE               0x02
                    180: #define READ_ERROR_COUNTER_LPAGE                0x03
                    181: #define READ_REVERSE_ERROR_COUNTER_LPAGE        0x04
                    182: #define VERIFY_ERROR_COUNTER_LPAGE              0x05
                    183: #define NON_MEDIUM_ERROR_LPAGE                  0x06
                    184: #define LAST_N_ERROR_LPAGE                      0x07
                    185: #define FORMAT_STATUS_LPAGE                     0x08
                    186: #define LB_PROV_LPAGE                           0x0c   /* SBC-3 */
                    187: #define TEMPERATURE_LPAGE                       0x0d
                    188: #define STARTSTOP_CYCLE_COUNTER_LPAGE           0x0e
                    189: #define APPLICATION_CLIENT_LPAGE                0x0f
                    190: #define SELFTEST_RESULTS_LPAGE                  0x10
                    191: #define SS_MEDIA_LPAGE                          0x11   /* SBC-3 */
                    192: #define BACKGROUND_RESULTS_LPAGE                0x15   /* SBC-3 */
                    193: #define NONVOL_CACHE_LPAGE                      0x17   /* SBC-3 */
                    194: #define PROTOCOL_SPECIFIC_LPAGE                 0x18
                    195: #define IE_LPAGE                                0x2f
                    196: 
                    197: /* Seagate vendor specific log pages. */
                    198: #define SEAGATE_CACHE_LPAGE                     0x37
                    199: #define SEAGATE_FACTORY_LPAGE                   0x3e
                    200: 
                    201: /* Log page response lengths */
                    202: #define LOG_RESP_SELF_TEST_LEN 0x194
                    203: 
                    204: /* See the SSC-2 document at www.t10.org . Earler note: From IBM 
                    205: Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
                    206: #define TAPE_ALERTS_LPAGE                        0x2e
                    207: 
                    208: /* ANSI SCSI-3 Mode Pages */
                    209: #define VENDOR_UNIQUE_PAGE                       0x00
                    210: #define READ_WRITE_ERROR_RECOVERY_PAGE           0x01
                    211: #define DISCONNECT_RECONNECT_PAGE                0x02
                    212: #define FORMAT_DEVICE_PAGE                       0x03
                    213: #define RIGID_DISK_DRIVE_GEOMETRY_PAGE           0x04
                    214: #define FLEXIBLE_DISK_PAGE                       0x05
                    215: #define VERIFY_ERROR_RECOVERY_PAGE               0x07
                    216: #define CACHING_PAGE                             0x08
                    217: #define PERIPHERAL_DEVICE_PAGE                   0x09
                    218: #define XOR_CONTROL_MODE_PAGE                    0x10
                    219: #define CONTROL_MODE_PAGE                        0x0a
                    220: #define MEDIUM_TYPES_SUPPORTED_PAGE              0x0b
                    221: #define NOTCH_PAGE                               0x0c
                    222: #define CD_DEVICE_PAGE                           0x0d
                    223: #define CD_AUDIO_CONTROL_PAGE                    0x0e
                    224: #define DATA_COMPRESSION_PAGE                    0x0f
                    225: #define ENCLOSURE_SERVICES_MANAGEMENT_PAGE       0x14
                    226: #define PROTOCOL_SPECIFIC_LUN_PAGE               0x18
                    227: #define PROTOCOL_SPECIFIC_PORT_PAGE              0x19
                    228: #define POWER_CONDITION_PAGE                     0x1a
                    229: #define INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE    0x1c
                    230: #define FAULT_FAILURE_REPORTING_PAGE             0x1c
                    231: 
                    232: /* Background control mode subpage is [0x1c,0x1] */
                    233: #define BACKGROUND_CONTROL_M_SUBPAGE             0x1   /* SBC-2 */
                    234: 
                    235: #define ALL_MODE_PAGES                           0x3f
                    236: 
                    237: /* Mode page control field */
                    238: #define MPAGE_CONTROL_CURRENT               0
                    239: #define MPAGE_CONTROL_CHANGEABLE            1
                    240: #define MPAGE_CONTROL_DEFAULT               2
                    241: #define MPAGE_CONTROL_SAVED                 3
                    242: 
                    243: /* defines for useful SCSI Status codes */
                    244: #define SCSI_STATUS_CHECK_CONDITION     0x2
                    245: 
                    246: /* defines for useful Sense Key codes */
                    247: #define SCSI_SK_NO_SENSE                0x0
                    248: #define SCSI_SK_RECOVERED_ERR           0x1
                    249: #define SCSI_SK_NOT_READY               0x2
                    250: #define SCSI_SK_MEDIUM_ERROR            0x3
                    251: #define SCSI_SK_HARDWARE_ERROR          0x4
                    252: #define SCSI_SK_ILLEGAL_REQUEST         0x5
                    253: #define SCSI_SK_UNIT_ATTENTION          0x6
                    254: #define SCSI_SK_ABORTED_COMMAND         0xb
                    255: 
                    256: /* defines for useful Additional Sense Codes (ASCs) */
                    257: #define SCSI_ASC_NOT_READY              0x4     /* more info in ASCQ code */
                    258: #define SCSI_ASC_NO_MEDIUM              0x3a    /* more info in ASCQ code */
                    259: #define SCSI_ASC_UNKNOWN_OPCODE         0x20
                    260: #define SCSI_ASC_UNKNOWN_FIELD          0x24
                    261: #define SCSI_ASC_UNKNOWN_PARAM          0x26
                    262: #define SCSI_ASC_WARNING                0xb
                    263: #define SCSI_ASC_IMPENDING_FAILURE      0x5d
                    264: 
                    265: #define SCSI_ASCQ_ATA_PASS_THROUGH      0x1d
                    266: 
                    267: /* Simplified error code (negative values as per errno) */
                    268: #define SIMPLE_NO_ERROR                 0
                    269: #define SIMPLE_ERR_NOT_READY            1
                    270: #define SIMPLE_ERR_BAD_OPCODE           2
                    271: #define SIMPLE_ERR_BAD_FIELD            3       /* in cbd */
                    272: #define SIMPLE_ERR_BAD_PARAM            4       /* in data */
                    273: #define SIMPLE_ERR_BAD_RESP             5       /* response fails sanity */
                    274: #define SIMPLE_ERR_NO_MEDIUM            6       /* no medium present */
                    275: #define SIMPLE_ERR_BECOMING_READY       7       /* device will be ready soon */
                    276: #define SIMPLE_ERR_TRY_AGAIN            8       /* some warning, try again */
                    277: #define SIMPLE_ERR_MEDIUM_HARDWARE      9       /* medium or hardware error */
                    278: #define SIMPLE_ERR_UNKNOWN              10      /* unknown sense value */
                    279: #define SIMPLE_ERR_ABORTED_COMMAND      11      /* most likely transport error */
                    280: 
                    281: 
                    282: /* defines for functioncode parameter in SENDDIAGNOSTIC function */
                    283: #define SCSI_DIAG_NO_SELF_TEST          0x00
                    284: #define SCSI_DIAG_DEF_SELF_TEST         0xff
                    285: #define SCSI_DIAG_BG_SHORT_SELF_TEST    0x01
                    286: #define SCSI_DIAG_BG_EXTENDED_SELF_TEST 0x02
                    287: #define SCSI_DIAG_FG_SHORT_SELF_TEST    0x05
                    288: #define SCSI_DIAG_FG_EXTENDED_SELF_TEST 0x06
                    289: #define SCSI_DIAG_ABORT_SELF_TEST       0x04
                    290: 
                    291: 
                    292: /* SCSI command timeout values (units are seconds) */
                    293: #define SCSI_TIMEOUT_DEFAULT    20  // should be longer than the spin up time
                    294:                                     // of a disk in standby mode.
                    295: #define SCSI_TIMEOUT_SELF_TEST  (5 * 60 * 60)   /* allow max 5 hours for */
                    296:                                             /* extended foreground self test */
                    297: 
                    298: 
                    299: 
                    300: #define LOGPAGEHDRSIZE  4
                    301: 
                    302: class scsi_device;
                    303: 
                    304: // Print SCSI debug messages?
                    305: extern unsigned char scsi_debugmode;
                    306: 
                    307: void scsi_do_sense_disect(const struct scsi_cmnd_io * in,
                    308:                           struct scsi_sense_disect * out);
                    309: 
                    310: int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo);
                    311: 
                    312: const char * scsiErrString(int scsiErr);
                    313: 
                    314: int scsi_vpd_dev_id_iter(const unsigned char * initial_desig_desc,
                    315:                          int page_len, int * off, int m_assoc,
                    316:                          int m_desig_type, int m_code_set);
                    317: 
                    318: int scsi_decode_lu_dev_id(const unsigned char * b, int blen, char * s,
                    319:                           int slen, int * transport);
                    320: 
                    321: 
                    322: /* STANDARD SCSI Commands  */
                    323: int scsiTestUnitReady(scsi_device * device);
                    324: 
                    325: int scsiStdInquiry(scsi_device * device, UINT8 *pBuf, int bufLen);
                    326: 
                    327: int scsiInquiryVpd(scsi_device * device, int vpd_page, UINT8 *pBuf, int bufLen);
                    328: 
                    329: int scsiLogSense(scsi_device * device, int pagenum, int subpagenum, UINT8 *pBuf,
                    330:                  int bufLen, int known_resp_len);
                    331: 
                    332: int scsiLogSelect(scsi_device * device, int pcr, int sp, int pc, int pagenum,
                    333:                   int subpagenum, UINT8 *pBuf, int bufLen);
                    334: 
                    335: int scsiModeSense(scsi_device * device, int pagenum, int subpagenum, int pc,
                    336:                   UINT8 *pBuf, int bufLen);
                    337: 
                    338: int scsiModeSelect(scsi_device * device, int sp, UINT8 *pBuf, int bufLen);
                    339: 
                    340: int scsiModeSense10(scsi_device * device, int pagenum, int subpagenum, int pc,
                    341:                     UINT8 *pBuf, int bufLen);
                    342: 
                    343: int scsiModeSelect10(scsi_device * device, int sp, UINT8 *pBuf, int bufLen);
                    344: 
                    345: int scsiModePageOffset(const UINT8 * resp, int len, int modese_len);
                    346: 
                    347: int scsiRequestSense(scsi_device * device, struct scsi_sense_disect * sense_info);
                    348: 
                    349: int scsiSendDiagnostic(scsi_device * device, int functioncode, UINT8 *pBuf, int bufLen);
                    350: 
                    351: int scsiReceiveDiagnostic(scsi_device * device, int pcv, int pagenum, UINT8 *pBuf,
                    352:                       int bufLen);
                    353: 
                    354: int scsiReadDefect10(scsi_device * device, int req_plist, int req_glist, int dl_format,
                    355:                      UINT8 *pBuf, int bufLen);
                    356: 
                    357: int scsiReadCapacity10(scsi_device * device, unsigned int * last_lbp,
                    358:                        unsigned int * lb_sizep);
                    359: 
                    360: int scsiReadCapacity16(scsi_device * device, UINT8 *pBuf, int bufLen);
                    361: 
                    362: uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep);
                    363: 
                    364: 
                    365: /* SMART specific commands */
                    366: int scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage, UINT8 *asc,
                    367:                 UINT8 *ascq, UINT8 *currenttemp, UINT8 *triptemp);
                    368: 
                    369: int scsiFetchIECmpage(scsi_device * device, struct scsi_iec_mode_page *iecp,
                    370:                       int modese_len);
                    371: int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp);
                    372: int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp);
                    373: int scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
                    374:                             const struct scsi_iec_mode_page *iecp);
                    375: void scsiDecodeErrCounterPage(unsigned char * resp,
                    376:                               struct scsiErrorCounter *ecp);
                    377: void scsiDecodeNonMediumErrPage(unsigned char * resp,
                    378:                                 struct scsiNonMediumError *nmep);
                    379: int scsiFetchExtendedSelfTestTime(scsi_device * device, int * durationSec,
                    380:                                   int modese_len);
                    381: int scsiCountFailedSelfTests(scsi_device * device, int noisy);
                    382: int scsiSelfTestInProgress(scsi_device * device, int * inProgress);
                    383: int scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current);
                    384: int scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len);
                    385: int scsiFetchTransportProtocol(scsi_device * device, int modese_len);
                    386: 
                    387: 
                    388: /* T10 Standard IE Additional Sense Code strings taken from t10.org */
                    389: const char* scsiGetIEString(UINT8 asc, UINT8 ascq);
                    390: int scsiGetTemp(scsi_device * device, UINT8 *currenttemp, UINT8 *triptemp);
                    391: 
                    392: 
                    393: int scsiSmartIBMOfflineTest(scsi_device * device);
                    394: 
                    395: int scsiSmartDefaultSelfTest(scsi_device * device);
                    396: int scsiSmartShortSelfTest(scsi_device * device);
                    397: int scsiSmartExtendSelfTest(scsi_device * device);
                    398: int scsiSmartShortCapSelfTest(scsi_device * device);
                    399: int scsiSmartExtendCapSelfTest(scsi_device * device);
                    400: int scsiSmartSelfTestAbort(scsi_device * device);
                    401: 
                    402: const char * scsiTapeAlertsTapeDevice(unsigned short code);
                    403: const char * scsiTapeAlertsChangerDevice(unsigned short code);
                    404: 
                    405: const char * scsi_get_opcode_name(UINT8 opcode);
                    406: void dStrHex(const char* str, int len, int no_ascii);
                    407: inline void dStrHex(const unsigned char* str, int len, int no_ascii)
                    408:   { dStrHex((const char *)str, len, no_ascii); }
                    409: 
                    410: 
                    411: /* SCSI command transmission interface function declaration. Its
                    412:  * definition is target OS specific (see os_<OS>.c file).
                    413:  * Returns 0 if SCSI command successfully launched and response
                    414:  * received. Even when 0 is returned the caller should check
                    415:  * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
                    416:  * (e.g. CHECK CONDITION). If the SCSI command could not be issued
                    417:  * (e.g. device not present or not a SCSI device) or some other problem
                    418:  * arises (e.g. timeout) then returns a negative errno value. */
                    419: // Moved to C++ interface
                    420: //int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
                    421: 
                    422: 
                    423: 
                    424: #endif
                    425: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>