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]

Reply via email to