]> git.proxmox.com Git - mirror_smartmontools-debian.git/commitdiff
Patch by Sven Hartge to fix HSM violation errors on SATA systems (Closes: #448781)
authorGuido Guenther <agx@sigxcpu.org>
Thu, 1 Nov 2007 12:28:03 +0000 (13:28 +0100)
committerGuido Guenther <agx@sigxcpu.org>
Thu, 1 Nov 2007 12:28:03 +0000 (13:28 +0100)
debian/patches/40_fix-sata-hsm-violation.diff [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/40_fix-sata-hsm-violation.diff b/debian/patches/40_fix-sata-hsm-violation.diff
new file mode 100644 (file)
index 0000000..af966cc
--- /dev/null
@@ -0,0 +1,74 @@
+Index: smartmontools/os_linux.cpp
+===================================================================
+--- smartmontools.orig/os_linux.cpp    2007-11-01 13:16:29.000000000 +0100
++++ smartmontools/os_linux.cpp 2007-11-01 13:16:29.000000000 +0100
+@@ -425,14 +425,10 @@
+ //   1 if the command succeeded and disk SMART status is "FAILING"
+-// huge value of buffer size needed because HDIO_DRIVE_CMD assumes
+-// that buff[3] is the data size.  Since the ATA_SMART_AUTOSAVE and
+-// ATA_SMART_AUTO_OFFLINE use values of 0xf1 and 0xf8 we need the space.
+-// Otherwise a 4+512 byte buffer would be enough.
+-#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
++#define BUFFER_LENGTH (4+512)
+ int ata_command_interface(int device, smart_command_set command, int select, char *data){
+-  unsigned char buff[STRANGE_BUFFER_LENGTH];
++  unsigned char buff[BUFFER_LENGTH];
+   // positive: bytes to write to caller.  negative: bytes to READ from
+   // caller. zero: non-data command
+   int copydata=0;
+@@ -449,7 +445,7 @@
+   // buff[2] contains the ATA SECTOR COUNT REGISTER
+   
+   // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
+-  memset(buff, 0, STRANGE_BUFFER_LENGTH);
++  memset(buff, 0, BUFFER_LENGTH);
+   buff[0]=ATA_SMART_CMD;
+   switch (command){
+@@ -499,12 +495,14 @@
+     buff[2]=ATA_SMART_STATUS;
+     break;
+   case AUTO_OFFLINE:
+-    buff[2]=ATA_SMART_AUTO_OFFLINE;
+-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
++    // NSECT is 241 for enable but no data transfer.  Use TASK ioctl.
++    buff[1]=ATA_SMART_AUTO_OFFLINE;
++    buff[2]=select;
+     break;
+   case AUTOSAVE:
+-    buff[2]=ATA_SMART_AUTOSAVE;
+-    buff[3]=select;   // YET NOTE - THIS IS A NON-DATA COMMAND!!
++    // NSECT is 248 for enable but no data transfer.  Use TASK ioctl.
++    buff[1]=ATA_SMART_AUTOSAVE;
++    buff[2]=select;
+     break;
+   case IMMEDIATE_OFFLINE:
+     buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
+@@ -559,7 +557,7 @@
+     
+   // There are two different types of ioctls().  The HDIO_DRIVE_TASK
+   // one is this:
+-  if (command==STATUS_CHECK){
++  if (command==STATUS_CHECK || command==AUTOSAVE || command==AUTO_OFFLINE){
+     int retval;
+     // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
+@@ -1641,13 +1639,13 @@
+ int highpoint_command_interface(int device, smart_command_set command,
+                                 int select, char *data)
+ {
+-  unsigned char hpt_buff[4*sizeof(int) + STRANGE_BUFFER_LENGTH];
++  unsigned char hpt_buff[4*sizeof(int) + BUFFER_LENGTH];
+   unsigned int *hpt = (unsigned int *)hpt_buff;
+   unsigned char *buff = &hpt_buff[4*sizeof(int)];
+   int copydata = 0;
+   const int HDIO_DRIVE_CMD_OFFSET = 4;
+-  memset(hpt_buff, 0, 4*sizeof(int) + STRANGE_BUFFER_LENGTH);
++  memset(hpt_buff, 0, 4*sizeof(int) + BUFFER_LENGTH);
+   hpt[0] = con->hpt_data[0]; // controller id
+   hpt[1] = con->hpt_data[1]; // channel number
+   hpt[3] = con->hpt_data[2]; // pmport number
index b381603288cff9de95cb0820f53b65015458901d..d3cd7d7968eb1ac168ee5dc6d78eeae5ab4f863c 100644 (file)
@@ -6,3 +6,4 @@
 10_remove-redhatism.diff
 20_fix-scsi-disk-detection.diff
 30_gcc4.3.diff
+40_fix-sata-hsm-violation.diff