diff --git a/src/drivers/block/scsi.c b/src/drivers/block/scsi.c index d7f7b4db..1abd2a5f 100644 --- a/src/drivers/block/scsi.c +++ b/src/drivers/block/scsi.c @@ -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 ); } } diff --git a/src/include/ipxe/scsi.h b/src/include/ipxe/scsi.h index b90aa3aa..5539b61d 100644 --- a/src/include/ipxe/scsi.h +++ b/src/include/ipxe/scsi.h @@ -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 */