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 -- 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