]> git.proxmox.com Git - mirror_smartmontools-debian.git/commitdiff
add debian specific patches
authorGuido Guenther <agx@bogon.sigxcpu.org>
Sun, 23 Apr 2006 16:39:04 +0000 (18:39 +0200)
committerGuido Guenther <agx@bogon.sigxcpu.org>
Sun, 23 Apr 2006 16:39:04 +0000 (18:39 +0200)
debian/patches/00list [new file with mode: 0755]
debian/patches/01_add-kfreebsd-support.dpatch [new file with mode: 0755]
debian/patches/02_remove-pragma.dpatch [new file with mode: 0755]
debian/patches/03_use-smartd-runner-by-default.dpatch [new file with mode: 0755]
debian/patches/04_remove-Id-from-smartd.conf.dpatch [new file with mode: 0755]
debian/patches/10_remove-redhadism.dpatch [new file with mode: 0755]
debian/patches/60_cciss.dpatch [new file with mode: 0644]

diff --git a/debian/patches/00list b/debian/patches/00list
new file mode 100755 (executable)
index 0000000..be0d636
--- /dev/null
@@ -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 (executable)
index 0000000..707fac3
--- /dev/null
@@ -0,0 +1,20 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 01_add-kfreebsd-support.dpatch by Guido Guenther <agx@sigxcpu.org>
+##
+## 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 (executable)
index 0000000..c9362f8
--- /dev/null
@@ -0,0 +1,131 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 02_remove-progma.dpatch by Guido Guenther <agx@sigxcpu.org>
+##
+## 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 (executable)
index 0000000..ff99881
--- /dev/null
@@ -0,0 +1,20 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 03_use-smartd-runner.dpatch by Guido Guenther <agx@sigxcpu.org>
+##
+## 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 (executable)
index 0000000..7872d88
--- /dev/null
@@ -0,0 +1,24 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 03_use-smartd-runner.dpatch by Guido Guenther <agx@sigxcpu.org>
+##
+## 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 (executable)
index 0000000..6a8410d
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 10_remove-redhadism.dpatch by Guido Guenther <agx@sigxcpu.org>
+##
+## 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 (file)
index 0000000..f2d18a7
--- /dev/null
@@ -0,0 +1,757 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 60_cciss.dpatch.dpatch by Guido Guenther <agx@sigxcpu.org>
+##
+## 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; i<CISS_MAX_LUN+1; i++) 
++    {
++        if (luns->LUN[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
+