From: Douglas Gilbert <dgilbert@interlog.com>
To: n0diamond@yahoo.co.jp
Cc: linux-scsi@vger.kernel.org
Subject: Re: How to detect if a libata ioctl SG_IO had an error?
Date: Thu, 07 Jun 2012 17:18:35 -0400 [thread overview]
Message-ID: <4FD11AAB.3080009@interlog.com> (raw)
In-Reply-To: <542808.89361.qm@web100008.mail.kks.yahoo.co.jp>
On 12-06-07 02:46 AM, Norman Diamond 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.
>
> 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.
>
> 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.)
>
> How can I really test if an error occured?
>
> 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?
>
> 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.
Please fetch the sg3_utils package and look at some user
space examples. If you are interested in libata then
following src/sg_sat_identify.c might be instructive. For
Linux, the pass-through code is in lib/sg_pt_linux.c .
Look at the get_scsi_pt_result_category() functions which
should answer your questions of how to check for sense
data. BTW the presence of sense data may indicate an error
or it may be just informative.
sg_pt_linux.c handles either of two SG_IO interfaces:
- sg v3: as used by the sg driver and block devices
(e.g. /dev/sdb)
- sg v4: as used by the bsg driver which has device
names like /dev/bsg/6:0:0:2
Doug Gilbert
next prev parent reply other threads:[~2012-06-07 21:19 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-07 6:46 How to detect if a libata ioctl SG_IO had an error? Norman Diamond
2012-06-07 21:18 ` Douglas Gilbert [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-06-08 4:34 Norman Diamond
2012-06-08 5:28 Norman Diamond
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FD11AAB.3080009@interlog.com \
--to=dgilbert@interlog.com \
--cc=linux-scsi@vger.kernel.org \
--cc=n0diamond@yahoo.co.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).