From e020d8f8b24189a5b357d12217e2fcde0cb310fd Mon Sep 17 00:00:00 2001 From: Guido Guenther Date: Sun, 23 Apr 2006 18:39:04 +0200 Subject: [PATCH] add debian specific patches --- debian/patches/00list | 5 + debian/patches/01_add-kfreebsd-support.dpatch | 20 + debian/patches/02_remove-pragma.dpatch | 131 +++ .../03_use-smartd-runner-by-default.dpatch | 20 + .../04_remove-Id-from-smartd.conf.dpatch | 24 + debian/patches/10_remove-redhadism.dpatch | 27 + debian/patches/60_cciss.dpatch | 757 ++++++++++++++++++ 7 files changed, 984 insertions(+) create mode 100755 debian/patches/00list create mode 100755 debian/patches/01_add-kfreebsd-support.dpatch create mode 100755 debian/patches/02_remove-pragma.dpatch create mode 100755 debian/patches/03_use-smartd-runner-by-default.dpatch create mode 100755 debian/patches/04_remove-Id-from-smartd.conf.dpatch create mode 100755 debian/patches/10_remove-redhadism.dpatch create mode 100644 debian/patches/60_cciss.dpatch diff --git a/debian/patches/00list b/debian/patches/00list new file mode 100755 index 0000000..be0d636 --- /dev/null +++ b/debian/patches/00list @@ -0,0 +1,5 @@ +01_add-kfreebsd-support +02_remove-pragma +03_use-smartd-runner-by-default +04_remove-Id-from-smartd.conf +10_remove-redhadism diff --git a/debian/patches/01_add-kfreebsd-support.dpatch b/debian/patches/01_add-kfreebsd-support.dpatch new file mode 100755 index 0000000..707fac3 --- /dev/null +++ b/debian/patches/01_add-kfreebsd-support.dpatch @@ -0,0 +1,20 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 01_add-kfreebsd-support.dpatch by Guido Guenther +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: add kfreebsd support to configure.in + +@DPATCH@ + +diff -u -Naur smartmontools-5.33+5.34cvs20050802.orig/configure.in smartmontools-5.33+5.34cvs20050802/configure.in +--- smartmontools-5.33+5.34cvs20050802.orig/configure.in 2005-04-20 09:38:44.000000000 +0200 ++++ smartmontools-5.33+5.34cvs20050802/configure.in 2006-02-28 17:38:26.000000000 +0100 +@@ -129,7 +129,7 @@ + *-*-linux*) + AC_SUBST([os_deps], ['os_linux.o']) + AC_SUBST([os_libs], ['']) ;; +- *-*-freebsd*) ++ *-*-freebsd* | *-*-kfreebsd*-gnu) + AC_SUBST([os_deps], ['os_freebsd.o']) + AC_SUBST([os_libs], ['-lcam']);; + sparc-*-solaris*) diff --git a/debian/patches/02_remove-pragma.dpatch b/debian/patches/02_remove-pragma.dpatch new file mode 100755 index 0000000..c9362f8 --- /dev/null +++ b/debian/patches/02_remove-pragma.dpatch @@ -0,0 +1,131 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 02_remove-progma.dpatch by Guido Guenther +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: remove #pragma since this causes trouble on arm + +@DPATCH@ + +diff -u -Naur smartmontools-5.33+5.34cvs20050802.orig/atacmds.h smartmontools-5.33+5.34cvs20050802/atacmds.h +--- smartmontools-5.33+5.34cvs20050802.orig/atacmds.h 2005-05-10 21:15:47.000000000 +0200 ++++ smartmontools-5.33+5.34cvs20050802/atacmds.h 2006-02-28 17:38:26.000000000 +0100 +@@ -105,7 +105,6 @@ + + // Needed parts of the ATA DRIVE IDENTIFY Structure. Those labeled + // word* are NOT used. +-#pragma pack(1) + struct ata_identify_device { + unsigned short words000_009[10]; + unsigned char serial_no[20]; +@@ -127,7 +126,6 @@ + ASSERT_SIZEOF_STRUCT(ata_identify_device, 512); + + /* ata_smart_attribute is the vendor specific in SFF-8035 spec */ +-#pragma pack(1) + struct ata_smart_attribute { + unsigned char id; + // meaning of flag bits: see MACROS just below +@@ -187,7 +185,6 @@ + + /* 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 */ +-#pragma pack(1) + struct ata_smart_values { + unsigned short int revnumber; + struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES]; +@@ -219,7 +216,6 @@ + */ + + /* Vendor attribute of SMART Threshold (compare to ata_smart_attribute above) */ +-#pragma pack(1) + struct ata_smart_threshold_entry { + unsigned char id; + unsigned char threshold; +@@ -230,7 +226,6 @@ + + /* Format of Read SMART THreshold Command */ + /* Compare to ata_smart_values above */ +-#pragma pack(1) + struct ata_smart_thresholds_pvt { + unsigned short int revnumber; + struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES]; +@@ -242,7 +237,6 @@ + + + // Table 42 of T13/1321D Rev 1 spec (Error Data Structure) +-#pragma pack(1) + struct ata_smart_errorlog_error_struct { + unsigned char reserved; + unsigned char error_register; +@@ -261,7 +255,6 @@ + + + // Table 41 of T13/1321D Rev 1 spec (Command Data Structure) +-#pragma pack(1) + struct ata_smart_errorlog_command_struct { + unsigned char devicecontrolreg; + unsigned char featuresreg; +@@ -277,7 +270,6 @@ + ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_command_struct, 12); + + // Table 40 of T13/1321D Rev 1 spec (Error log data structure) +-#pragma pack(1) + struct ata_smart_errorlog_struct { + struct ata_smart_errorlog_command_struct commands[5]; + struct ata_smart_errorlog_error_struct error_struct; +@@ -286,7 +278,6 @@ + ASSERT_SIZEOF_STRUCT(ata_smart_errorlog_struct, 90); + + // Table 39 of T13/1321D Rev 1 spec (SMART error log sector) +-#pragma pack(1) + struct ata_smart_errorlog { + unsigned char revnumber; + unsigned char error_log_pointer; +@@ -299,7 +290,6 @@ + ASSERT_SIZEOF_STRUCT(ata_smart_errorlog, 512); + + // Table 45 of T13/1321D Rev 1 spec (Self-test log descriptor entry) +-#pragma pack(1) + struct ata_smart_selftestlog_struct { + unsigned char selftestnumber; // Sector number register + unsigned char selfteststatus; +@@ -312,7 +302,6 @@ + ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog_struct, 24); + + // Table 44 of T13/1321D Rev 1 spec (Self-test log data structure) +-#pragma pack(1) + struct ata_smart_selftestlog { + unsigned short int revnumber; + struct ata_smart_selftestlog_struct selftest_struct[21]; +@@ -325,7 +314,6 @@ + ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog, 512); + + // SMART LOG DIRECTORY Table 52 of T13/1532D Vol 1 Rev 1a +-#pragma pack(1) + struct ata_smart_log_entry { + unsigned char numsectors; + unsigned char reserved; +@@ -333,7 +321,6 @@ + #pragma pack() + ASSERT_SIZEOF_STRUCT(ata_smart_log_entry, 2); + +-#pragma pack(1) + struct ata_smart_log_directory { + unsigned short int logversion; + struct ata_smart_log_entry entry[255]; +@@ -343,7 +330,6 @@ + + // SMART SELECTIVE SELF-TEST LOG Table 61 of T13/1532D Volume 1 + // Revision 3 +-#pragma pack(1) + struct test_span { + uint64_t start; + uint64_t end; +@@ -351,7 +337,6 @@ + #pragma pack() + ASSERT_SIZEOF_STRUCT(test_span, 16); + +-#pragma pack(1) + struct ata_selective_self_test_log { + unsigned short logversion; + struct test_span span[5]; diff --git a/debian/patches/03_use-smartd-runner-by-default.dpatch b/debian/patches/03_use-smartd-runner-by-default.dpatch new file mode 100755 index 0000000..ff99881 --- /dev/null +++ b/debian/patches/03_use-smartd-runner-by-default.dpatch @@ -0,0 +1,20 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 03_use-smartd-runner.dpatch by Guido Guenther +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: use smartd-runner by default in smartd.conf + +@DPATCH@ + +diff -u -Naur smartmontools-5.33+5.34cvs20050802.orig/smartd.conf smartmontools-5.33+5.34cvs20050802/smartd.conf +--- smartmontools-5.33+5.34cvs20050802.orig/smartd.conf 2004-09-14 18:57:49.000000000 +0200 ++++ smartmontools-5.33+5.34cvs20050802/smartd.conf 2006-04-10 17:35:05.000000000 +0200 +@@ -20,7 +19,7 @@ + # Directives listed below, which will be applied to all devices that + # are found. Most users should comment out DEVICESCAN and explicitly + # list the devices that they wish to monitor. +-DEVICESCAN ++DEVICESCAN -m root -M exec /usr/share/smartmontools/smartd-runner + + # First (primary) ATA/IDE hard disk. Monitor all attributes, enable + # automatic online data collection, automatic Attribute autosave, and diff --git a/debian/patches/04_remove-Id-from-smartd.conf.dpatch b/debian/patches/04_remove-Id-from-smartd.conf.dpatch new file mode 100755 index 0000000..7872d88 --- /dev/null +++ b/debian/patches/04_remove-Id-from-smartd.conf.dpatch @@ -0,0 +1,24 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 03_use-smartd-runner.dpatch by Guido Guenther +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: remove $Id from smartd.conf to ease upgrades when the user +## DP: uses a RCS for /etc + +@DPATCH@ + +diff -u -Naur smartmontools-5.33+5.34cvs20050802.orig/smartd.conf smartmontools-5.33+5.34cvs20050802/smartd.conf +--- smartmontools-5.33+5.34cvs20050802.orig/smartd.conf 2004-09-14 18:57:49.000000000 +0200 ++++ smartmontools-5.33+5.34cvs20050802/smartd.conf 2006-04-10 17:35:05.000000000 +0200 +@@ -1,9 +1,8 @@ +-# Sample configuration file for smartd. See man smartd.conf. ++# /etc/smartd.conf ++# Configuration file for smartd. Use "man smartd.conf" for more information. + + # Home page is: http://smartmontools.sourceforge.net + +-# $Id: smartd.conf,v 1.40 2006/04/12 14:00:12 ballen4705 Exp $ +- + # smartd will re-read the configuration file if it receives a HUP + # signal + diff --git a/debian/patches/10_remove-redhadism.dpatch b/debian/patches/10_remove-redhadism.dpatch new file mode 100755 index 0000000..6a8410d --- /dev/null +++ b/debian/patches/10_remove-redhadism.dpatch @@ -0,0 +1,27 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 10_remove-redhadism.dpatch by Guido Guenther +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: remove redhat specific parts from the documentation + +@DPATCH@ + +diff -u -Naur smartmontools-5.33+5.34cvs20050802.orig/smartd.8.in smartmontools-5.33+5.34cvs20050802/smartd.8.in +--- smartmontools-5.33+5.34cvs20050802.orig/smartd.8.in 2005-04-08 21:17:53.000000000 +0200 ++++ smartmontools-5.33+5.34cvs20050802/smartd.8.in 2006-04-13 09:31:13.000000000 +0200 +@@ -376,15 +376,6 @@ + .B /usr/local/etc/rc.d/init.d/smartd stop + + .fi +-If you want \fBsmartd\fP to start running whenever your machine is +-booted, this can be enabled by using the command: +-.nf +-.B /sbin/chkconfig --add smartd +-.fi +-and disabled using the command: +-.nf +-.B /sbin/chkconfig --del smartd +-.fi + + .\" DO NOT MODIFY THIS OR THE FOLLOWING TWO LINES. THIS MATERIAL + .\" IS AUTOMATICALLY INCLUDED IN THE FILE smartd.conf.5 diff --git a/debian/patches/60_cciss.dpatch b/debian/patches/60_cciss.dpatch new file mode 100644 index 0000000..f2d18a7 --- /dev/null +++ b/debian/patches/60_cciss.dpatch @@ -0,0 +1,757 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 60_cciss.dpatch.dpatch by Guido Guenther +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: add support for Compaq/HP CCISS controllers + +@DPATCH@ + +diff -rN -u old-smartmontools-cciss/os_linux.c new-smartmontools-cciss/os_linux.c +--- old-smartmontools-cciss/os_linux.c 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/os_linux.c 2006-04-10 16:15:40.000000000 +0200 +@@ -64,12 +64,15 @@ + #include "os_linux.h" + #include "scsicmds.h" + #include "utility.h" ++#include "cciss_ioctl.h" ++ + + #ifndef ENOTSUP + #define ENOTSUP ENOSYS + #endif + typedef unsigned long long u8; + ++ + #define ARGUSED(x) ((void)(x)) + + static const char *filenameandversion="$Id: os_linux.c,v 1.79 2005/04/27 01:24:51 dpgilbert Exp $"; +@@ -83,6 +86,17 @@ + // global variable holding byte count of allocated memory + extern long long bytes; + ++typedef struct _ReportLUNdata_struct ++{ ++ BYTE LUNListLength[4]; ++ DWORD reserved; ++ BYTE LUN[CISS_MAX_LUN][8]; ++} ReportLunData_struct; ++ ++/* Structure/defines of Report Physical LUNS of drive */ ++#define CISS_MAX_LUN 16 ++#define CISS_MAX_PHYS_LUN 1024 ++#define CISS_REPORT_PHYS 0xc3 + + + /* This function will setup and fix device nodes for a 3ware controller. */ +@@ -191,8 +205,15 @@ + } + return open(pathname, O_RDONLY | O_NONBLOCK); + } ++ // cciss+ ++ else if(!strcmp(type, "CCISS")) ++ { ++ // the device is a cciss smart array device. ++ return open(pathname, O_RDWR | O_NONBLOCK); ++ } + else + return -1; ++ + } + + // equivalent to close(file descriptor) +@@ -609,6 +630,93 @@ + + return 0; + } ++// cciss+ ++static int cciss_sendpassthru(unsigned int cmdtype, unsigned char *CDB, ++ unsigned int CDBlen, char *buff, ++ unsigned int size, unsigned int LunID, ++ unsigned char *scsi3addr, int fd) ++{ ++ int err ; ++ IOCTL_Command_struct iocommand; ++ ++ memset(&iocommand, 0, sizeof(iocommand)); ++ ++ if (cmdtype == 0) ++ { ++ // To controller; nothing to do ++ } ++ else if (cmdtype == 1) ++ { ++ iocommand.LUN_info.LogDev.VolId = LunID; ++ iocommand.LUN_info.LogDev.Mode = 1; ++ } ++ else if (cmdtype == 2) ++ { ++ memcpy(&iocommand.LUN_info.LunAddrBytes,scsi3addr,8); ++ iocommand.LUN_info.LogDev.Mode = 0; ++ } ++ else ++ { ++ fprintf(stderr, "cciss_sendpassthru: bad cmdtype\n"); ++ return 1; ++ } ++ ++ memcpy(&iocommand.Request.CDB[0], CDB, CDBlen); ++ iocommand.Request.CDBLen = CDBlen; ++ iocommand.Request.Type.Type = TYPE_CMD; ++ iocommand.Request.Type.Attribute = ATTR_SIMPLE; ++ iocommand.Request.Type.Direction = XFER_READ; ++ iocommand.Request.Timeout = 0; ++ ++ iocommand.buf_size = size; ++ iocommand.buf = (unsigned char *)buff; ++ ++ if ((err = ioctl(fd, CCISS_PASSTHRU, &iocommand))) ++ { ++ fprintf(stderr, "CCISS ioctl error %d\n", err); ++ } ++ return err; ++} ++ ++// cciss+ ++static int cciss_getlun(int device, int target, unsigned char *physlun) ++{ ++ unsigned char CDB[16]= {0}; ++ ReportLunData_struct *luns; ++ int reportlunsize = sizeof(*luns) + CISS_MAX_PHYS_LUN * 8; ++ int i; ++ int ret; ++ ++ luns = (ReportLunData_struct *)malloc(reportlunsize); ++ ++ memset(luns, 0, reportlunsize); ++ ++ /* Get Physical LUN Info (for physical device) */ ++ CDB[0] = CISS_REPORT_PHYS; ++ CDB[6] = (reportlunsize >> 24) & 0xFF; /* MSB */ ++ CDB[7] = (reportlunsize >> 16) & 0xFF; ++ CDB[8] = (reportlunsize >> 8) & 0xFF; ++ CDB[9] = reportlunsize & 0xFF; ++ ++ if ((ret = cciss_sendpassthru(0, CDB, 12, (char *)luns, reportlunsize, 0, NULL, device))) ++ { ++ free(luns); ++ return ret; ++ } ++ ++ for (i=0; iLUN[i][6] == target) ++ { ++ memcpy(physlun, luns->LUN[i], 8); ++ free(luns); ++ return 0; ++ } ++ } ++ ++ free(luns); ++ return ret; ++} + + // >>>>>> Start of general SCSI specific linux code + +@@ -946,6 +1054,75 @@ + // >>>>>> End of general SCSI specific linux code + + ++// cciss+ >> CCSISS I/O passthrough ++// This is an interface that uses the cciss passthrough to talk to the SMART controller on ++// the HP system. The cciss driver provides a way to send SCSI cmds through the CCISS passthrough ++// essentially the methods above and below pertain to SCSI, except for the SG driver which is not ++// involved. The CCISS driver does not engage the scsi subsystem. ++int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report) ++{ ++ unsigned char pBuf[512] = {0}; ++ unsigned char phylun[1024] = {0}; ++ int iBufLen = 512; ++ int status = -1; ++ int len = 0; // used later in the code. ++ report = 0; ++ ++ cciss_getlun(device, target, phylun); ++ status = cciss_sendpassthru( 2, iop->cmnd, iop->cmnd_len, (char*) pBuf, iBufLen, 1, phylun, device); ++ ++ if (0 == status) ++ { ++ if (report > 0) ++ printf(" status=0\n"); ++ if (DXFER_FROM_DEVICE == iop->dxfer_dir) ++ { ++ memcpy(iop->dxferp, pBuf, iop->dxfer_len); ++ if (report > 1) ++ { ++ int trunc = (iop->dxfer_len > 256) ? 1 : 0; ++ printf(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len, ++ (trunc ? " [only first 256 bytes shown]" : "")); ++ dStrHex((const char*)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1); ++ } ++ } ++ return 0; ++ } ++ iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */ ++ if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf)) ++ iop->scsi_status = SCSI_STATUS_CHECK_CONDITION; ++ len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ? ++ SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len; ++ if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && ++ iop->sensep && (len > 0)) ++ { ++ memcpy(iop->sensep, pBuf, len); ++ iop->resp_sense_len = iBufLen; ++ if (report > 1) ++ { ++ printf(" >>> Sense buffer, len=%d:\n", (int)len); ++ dStrHex((const char *)pBuf, len , 1); ++ } ++ } ++ if (report) ++ { ++ if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) { ++ printf(" status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff, ++ pBuf[2] & 0xf, pBuf[12], pBuf[13]); ++ } ++ else ++ printf(" status=0x%x\n", status); ++ } ++ if (iop->scsi_status > 0) ++ return 0; ++ else ++ { ++ if (report > 0) ++ printf(" ioctl status=0x%x but scsi status=0, fail with EIO\n", status); ++ return -EIO; /* give up, assume no device there */ ++ } ++} ++ + // prototype + void printwarning(smart_command_set command); + +diff -rN -u old-smartmontools-cciss/scsicmds.c new-smartmontools-cciss/scsicmds.c +--- old-smartmontools-cciss/scsicmds.c 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/scsicmds.c 2006-04-13 09:29:10.000000000 +0200 +@@ -53,6 +53,26 @@ + /* for passing global control variables */ + extern smartmonctrl *con; + ++// Check and call the right interface. May be when the do_generic_scsi_cmd_io interface is better ++// we can take off this crude way of calling the right interface ++ ++static int do_generic_scsi_cmd_io(int dev_fd, struct scsi_cmnd_io * iop, int report) ++{ ++ switch(con->controller_type) ++ { ++ case CONTROLLER_CCISS: ++ return cciss_io_interface(dev_fd, con->controller_port-1, iop, report); ++ // not reached ++ break; ++ default: ++ return do_scsi_cmnd_io(dev_fd, iop, report); ++ // not reached ++ break; ++ } ++} ++ ++ ++ + /* output binary in hex and optionally ascii */ + void dStrHex(const char* str, int len, int no_ascii) + { +@@ -267,7 +287,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -301,7 +321,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -344,13 +364,13 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); + status = scsiSimpleSenseFilter(&sinfo); + if (SIMPLE_ERR_TRY_AGAIN == status) { +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -406,7 +426,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -440,13 +460,13 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); + status = scsiSimpleSenseFilter(&sinfo); + if (SIMPLE_ERR_TRY_AGAIN == status) { +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -503,7 +523,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -536,7 +556,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -574,7 +594,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -615,7 +635,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if ((0 == status) && (sense_info)) { + ecode = buff[0] & 0x7f; + sense_info->error_code = ecode; +@@ -665,7 +685,7 @@ + /* worst case is an extended foreground self test on a big disk */ + io_hdr.timeout = SCSI_TIMEOUT_SELF_TEST; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -700,7 +720,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +@@ -727,7 +747,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, sinfo); +@@ -783,7 +803,7 @@ + io_hdr.max_sense_len = sizeof(sense); + io_hdr.timeout = SCSI_TIMEOUT_DEFAULT; + +- status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl); ++ status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl); + if (0 != status) + return status; + scsi_do_sense_disect(&io_hdr, &sinfo); +diff -rN -u old-smartmontools-cciss/scsicmds.h new-smartmontools-cciss/scsicmds.h +--- old-smartmontools-cciss/scsicmds.h 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/scsicmds.h 2006-04-10 11:34:37.000000000 +0200 +@@ -346,6 +346,8 @@ + * (e.g. device not present or not a SCSI device) or some other problem + * arises (e.g. timeout) then returns a negative errno value. */ + int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report); ++// The cciss interface for the cciss over SCSI - Linux specific so far ++int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report); + + + /* This is Linux specific and will be generalized later. */ +diff -rN -u old-smartmontools-cciss/smartctl.8.in new-smartmontools-cciss/smartctl.8.in +--- old-smartmontools-cciss/smartctl.8.in 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/smartctl.8.in 2006-04-12 11:40:36.000000000 +0200 +@@ -173,7 +173,7 @@ + .TP + .B \-d TYPE, \-\-device=TYPE + Specifies the type of the device. The valid arguments to this option +-are \fIata\fP, \fIscsi\fP, \fImarvell\fP, and \fI3ware,N\fP. If this option is not ++are \fIata\fP, \fIscsi\fP, \fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP. If this option is not + used then \fBsmartctl\fP will attempt to guess the device type from + the device name. + +@@ -253,6 +253,8 @@ + + .B 3ware controllers are currently ONLY supported under Linux and FreeBSD. + ++.B cciss controllers are currently ONLY supported under Linux. ++ + .TP + .B \-T TYPE, \-\-tolerance=TYPE + Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART command +@@ -1138,6 +1140,12 @@ + power\-cycled during the read\-scan, resume the scan 45 minutes after power to the + device is restored. + .PP ++.nf ++.B smartctl \-a \-d cciss,0 /dev/cciss/c0d0 ++.fi ++Examine all SMART data for the first SCSI disk connected to a cciss ++RAID controller card. ++.PP + .SH RETURN VALUES + The return values of \fBsmartctl\fP are defined by a bitmask. If all + is well with the disk, the return value (exit status) of +diff -rN -u old-smartmontools-cciss/smartctl.c new-smartmontools-cciss/smartctl.c +--- old-smartmontools-cciss/smartctl.c 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/smartctl.c 2006-04-12 11:31:32.000000000 +0200 +@@ -234,7 +234,7 @@ + case 'q': + return "errorsonly, silent"; + case 'd': +- return "ata, scsi, marvell, 3ware,N"; ++ return "ata, scsi, marvell, 3ware,N, cciss,N"; + case 'T': + return "normal, conservative, permissive, verypermissive"; + case 'b': +@@ -384,21 +384,35 @@ + con->dont_print = FALSE; + pout("No memory for argument of -d. Exiting...\n"); + exit(FAILCMD); +- } else if (strncmp(s,"3ware,",6)) { +- badarg = TRUE; +- } else if (split_report_arg2(s, &i)) { +- sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n"); +- badarg = TRUE; +- } else if (i<0 || i>15) { +- sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i); +- badarg = TRUE; +- } else { +- // NOTE: controller_port == disk number + 1 +- con->controller_type = CONTROLLER_3WARE; +- con->controller_port = i+1; +- } +- free(s); +- } ++ } else if (!strncmp(s,"3ware,",6)) { ++ if (split_report_arg2(s, &i)) { ++ sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n"); ++ badarg = TRUE; ++ } else if (i<0 || i>15) { ++ sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i); ++ badarg = TRUE; ++ } else { ++ // NOTE: controller_port == disk number + 1 ++ con->controller_type = CONTROLLER_3WARE; ++ con->controller_port = i+1; ++ } ++ free(s); ++ } else if (!strncmp(s,"cciss,",6)) { ++ if (split_report_arg2(s, &i)) { ++ sprintf(extraerror, "Option -d cciss,N requires N to be a non-negative integer\n"); ++ badarg = TRUE; ++ } else if (i<0 || i>15) { ++ sprintf(extraerror, "Option -d cciss,N (N=%d) must have 0 <= N <= 15\n", i); ++ badarg = TRUE; ++ } else { ++ // NOTE: controller_port == drive number ++ con->controller_type = CONTROLLER_CCISS; ++ con->controller_port = i+1; ++ } ++ free(s); ++ } else ++ badarg=TRUE; ++ } + break; + case 'T': + if (!strcmp(optarg,"normal")) { +@@ -851,6 +865,9 @@ + case CONTROLLER_3WARE_678K_CHAR: + mode="ATA_3WARE_678K"; + break; ++ case CONTROLLER_CCISS: ++ mode="CCISS"; ++ break; + default: + mode="ATA"; + break; +@@ -882,6 +899,11 @@ + case CONTROLLER_SCSI: + retval = scsiPrintMain(fd); + break; ++ case CONTROLLER_CCISS: ++ // route the cciss command through scsiPrintMain. ++ // cciss pass-throughs will separeate from the SCSI data-path. ++ retval = scsiPrintMain(fd); ++ break; + default: + retval = ataPrintMain(fd); + break; +diff -rN -u old-smartmontools-cciss/smartd.8.in new-smartmontools-cciss/smartd.8.in +--- old-smartmontools-cciss/smartd.8.in 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/smartd.8.in 2006-04-12 11:41:03.000000000 +0200 +@@ -561,8 +561,8 @@ + .B \-d TYPE + Specifies the type of the device. This Directive may be used multiple + times for one device, but the arguments \fIata\fP, \fIscsi\fP, +-\fImarvell\fP, and \fI3ware,N\fP are mutually-exclusive. If more than +-one is given then \fBsmartd\fP will use the last one which appears. ++\fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP are mutually-exclusive. If more ++than one is given then \fBsmartd\fP will use the last one which appears. + + If none of these three arguments is given, then \fBsmartd\fP will + first attempt to guess the device type by looking at whether the sixth +@@ -629,8 +629,14 @@ + 6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series + controllers). + ++.I cciss,N ++\- the device consists of one or more SCSI disks connected to a cciss ++RAID controller. The non-negative integer N (in the range from 0 to 15 ++inclusive) denotes which disk on the controller is monitored. In log ++files and email messages this disk will be identified as cciss_disk_XX ++with XX in the range from 00 to 15 inclusive. + +-.B 3ware controllers are currently ONLY supported under Linux. ++.B 3ware and cciss controllers are currently ONLY supported under Linux. + + .I removable + \- the device or its media is removable. This indicates to +diff -rN -u old-smartmontools-cciss/smartd.c new-smartmontools-cciss/smartd.c +--- old-smartmontools-cciss/smartd.c 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/smartd.c 2006-04-12 11:32:50.000000000 +0200 +@@ -705,6 +705,18 @@ + *s=' '; + } + break; ++ case CONTROLLER_CCISS: ++ { ++ char *s,devicetype[16]; ++ sprintf(devicetype, "cciss,%d", cfg->controller_port-1); ++ exportenv(environ_strings[8], "SMARTD_DEVICETYPE", devicetype); ++ if ((s=strchr(cfg->name, ' '))) ++ *s='\0'; ++ exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name); ++ if (s) ++ *s=' '; ++ } ++ break; + case CONTROLLER_ATA: + exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "ata"); + exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name); +@@ -716,6 +728,7 @@ + case CONTROLLER_SCSI: + exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "scsi"); + exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name); ++ break; + } + + snprintf(fullmessage, 1024, +@@ -1063,7 +1076,7 @@ + void Directives() { + PrintOut(LOG_INFO, + "Configuration file (%s) Directives (after device name):\n" +- " -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N\n" ++ " -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N, cciss,N\n" + " -T TYPE Set the tolerance to one of: normal, permissive\n" + " -o VAL Enable/disable automatic offline tests (on/off)\n" + " -S VAL Enable/disable attribute autosave (on/off)\n" +@@ -1593,11 +1606,15 @@ + // should we try to register this as a SCSI device? + switch (cfg->controller_type) { + case CONTROLLER_SCSI: ++ case CONTROLLER_CCISS: + case CONTROLLER_UNKNOWN: + break; + default: + return 1; + } ++ // pass user settings on to low-level SCSI commands ++ con->controller_port=cfg->controller_port; ++ con->controller_type=cfg->controller_type; + + // open the device + if ((fd = OpenDevice(device, "SCSI", scanning)) < 0) +@@ -2728,26 +2745,42 @@ + PrintOut(LOG_CRIT, + "No memory to copy argument to -d option - exiting\n"); + EXIT(EXIT_NOMEM); +- } else if (strncmp(s,"3ware,",6)) { +- badarg=1; +- } else if (split_report_arg2(s, &i)){ +- PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n", +- configfile, lineno, name); +- badarg=1; +- } else if ( i<0 || i>15) { +- PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n", +- configfile, lineno, name, i); +- badarg=1; +- } else { +- // determine type of escalade device from name of device +- cfg->controller_type = guess_device_type(name); +- if (cfg->controller_type!=CONTROLLER_3WARE_9000_CHAR && cfg->controller_type!=CONTROLLER_3WARE_678K_CHAR) +- cfg->controller_type=CONTROLLER_3WARE_678K; ++ } else if (!strncmp(s,"3ware,",6)) { ++ if (split_report_arg2(s, &i)){ ++ PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n", ++ configfile, lineno, name); ++ badarg=1; ++ } else if ( i<0 || i>15) { ++ PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n", ++ configfile, lineno, name, i); ++ badarg=1; ++ } else { ++ // determine type of escalade device from name of device ++ cfg->controller_type = guess_device_type(name); ++ if (cfg->controller_type!=CONTROLLER_3WARE_9000_CHAR && cfg->controller_type!=CONTROLLER_3WARE_678K_CHAR) ++ cfg->controller_type=CONTROLLER_3WARE_678K; + +- // NOTE: controller_port == disk number + 1 +- cfg->controller_port = i+1; ++ // NOTE: controller_port == disk number + 1 ++ cfg->controller_port = i+1; ++ } ++ } else if (!strncmp(s,"cciss,",6)) { ++ if (split_report_arg2(s, &i)){ ++ PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N requires N integer\n", ++ configfile, lineno, name); ++ badarg=1; ++ } else if ( i<0 || i>15) { ++ PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N (N=%d) must have 0 <= N <= 15\n", ++ configfile, lineno, name, i); ++ badarg=1; ++ } else { ++ // NOTE: controller_port == disk number + 1 ++ cfg->controller_type = CONTROLLER_CCISS; ++ cfg->controller_port = i+1; ++ } ++ } else { ++ badarg=1; + } +- s=CheckFree(s, __LINE__,filenameandversion); ++ s=CheckFree(s, __LINE__,filenameandversion); + } + break; + case 'F': +@@ -3155,13 +3188,13 @@ + } + } + +- // If we found 3ware controller, then modify device name by adding a SPACE +- if (cfg->controller_port){ ++ // If we found 3ware/cciss controller, then modify device name by adding a SPACE ++ if (cfg->controller_port) { + int len=17+strlen(cfg->name); + char *newname; + + if (devscan){ +- PrintOut(LOG_CRIT, "smartd: can not scan for 3ware devices (line %d of file %s)\n", ++ PrintOut(LOG_CRIT, "smartd: can not scan for 3ware/cciss devices (line %d of file %s)\n", + lineno, configfile); + return -2; + } +@@ -3172,7 +3205,8 @@ + } + + // Make new device name by adding a space then RAID disk number +- snprintf(newname, len, "%s [3ware_disk_%02d]", cfg->name, cfg->controller_port-1); ++ snprintf(newname, len, "%s [%s_disk_%02d]", cfg->name, (cfg->controller_type == CONTROLLER_CCISS) ? "cciss" : "3ware", ++ cfg->controller_port-1); + cfg->name=CheckFree(cfg->name, __LINE__,filenameandversion); + cfg->name=newname; + bytes+=16; +@@ -3808,7 +3842,7 @@ + continue; + + // register ATA devices +- if (ent->controller_type!=CONTROLLER_SCSI){ ++ if (ent->controller_type!=CONTROLLER_SCSI && ent->controller_type!=CONTROLLER_CCISS){ + if (ATADeviceScan(ent, scanning)) + CanNotRegister(ent->name, "ATA", ent->lineno, scanning); + else { +@@ -3821,7 +3855,8 @@ + } + + // then register SCSI devices +- if (ent->controller_type==CONTROLLER_SCSI || ent->controller_type==CONTROLLER_UNKNOWN){ ++ if (ent->controller_type==CONTROLLER_SCSI || ent->controller_type==CONTROLLER_CCISS || ++ ent->controller_type==CONTROLLER_UNKNOWN){ + int retscsi=0; + + #if SCSITIMEOUT +diff -rN -u old-smartmontools-cciss/smartd.conf.5.in new-smartmontools-cciss/smartd.conf.5.in +--- old-smartmontools-cciss/smartd.conf.5.in 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/smartd.conf.5.in 2006-04-12 11:58:07.000000000 +0200 +@@ -226,8 +226,8 @@ + .B \-d TYPE + Specifies the type of the device. This Directive may be used multiple + times for one device, but the arguments \fIata\fP, \fIscsi\fP, +-\fImarvell\fP, and \fI3ware,N\fP are mutually-exclusive. If more than +-one is given then \fBsmartd\fP will use the last one which appears. ++\fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP are mutually-exclusive. If more ++than one is given then \fBsmartd\fP will use the last one which appears. + + If none of these three arguments is given, then \fBsmartd\fP will + first attempt to guess the device type by looking at whether the sixth +@@ -294,8 +294,14 @@ + 6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series + controllers). + ++.I cciss,N ++\- the device consists of one or more SCSI disks connected to a cciss ++RAID controller. The non-negative integer N (in the range from 0 to 15 ++inclusive) denotes which disk on the controller is monitored. In log ++files and email messages this disk will be identified as cciss_disk_XX ++with XX in the range from 00 to 15 inclusive. + +-.B 3ware controllers are currently ONLY supported under Linux. ++.B 3ware and cciss controllers are currently ONLY supported under Linux. + + .I removable + \- the device or its media is removable. This indicates to +diff -rN -u old-smartmontools-cciss/utility.h new-smartmontools-cciss/utility.h +--- old-smartmontools-cciss/utility.h 2006-02-28 17:38:26.000000000 +0100 ++++ new-smartmontools-cciss/utility.h 2006-04-13 09:28:32.000000000 +0200 +@@ -174,6 +174,6 @@ + #define CONTROLLER_3WARE_9000_CHAR 0x05 // set by guess_device_type() + #define CONTROLLER_3WARE_678K_CHAR 0x06 // set by guess_device_type() + #define CONTROLLER_MARVELL_SATA 0x07 // SATA drives behind Marvell controllers +- ++#define CONTROLLER_CCISS 0x08 // CCISS controller + + #endif + -- 2.39.5