]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[scsi] Include sense key within error number reported to user
authorMichael Brown <mcb30@ipxe.org>
Wed, 15 Sep 2010 21:23:48 +0000 (22:23 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 15 Sep 2010 21:23:48 +0000 (22:23 +0100)
The sense key gives a first idea of what the problem might be, and so
is potentially useful in diagnosing problems in a non-debug build.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/block/scsi.c
src/include/ipxe/scsi.h

index d7f7b4dbc0b3fa7d11a16386fdf4a2bbd090cf50..1abd2a5f317de096b08142bfb27cb6236de9f7a7 100644 (file)
@@ -36,6 +36,63 @@ FILE_LICENCE ( GPL2_OR_LATER );
 /** Maximum number of command retries */
 #define SCSICMD_MAX_RETRIES 10
 
+/* Error numbers generated by SCSI sense data */
+#define EIO_NO_SENSE __einfo_error ( EINFO_EIO_NO_SENSE )
+#define EINFO_EIO_NO_SENSE \
+       __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )
+#define EIO_RECOVERED_ERROR __einfo_error ( EINFO_EIO_RECOVERED_ERROR )
+#define EINFO_EIO_RECOVERED_ERROR \
+       __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )
+#define EIO_NOT_READY __einfo_error ( EINFO_EIO_NOT_READY )
+#define EINFO_EIO_NOT_READY \
+       __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )
+#define EIO_MEDIUM_ERROR __einfo_error ( EINFO_EIO_MEDIUM_ERROR )
+#define EINFO_EIO_MEDIUM_ERROR \
+       __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )
+#define EIO_HARDWARE_ERROR __einfo_error ( EINFO_EIO_HARDWARE_ERROR )
+#define EINFO_EIO_HARDWARE_ERROR \
+       __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )
+#define EIO_ILLEGAL_REQUEST __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )
+#define EINFO_EIO_ILLEGAL_REQUEST \
+       __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )
+#define EIO_UNIT_ATTENTION __einfo_error ( EINFO_EIO_UNIT_ATTENTION )
+#define EINFO_EIO_UNIT_ATTENTION \
+       __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )
+#define EIO_DATA_PROTECT __einfo_error ( EINFO_EIO_DATA_PROTECT )
+#define EINFO_EIO_DATA_PROTECT \
+       __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )
+#define EIO_BLANK_CHECK __einfo_error ( EINFO_EIO_BLANK_CHECK )
+#define EINFO_EIO_BLANK_CHECK \
+       __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )
+#define EIO_VENDOR_SPECIFIC __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )
+#define EINFO_EIO_VENDOR_SPECIFIC \
+       __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )
+#define EIO_COPY_ABORTED __einfo_error ( EINFO_EIO_COPY_ABORTED )
+#define EINFO_EIO_COPY_ABORTED \
+       __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )
+#define EIO_ABORTED_COMMAND __einfo_error ( EINFO_EIO_ABORTED_COMMAND )
+#define EINFO_EIO_ABORTED_COMMAND \
+       __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )
+#define EIO_RESERVED __einfo_error ( EINFO_EIO_RESERVED )
+#define EINFO_EIO_RESERVED \
+       __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )
+#define EIO_VOLUME_OVERFLOW __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )
+#define EINFO_EIO_VOLUME_OVERFLOW \
+       __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )
+#define EIO_MISCOMPARE __einfo_error ( EINFO_EIO_MISCOMPARE )
+#define EINFO_EIO_MISCOMPARE \
+       __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )
+#define EIO_COMPLETED __einfo_error ( EINFO_EIO_COMPLETED )
+#define EINFO_EIO_COMPLETED \
+       __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )
+#define EIO_SENSE( key )                                               \
+       EUNIQ ( EIO, (key), EIO_NO_SENSE, EIO_RECOVERED_ERROR,          \
+               EIO_NOT_READY, EIO_MEDIUM_ERROR, EIO_HARDWARE_ERROR,    \
+               EIO_ILLEGAL_REQUEST, EIO_UNIT_ATTENTION,                \
+               EIO_DATA_PROTECT, EIO_BLANK_CHECK, EIO_VENDOR_SPECIFIC, \
+               EIO_COPY_ABORTED, EIO_ABORTED_COMMAND, EIO_RESERVED,    \
+               EIO_VOLUME_OVERFLOW, EIO_MISCOMPARE, EIO_COMPLETED )
+
 /******************************************************************************
  *
  * Utility functions
@@ -379,6 +436,7 @@ static void scsicmd_response ( struct scsi_command *scsicmd,
        struct scsi_device *scsidev = scsicmd->scsidev;
        size_t overrun;
        size_t underrun;
+       int rc;
 
        if ( response->status == 0 ) {
                scsicmd_done ( scsicmd, 0 );
@@ -395,7 +453,10 @@ static void scsicmd_response ( struct scsi_command *scsicmd,
                DBGC ( scsidev, " sense %02x:%02x:%08x\n",
                       response->sense.code, response->sense.key,
                       ntohl ( response->sense.info ) );
-               scsicmd_done ( scsicmd, -EIO );
+
+               /* Construct error number from sense data */
+               rc = -EIO_SENSE ( response->sense.key & SCSI_SENSE_KEY_MASK );
+               scsicmd_done ( scsicmd, rc );
        }
 }
 
index b90aa3aa0d630f73a12e8053cf5cd056643dbb17..5539b61d0fff2cc8df6c120b0e37e969935f3cb7 100644 (file)
@@ -267,6 +267,9 @@ struct scsi_sns {
        uint32_t info;
 };
 
+/** SCSI sense key mask */
+#define SCSI_SENSE_KEY_MASK 0x0f
+
 /** A SCSI response information unit */
 struct scsi_rsp {
        /** SCSI status code */