[prev in list] [next in list] [prev in thread] [next in thread] 

List:       smartmontools-support
Subject:    [smartmontools-support] masked_status == CHECK_CONDITION and sense
From:       Alex Volkov <avolkov () gmail ! com>
Date:       2010-09-22 19:23:55
Message-ID: 1285183435.2543.35.camel () alex-laptop ! vlk ! int
[Download RAW message or body]

Hello All,

I'm trying to figure out how to read smart data through SCSI interface
in linux, my question is not strictly about smartmontools, but hopefully
I'm not too offtopic.


So here it is, I've got a program that sends SG_IO command to the drive
(/dev/sda is hardcoded, and I know it supports sat16), I was a bit fuzzy
on the values of the log sense command fields, so I took them from 

scsicmds.cpp lines 318-321
http://sourceforge.net/apps/trac/smartmontools/browser/trunk/smartmontools/scsicmds.cpp#L318

And now instead of getting temperature data, masked_status field is gets
set to CHECK_CONDITION, with sense field containing following
information:

#0:0x70
#2:0x5
#7:0xA
#12:0x20

SCSI Primary Commands draft in section 4.5.3 (page 56) talks a little
about error values in this sense field, but I haven't yet figured out
the exact meaning of it, maybe someone could give me a hint on where the
problem is.

Thanks,

Alex. 

["temp_read.c" (temp_read.c)]

#include <stdio.h>
#include <strings.h>
#include <stdint.h>


#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

#include <scsi/sg.h>
#include <scsi/scsi.h>

//Seems to be the most popular size of output structure in smartclt tools, this size \
is also used with TEMPERATURE_LPAGE request #define DXFER_SZ 252
#define SENSE_SZ 32
//Need only 8 bytes for CDB_CMD_SZ, but earlier viersons only understand 6,10,12 & 16 \
bytes -- http://en.wikipedia.org/wiki/SCSI_CDB #define CDB_CMD_SZ 10

int main (int argc, char ** argv)
{
	int fd = -1, return_status = 0;
	//sg structures
	struct sg_io_hdr io_hdr;
	uint8_t cdb[CDB_CMD_SZ];
	uint8_t sense[SENSE_SZ];
	uint8_t pBuf[DXFER_SZ];
	//sg config variables
	uint8_t temperature_code = 0x0d;
	/* a bit of documentation:
	SCSI LOG SENSE --- http://en.wikipedia.org/wiki/SCSI_Log_Sense_Command
	*/

	//sg initialization
	bzero(pBuf, sizeof(pBuf));
	bzero(cdb, sizeof(cdb));
	bzero(sense, sizeof(sense));
	bzero(&io_hdr, sizeof(io_hdr));

	//prepare command,
	/*
	See:
		SCSI Log Sense Command -- http://en.wikipedia.org/wiki/SCSI_Log_Sense_Command
		LOG Sense Command -- SCSI Primary Commands 4, section 6.6 page 279
	*/
	cdb[0]=0x4d; //LOG SENSE 0x4d
	//Uhh... let's see if codes from smartmontools would do anything
	/*
	PAGE CONTROL:
		00 -- current threshold value
		01 -- current cumulatiove values
		10 -- default threshold values
		11 -- default cumulative values
	*/
	cdb[2]=0x40 | (temperature_code | 0x3f); //let's go with smartmontools \
implementation & see if it works  cdb[7]=(DXFER_SZ >>8) & 0xff; //Allocation length
	cdb[8]= DXFER_SZ & 0xff; //CONTROL
	
	
	io_hdr.interface_id = 'S';
	//command
	io_hdr.cmd_len = CDB_CMD_SZ;
	io_hdr.cmdp =cdb;
	//sense
	io_hdr.mx_sb_len = SENSE_SZ;
	io_hdr.sbp = sense;
	//data transfer 
	//should only write 15 bytes, but let's be safe, I'm using smartclt's default dxferp \
value  io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
	io_hdr.dxferp = pBuf;
	io_hdr.dxfer_len = DXFER_SZ;

	fd = open("/dev/sda", O_RDONLY|O_NONBLOCK);
	if (fd == -1){
		return_status = 1;
		printf("ERROR!\n");
		goto close;
	}
	
	if (ioctl(fd, SG_IO, &io_hdr)<0){
		fprintf(stderr, "That's it IOCTL failed. Game over.\n");
		return_status = 2;
		goto close;
	}
	/*
		SCSI error checking
		io_hdr.info -- http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x364.html
		io_hdr.masked_status -- http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x260.html
		io_hdr.host_status -- http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html
		io_hdr.driver_status -- http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x322.html
	*/
	
	printf("Performing error checking\n");
	if (io_hdr.info == SG_INFO_OK) printf("Everything went exceptionally well and we're \
on our way.\n");  else {
		printf("- Some sort of error detected\n");
		printf("-- Masked status [%x]\n", io_hdr.masked_status);
		if (io_hdr.masked_status == CHECK_CONDITION) printf("--- Masked status -> \
CHECK_CONDITION\n");  printf("-- Host status [%x]\n", io_hdr.host_status);
		printf("-- Driver status [%x]\n", io_hdr.driver_status);
		/*
		driver_status: SG_ERR_DRIVER_SENSE[0x08] implies sense_buffer output
		http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x322.html
		*/
		
		if (io_hdr.driver_status == 0x08){
			int k=0;
			printf("--- Driver status: implies that sense_buffer has output\n");
			printf("Dumping sense info\n");
			/*
				Spc v4 -- 4.5 Sense data, p 46.
				response code 0x70
				Error type -- Description:current, Reference: 4.5.4
				Sense data format -- Description: fixed, Reference: 4.5.3
			*/
			for(k=0; k < SENSE_SZ; k++){
				if (sense[k] != 0) printf("#%d:0x%X\n", k, sense[k]);
			}
			printf("\n");
			
		}
	}
	//parse output, temperature log page (SCSI primary commands v4 -- 7.3.19, p.446)
	//smartclt scsicmds.cpp lines 1049-1065

	
	uint8_t returned_page_code = pBuf[0] & 0x3f;
	uint8_t temperature = pBuf[7];
	uint8_t reference_temperature = pBuf[15];
	printf("page code %x, temperature %d, reference temperature \
%d\n",returned_page_code, temperature, reference_temperature); close:
	if (fd > -1) close(fd);
	printf("Return status: %d\n", return_status);
	return return_status;
}


["Makefile" (Makefile)]

all: temp_read
	
temp_read: temp_read.c
	gcc temp_read.c -o temp_read
clean:
	rm -v temp_read


------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev

_______________________________________________
Smartmontools-support mailing list
Smartmontools-support@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/smartmontools-support


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic