Hi,
I'm doing HDD test using sg driver. It works fine, but I always
feel something odd in the case of device error.
Heiko Eifeldt's SCSI programming HOWTO says "the result code of read or
write call is set to sg_header.result, and zero meaning no error".
In the case of device error, sense byte is set to sg_header.sense_buffer,
but sg_header.result is always zero. To detect device error,
I'm checking sg_header.result and also sg_header.sense_buffer at every
command...
The below is the example of illegal CDB's response.
(Sending read_extended(illegal LBA) to hard disk(QUANTUM FIREBALL_TM2110S)
intentionaly, to get check condition)
/* read 1 block data from 0x7fffffff(illegal LBA) */
CDB is read_ex[10] = {0x28,0,0x7f,0xff,0xff,0xff,0,0,1,0};
/* sg_header dump - result=0, but sense data */
status of read = 548
sg_hd->pack_len = 548
sg_hd->reply_len = 548
sg_hd->pack_id = 0
sg_hd->result = 0 <------
sg_hd->twelve_byte = 0
sg_hd->other_flags = 0
sg_hd->sense_buffer = 70 00 05 00 00 00 00 0a /* key = illegal request */
00 00 00 00 21 00 00 00 /* code = LBA out of range */
Kernel version is 2.0.34.
Any suggestions?
Thanks,
Hironobu
---- sample source ------------------------------------------------------------
#define DEVICE "/dev/sga"
#define SCSI_OFF sizeof(struct sg_header)
#define CMD_LEN sizeof(read_ex)
#define RD_SIZE 512
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/sg.h>
main()
{
static char read_ex[10] = {0x28,0,0x7f,0xff,0xff,0xff,0,0,1,0}; /* ille
char i_buff[SCSI_OFF + CMD_LEN], o_buff[SCSI_OFF + RD_SIZE];
struct sg_header *sg_hd_w, *sg_hd_r;
int fd, status;
fd = open(DEVICE, O_RDWR); /* open SG */
if(fd < 0) exit(1);
memset(i_buff, 0, sizeof(i_buff)); /* initialize i_buff */
sg_hd_w = (struct sg_header *)i_buff; /* set sg_header */
sg_hd_w->pack_len = SCSI_OFF + CMD_LEN;
sg_hd_w->reply_len = SCSI_OFF + RD_SIZE;
sg_hd_w->pack_id = 0;
sg_hd_w->result = 0;
sg_hd_w->twelve_byte = 0;
sg_hd_w->other_flags = 0;
/* issue read extended */
memcpy(&i_buff[SCSI_OFF], &read_ex[0], CMD_LEN); /* set CDB */
status = write(fd, sg_hd_w, SCSI_OFF + CMD_LEN); /* send packet */
if(status < 0 || status != SCSI_OFF + CMD_LEN || sg_hd_w->result) exit(1);
memset(o_buff, 0, sizeof(o_buff)); /* initialize o_buff */
sg_hd_r = (struct sg_header *)o_buff;
status = read(fd, sg_hd_r, SCSI_OFF + RD_SIZE); /* receive packet */
printf("status of read = %d\n", status);
printf("sg_hd->pack_len = %d\n", sg_hd_r->pack_len);
printf("sg_hd->reply_len = %d\n", sg_hd_r->reply_len);
printf("sg_hd->pack_id = %d\n", sg_hd_r->pack_id);
printf("sg_hd->result = %d\n", sg_hd_r->result);
printf("sg_hd->twelve_byte = %d\n", sg_hd_r->twelve_byte);
printf("sg_hd->other_flags = %d\n", sg_hd_r->other_flags);
printf("sg_hd->sense_buffer = %02x %02x %02x %02x %02x %02x %02x %02x\n",
sg_hd_r->sense_buffer[0], sg_hd_r->sense_buffer[1],
sg_hd_r->sense_buffer[2], sg_hd_r->sense_buffer[3],
sg_hd_r->sense_buffer[4], sg_hd_r->sense_buffer[5],
sg_hd_r->sense_buffer[6], sg_hd_r->sense_buffer[7]);
printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
sg_hd_r->sense_buffer[8], sg_hd_r->sense_buffer[9],
sg_hd_r->sense_buffer[10], sg_hd_r->sense_buffer[11],
sg_hd_r->sense_buffer[12], sg_hd_r->sense_buffer[13],
sg_hd_r->sense_buffer[14], sg_hd_r->sense_buffer[15]);
close(fd);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]