|
Subject: [PATCH] atacb support (fwd) Newsgroups: gmane.linux.utilities.smartmontools Date: 2008-02-24 07:41:24 GMT (1 year, 18 weeks, 4 days, 20 hours and 5 minutes ago) Hi Matthieu, Thank you for the code! The reference to cy7c68300c_8.pdf is also useful. I found a copy here: http://download.cypress.com.edgesuite.net/design_resources/datasheets/contents/cy7c68300c_8.pdf Doug, could you please have a look at the patch? We should probably include this as experimental after the upcoming smartmontools release. Matthieu, a few small comments and questions: (1) Could I add you to the smartmontools developers so that you can put the code into CVS youself and if necessary help to maintain it? If so, please send me your sourceforge username. (2) If I understand correctly, you have NOT modified smartd, only smartctl. Though of course the interface function could be used from smartd. (3) The man pages (documentation) also need modification. Could you please also provide a patch for smartctl.8.in ? Cheers, Bruce ---------- Forwarded message ---------- Date: Sat, 23 Feb 2008 12:08:56 +0100 From: matthieu castet <castet.matthieu <at> free.fr> To: smartmontools-support <at> lists.sourceforge.net Cc: Bruce Allen <ballen <at> gravity.phys.uwm.edu> Subject: [smartmontools-support] [PATCH] atacb support Hi, I have implemented atacb support for smartmontools, only for smartctl ATM. I only did some basic test on a cypress usb bridge. Why on http://smartmontools.sourceforge.net/smartmontools_scsi.html, atacb is said to only work when there no other access ? Matthieu
? .os_linux.cpp.swp
? scsiata1.cpp
Index: atacmds.cpp
===================================================================
RCS file: /cvsroot/smartmontools/sm5/atacmds.cpp,v
retrieving revision 1.189
diff -u -r1.189 atacmds.cpp
--- atacmds.cpp 7 Jan 2008 20:07:55 -0000 1.189
+++ atacmds.cpp 23 Feb 2008 11:03:57 -0000
@@ -635,6 +635,9 @@
case CONTROLLER_SAT:
retval=sat_command_interface(device, command, select, data);
break;
+ case CONTROLLER_ATACB:
+ retval=atacb_command_interface(device, command, select, data);
+ break;
case CONTROLLER_HPT:
retval=highpoint_command_interface(device, command, select, data);
break;
Index: scsiata.cpp
===================================================================
RCS file: /cvsroot/smartmontools/sm5/scsiata.cpp,v
retrieving revision 1.8
diff -u -r1.8 scsiata.cpp
--- scsiata.cpp 3 Dec 2007 02:14:20 -0000 1.8
+++ scsiata.cpp 23 Feb 2008 11:03:57 -0000
@@ -451,3 +451,216 @@
}
return NULL;
}
+
+/* see cy7c68300c_8.pdf for more information */
+#define ATACB_PASSTHROUGH_LEN 16
+int atacb_command_interface(int device, smart_command_set command, int select,
+ char *data)
+{
+ struct scsi_cmnd_io io_hdr;
+ unsigned char cdb[ATACB_PASSTHROUGH_LEN];
+ int status;
+ int copydata = 0;
+ int outlen = 0;
+ int ck_cond = 0; /* set to 1 to read register(s) back */
+ int protocol = 3; /* non-data */
+ int t_dir = 1; /* 0 -> to device, 1 -> from device */
+ int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
+ int t_length = 0; /* 0 -> no data transferred */
+ int feature = 0;
+ int ata_command = 0;
+ int sector_count = 0;
+ int lba_low = 0;
+ int lba_mid = 0;
+ int lba_high = 0;
+ int passthru_size = ATACB_PASSTHROUGH_LEN;
+
+ memset(cdb, 0, sizeof(cdb));
+
+ ata_command = ATA_SMART_CMD;
+ switch (command) {
+ case CHECK_POWER_MODE:
+ ata_command = ATA_CHECK_POWER_MODE;
+ ck_cond = 1;
+ copydata = 1;
+ break;
+ case READ_VALUES: /* READ DATA */
+ feature = ATA_SMART_READ_VALUES;
+ sector_count = 1; /* one (512 byte) block */
+ protocol = 4; /* PIO data-in */
+ t_length = 2; /* sector count holds count */
+ copydata = 512;
+ break;
+ case READ_THRESHOLDS: /* obsolete */
+ feature = ATA_SMART_READ_THRESHOLDS;
+ sector_count = 1; /* one (512 byte) block */
+ lba_low = 1;
+ protocol = 4; /* PIO data-in */
+ t_length = 2; /* sector count holds count */
+ copydata=512;
+ break;
+ case READ_LOG:
+ feature = ATA_SMART_READ_LOG_SECTOR;
+ sector_count = 1; /* one (512 byte) block */
+ lba_low = select;
+ protocol = 4; /* PIO data-in */
+ t_length = 2; /* sector count holds count */
+ copydata = 512;
+ break;
+ case WRITE_LOG:
+ feature = ATA_SMART_WRITE_LOG_SECTOR;
+ sector_count = 1; /* one (512 byte) block */
+ lba_low = select;
+ protocol = 5; /* PIO data-out */
+ t_length = 2; /* sector count holds count */
+ t_dir = 0; /* to device */
+ outlen = 512;
+ break;
+ case IDENTIFY:
+ ata_command = ATA_IDENTIFY_DEVICE;
+ sector_count = 1; /* one (512 byte) block */
+ protocol = 4; /* PIO data-in */
+ t_length = 2; /* sector count holds count */
+ copydata = 512;
+ break;
+ case PIDENTIFY:
+ ata_command = ATA_IDENTIFY_PACKET_DEVICE;
+ sector_count = 1; /* one (512 byte) block */
+ protocol = 4; /* PIO data-in */
+ t_length = 2; /* sector count (7:0) holds count */
+ copydata = 512;
+ break;
+ case ENABLE:
+ feature = ATA_SMART_ENABLE;
+ lba_low = 1;
+ break;
+ case DISABLE:
+ feature = ATA_SMART_DISABLE;
+ lba_low = 1;
+ break;
+ case STATUS:
+ // this command only says if SMART is working. It could be
+ // replaced with STATUS_CHECK below.
+ feature = ATA_SMART_STATUS;
+ ck_cond = 1;
+ break;
+ case AUTO_OFFLINE:
+ feature = ATA_SMART_AUTO_OFFLINE;
+ sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
+ break;
+ case AUTOSAVE:
+ feature = ATA_SMART_AUTOSAVE;
+ sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
+ break;
+ case IMMEDIATE_OFFLINE:
+ feature = ATA_SMART_IMMEDIATE_OFFLINE;
+ lba_low = select;
+ break;
+ case STATUS_CHECK:
+ // This command uses HDIO_DRIVE_TASK and has different syntax than
+ // the other commands.
+ feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
+ ck_cond = 1;
+ break;
+ default:
+ pout("Unrecognized command %d in sat_command_interface()\n"
+ "Please contact " PACKAGE_BUGREPORT "\n", command);
+ errno=ENOSYS;
+ return -1;
+ }
+ if (ATA_SMART_CMD == ata_command) {
+ lba_mid = 0x4f;
+ lba_high = 0xc2;
+ }
+
+ cdb[0] = 0x24;
+ cdb[1] = 0x24;
+ cdb[2] = 0x0;
+ if (ata_command == ATA_IDENTIFY_DEVICE || ata_command == ATA_IDENTIFY_PACKET_DEVICE)
+ cdb[2] |= (1<<7);
+ cdb[3] = 0xff - (1<<0) - (1<<6);
+ cdb[4] = byte_block;
+
+
+ cdb[6] = feature;
+ cdb[7] = sector_count;
+ cdb[8] = lba_low;
+ cdb[9] = lba_mid;
+ cdb[10] = lba_high;
+ cdb[12] = ata_command;
+
+ memset(&io_hdr, 0, sizeof(io_hdr));
+ if (0 == t_length) {
+ io_hdr.dxfer_dir = DXFER_NONE;
+ io_hdr.dxfer_len = 0;
+ } else if (t_dir) { /* from device */
+ io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
+ io_hdr.dxfer_len = copydata;
+ io_hdr.dxferp = (unsigned char *)data;
+ memset(data, 0, copydata); /* prefill with zeroes */
+ } else { /* to device */
+ io_hdr.dxfer_dir = DXFER_TO_DEVICE;
+ io_hdr.dxfer_len = outlen;
+ io_hdr.dxferp = (unsigned char *)data;
+ }
+ io_hdr.cmnd = cdb;
+ io_hdr.cmnd_len = passthru_size;
+ io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
+
+ status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
+ if (0 != status) {
+ if (con->reportscsiioctl > 0)
+ pout("sat_command_interface: do_scsi_cmnd_io() failed, "
+ "status=%d\n", status);
+ return -1;
+ }
+ if (ck_cond) {
+ unsigned char ardp[8];
+ int ard_len = 8;
+ /* XXX this is racy */
+ cdb[2] = (1<<0); /* ask read taskfile */
+
+ /* transfert 8 bytes */
+ memset(&io_hdr, 0, sizeof(io_hdr));
+ io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
+ io_hdr.dxfer_len = ard_len;
+ io_hdr.dxferp = (unsigned char *)ardp;
+ memset(ardp, 0, ard_len); /* prefill with zeroes */
+
+ io_hdr.cmnd = cdb;
+ io_hdr.cmnd_len = passthru_size;
+ io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
+
+
+ status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
+ if (0 != status) {
+ if (con->reportscsiioctl > 0)
+ pout("sat_command_interface: do_scsi_cmnd_io() failed, "
+ "status=%d\n", status);
+ return -1;
+ }
+
+ if (con->reportscsiioctl > 1) {
+ pout("Values from ATA Return Descriptor are:\n");
+ dStrHex((const char *)ardp, ard_len, 1);
+ }
+
+ if (ATA_CHECK_POWER_MODE == ata_command)
+ data[0] = ardp[2]; /* sector count (0:7) */
+ else if (STATUS_CHECK == command) {
+ if ((ardp[4] == 0x4f) && (ardp[5] == 0xc2))
+ return 0; /* GOOD smart status */
+ if ((ardp[4] == 0xf4) && (ardp[5] == 0x2c))
+ return 1; // smart predicting failure, "bad" status
+ // We haven't gotten output that makes sense so
+ // print out some debugging info
+ syserror("Error SMART Status command failed");
+ pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
+ pout("Values from ATA Return Descriptor are:\n");
+ dStrHex((const char *)ardp, ard_len, 1);
+ return -1;
+ }
+ }
+ return 0;
+}
+
Index: scsiata.h
===================================================================
RCS file: /cvsroot/smartmontools/sm5/scsiata.h,v
retrieving revision 1.2
diff -u -r1.2 scsiata.h
--- scsiata.h 1 Jul 2006 21:29:31 -0000 1.2
+++ scsiata.h 23 Feb 2008 11:03:58 -0000
@@ -74,5 +74,8 @@
extern const unsigned char * sg_scsi_sense_desc_find(
const unsigned char * sensep, int sense_len, int desc_type);
+extern int atacb_command_interface(int device, smart_command_set command,
+ int select, char *data);
+
#endif
Index: smartctl.cpp
===================================================================
RCS file: /cvsroot/smartmontools/sm5/smartctl.cpp,v
retrieving revision 1.168
diff -u -r1.168 smartctl.cpp
--- smartctl.cpp 13 Nov 2007 14:53:27 -0000 1.168
+++ smartctl.cpp 23 Feb 2008 11:03:58 -0000
@@ -395,6 +395,10 @@
} else if (!strcmp(optarg,"marvell")) {
con->controller_type = CONTROLLER_MARVELL_SATA;
con->controller_port = 0;
+ } else if (!strncmp(optarg, "atacb", 5)) {
+ con->controller_type = CONTROLLER_ATACB;
+ con->controller_port = 0;
+ /* TODO implement a way to change bVSCBSignature */
} else if (!strncmp(optarg, "sat", 3)) {
con->controller_type = CONTROLLER_SAT;
con->controller_port = 0;
@@ -995,6 +999,7 @@
switch (con->controller_type) {
case CONTROLLER_SCSI:
case CONTROLLER_SAT:
+ case CONTROLLER_ATACB:
mode="SCSI";
break;
case CONTROLLER_3WARE_9000_CHAR:
@@ -1039,7 +1044,8 @@
break;
case CONTROLLER_SCSI:
retval = scsiPrintMain(fd);
- if ((0 == retval) && (CONTROLLER_SAT == con->controller_type))
+ if ((0 == retval) &&
+ (CONTROLLER_SAT == con->controller_type) || (CONTROLLER_ATACB == con->controller_type))
retval = ataPrintMain(fd);
break;
case CONTROLLER_CCISS:
Index: utility.h
===================================================================
RCS file: /cvsroot/smartmontools/sm5/utility.h,v
retrieving revision 1.50
diff -u -r1.50 utility.h
--- utility.h 26 Jul 2007 20:58:50 -0000 1.50
+++ utility.h 23 Feb 2008 11:03:58 -0000
@@ -194,5 +194,6 @@
#define CONTROLLER_HPT 0x09 // SATA drives behind HighPoint Raid controllers
#define CONTROLLER_CCISS 0x10 // CCISS controller
#define CONTROLLER_PARSEDEV 0x11 // "smartctl -r ataioctl,2 ..." output parser pseudo-device
+#define CONTROLLER_ATACB 0x12
#endif
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Smartmontools-support mailing list Smartmontools-support <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/smartmontools-support ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Smartmontools-support mailing list Smartmontools-support <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/smartmontools-support |
|
|