Re: How to detect if a libata ioctl SG_IO had an error?

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

 



I wrote:

>> My application wants to detect if an error occured, but in struct sg_io_hdr sg_io, sg_io.driver_status != DRIVER_OK does not say if an error occured, and (sg_io.info & SG_INFO_OK_MASK) != SG_INFO_OK does not say if an error occured.
>> 
>> In http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x322.html:
>> "A copy of these defines can be found in sg_err.h (see the utilities section): 
>> SG_ERR_DRIVER_OK [0x00] Typically no suggestion"
>> 
>> Where's sg_err.h?  scsi.h defines DRIVER_OK but no one defines SG_ERR_DRIVER_OK.  Anyway, the real problem is that other values besides DRIVER_OK also mean driver ok.
>> 
>> In http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x364.html:
>> "SG_INFO_CHECK [0x1] something abnormal happened."
>> 
>> Sense data is abnormal but not an error, so I don't know if an error occured.

Doug Gilbert wrote:
> BTW the presence of sense data may indicate an error or it may be just informative.

Right, I got that from libata-scsi.c line 525.

>> In scsi.h:
>> 443 #define DRIVER_OK       0x00    /* Driver status                           */
>> 444 
>> 445 /*
>> 446  *  These indicate the error that occurred, and what is available.
>> 447  */
>> 448 
>> 449 #define DRIVER_BUSY         0x01
>> 450 #define DRIVER_SOFT         0x02
>> 451 #define DRIVER_MEDIA        0x03
>> 452 #define DRIVER_ERROR        0x04
>> 453 
>> 454 #define DRIVER_INVALID      0x05
>> 455 #define DRIVER_TIMEOUT      0x06
>> 456 #define DRIVER_HARD         0x07
>> 457 #define DRIVER_SENSE        0x08
>> 
>> Is DRIVER_SENSE a bitwise value that can be or'ed with other values?
>> 
>> In libata-scsi.c
>> 523         if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
>> 524                 u8 *desc = sensebuf + 8;
>> 525                 cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
>> 
>> Line 523 does not test driver_byte(cmd_result) & DRIVER_SENSE.  It looks like DRIVER_SENSE is a value all by itself, not bitwise.
>> 
>> In sc.c:
>> 463         if ((CHECK_CONDITION & hp->masked_status) ||
>> 464             (DRIVER_SENSE & hp->driver_status))
>> 
>> Line 464 does not test DRIVER_SENSE == hp->driver_status.  It looks like DRIVER_SENSE is bitwise, not a value all by itself.
>> 
>> I sense inconsistency.

The inconsistency looks like a bug.

For the time being I will treat DRIVER_OK as requiring further investigation because other components might or might not be OK, DRIVER_SENSE (as a value not a bit) as requiring investigation of sense data, and anything else as an error.

>> In sc.c:
>> 546         if (hp->masked_status || hp->host_status || hp->driver_status)
>> 547                 hp->info |= SG_INFO_CHECK;
>> 
>> So even though DRIVER_SENSE is not an error, the SG_INFO_CHECK bit gets set.  (The info field is undoubtedly bitwise.)

So I pretty much have to ignore SG_INFO_CHECK because further details have to be investigated regardless.

>> How can I really test if an error occured?

Doug Gilbert gave some hints.  I'm still not sure of the answer, but I am sure that I found another libata bug, described later in this message.

>> A bit more here.
>> 
>> In scsi.h:
>> 217 /*
>> 218  *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
>> 219  *  T10/1561-D Revision 4 Draft dated 7th November 2002.
>> 220  */
>> 221 #define SAM_STAT_GOOD            0x00
>> 222 #define SAM_STAT_CHECK_CONDITION 0x02
>> 223 #define SAM_STAT_CONDITION_MET   0x04
>> 224 #define SAM_STAT_BUSY            0x08
>> 225 #define SAM_STAT_INTERMEDIATE    0x10
>> 226 #define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
>> 227 #define SAM_STAT_RESERVATION_CONFLICT 0x18
>> 228 #define SAM_STAT_COMMAND_TERMINATED 0x22        /* obsolete in SAM-3 */
>> 229 #define SAM_STAT_TASK_SET_FULL   0x28
>> 230 #define SAM_STAT_ACA_ACTIVE      0x30
>> 231 #define SAM_STAT_TASK_ABORTED    0x40
>> 
>> Is SAM_STAT_CHECK_CONDITION a bitwise value?  It looks like the answer is mostly no.  Some of them could be, but not consistently.  Did the T10 committee say if these are bitwise?
>> 
>> In scsi.h:
>> 256 /*
>> 257  *  Status codes. These are deprecated as they are shifted 1 bit right
>> 258  *  from those found in the SCSI standards. This causes confusion for
>> 259  *  applications that are ported to several OSes. Prefer SAM Status codes
>> 260  *  above.
>> 261  */
>> 262 
>> 263 #define GOOD                 0x00
>> 264 #define CHECK_CONDITION      0x01
>> 
>> In sg.c:
>> 533                 if ((CHECK_CONDITION & hp->masked_status) ||
>> 534                     (DRIVER_SENSE & hp->driver_status)) {
>> 
>> Why doesn't sg use SAM Status codes?

Hmm, as far as I can tell today, sg DOES SOMETIMES use SAM Status codes but SOMETIMES NOT.

>> Meanwhile, is CHECK_CONDITION a bitwise value?  It looks like the answer is mostly no, for the same reason as SAM_STAT_CHECK_CONDITION.  These bitwise tests look like bugs.

Still looks like a bug.  I think those values are not supposed to be bitwise.

Now for today's discovery.

When the SG_IO ioctl times out, libata sets the ABRT bit but not the ERR bit in the sense data.  I was checking the ERR bit which was 0, and then going off on a wild goose chase trying to find what level SCSI driver reported the timeout error.  There was none.  It's all in the ABRT bit.  This looks like a bug in libata.

The ATA and SAT standards seem to make it pretty clear that if the ERR bit isn't set then the driver (or my application) should ignore the ABRT bit.  But when using libata I have to ignore the ERR bit and look at the ABRT bit.  This looks like a bug.
--
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