[PATCH] aic94xx: fix smartctl utility problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



   Fixed the problem that "smartctl -a /dev/some_sata_disk -d ata"  does not work on SATA device.
   ( The smartctl v5.38 does need "-d ata" option.)
   The root cause is the aic94xx driver does not return ATA output register due to performance reason.
   The aic94xx need check ATA command which need ATA output register and turn on internal flag to
   enable firmware to return ATA output register to top layer.
   It also add new ATA commands to ata.h sush as ATA_CMD_CHK_MEDIA_TYPE and ATA_CMD_SMART.

Signed-off-by: Gilbert Wu <gilbert_wu@xxxxxxxxxxx>

diff -urN a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
--- a/drivers/scsi/aic94xx/aic94xx_task.c	2007-09-04 14:55:57.000000000 -0700
+++ b/drivers/scsi/aic94xx/aic94xx_task.c	2007-09-05 14:55:45.000000000 -0700
@@ -25,6 +25,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/hdreg.h>
 #include "aic94xx.h"
 #include "aic94xx_sas.h"
 #include "aic94xx_hwi.h"
@@ -152,6 +153,22 @@
 		pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
 			     task->data_dir);
 }
+static const struct ata_command_table {
+	u8 command;
+	u8 sub_command;
+} ata_command_tbl[] = {
+	{ATA_CMD_CHK_MEDIA_TYPE,         0},
+	{ATA_CMD_DEV_RESET,              0},
+	{ATA_CMD_EDD,                    0},
+	{ATA_CMD_IDLEIMMEDIATE,          0},
+	{ATA_CMD_READ_NATIVE_MAX,        0},
+	{ATA_CMD_READ_NATIVE_MAX_EXT,    0},
+	{ATA_CMD_SET_MAX,                0},
+	{ATA_CMD_SET_MAX_EXT,            0},
+	{ATA_CMD_SMART,                  SMART_STATUS},
+	{ATA_CMD_SMART,                  SMART_IMMEDIATE_OFFLINE}, 
+	{0,0} /* terminate list */
+};
 
 /* ---------- Task complete tasklet ---------- */
 
@@ -253,6 +270,7 @@
 		break;
 	case TC_SSP_RESP:
 	case TC_ATA_RESP:
+	case TC_CSMI:
 		ts->resp = SAS_TASK_COMPLETE;
 		ts->stat = SAS_PROTO_RESPONSE;
 		asd_get_response_tasklet(ascb, dl);
@@ -375,6 +393,21 @@
 
 /* ---------- ATA ---------- */
 
+int need_ata_output_reg(u8 command, u8 sub_command)
+{
+
+	int i;
+		
+	for (i = 0; ata_command_tbl[i].command != 0 ; i++) {
+
+		if (ata_command_tbl[i].command == command &&
+			(!ata_command_tbl[i].sub_command || 
+			  ata_command_tbl[i].sub_command == sub_command )) 
+		return 1;
+	}
+	return 0;
+}
+
 static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
 			      gfp_t gfp_flags)
 {
@@ -427,6 +460,9 @@
 			flags |= STP_AFFIL_POLICY;
 		scb->ata_task.flags = flags;
 	}
+	if (need_ata_output_reg(scb->ata_task.fis.command,scb->ata_task.fis.features))
+		scb->ata_task.ata_flags|=CSMI_TASK;
+
 	ascb->tasklet_complete = asd_task_tasklet_complete;
 
 	if (likely(!task->ata_task.device_control_reg_update))
diff -urN a/include/linux/ata.h b/include/linux/ata.h
--- a/include/linux/ata.h	2007-09-04 14:48:44.000000000 -0700
+++ b/include/linux/ata.h	2007-09-04 19:28:05.000000000 -0700
@@ -175,6 +175,8 @@
 	ATA_CMD_READ_LOG_EXT	= 0x2f,
 	ATA_CMD_PMP_READ	= 0xE4,
 	ATA_CMD_PMP_WRITE	= 0xE8,
+	ATA_CMD_CHK_MEDIA_TYPE	= 0xD1,
+	ATA_CMD_SMART		= 0xB0,
 
 	/* READ_LOG_EXT pages */
 	ATA_LOG_SATA_NCQ	= 0x10,


-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux