mirror of
https://github.com/ipxe/ipxe
synced 2025-12-20 03:55:46 +03:00
[scsi] Improve sense code parsing
Parse the sense data to extract the reponse code, the sense key, the additional sense code, and the additional sense code qualifier. Originally-implemented-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -132,6 +132,33 @@ int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse SCSI sense data
|
||||
*
|
||||
* @v data Raw sense data
|
||||
* @v len Length of raw sense data
|
||||
* @v sense Descriptor-format sense data to fill in
|
||||
*/
|
||||
void scsi_parse_sense ( const void *data, size_t len,
|
||||
struct scsi_sns_descriptor *sense ) {
|
||||
const union scsi_sns *sns = data;
|
||||
|
||||
/* Avoid returning uninitialised data */
|
||||
memset ( sense, 0, sizeof ( *sense ) );
|
||||
|
||||
/* Copy, assuming descriptor-format data */
|
||||
if ( len < sizeof ( sns->desc ) )
|
||||
return;
|
||||
memcpy ( sense, &sns->desc, sizeof ( *sense ) );
|
||||
|
||||
/* Convert fixed-format to descriptor-format, if applicable */
|
||||
if ( len < sizeof ( sns->fixed ) )
|
||||
return;
|
||||
if ( ! SCSI_SENSE_FIXED ( sns->code ) )
|
||||
return;
|
||||
sense->additional = sns->fixed.additional;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Interface methods
|
||||
@@ -468,9 +495,10 @@ static void scsicmd_response ( struct scsi_command *scsicmd,
|
||||
underrun = -(response->overrun);
|
||||
DBGC ( scsidev, " underrun -%zd", underrun );
|
||||
}
|
||||
DBGC ( scsidev, " sense %02x:%02x:%08x\n",
|
||||
response->sense.code, response->sense.key,
|
||||
ntohl ( response->sense.info ) );
|
||||
DBGC ( scsidev, " sense %02x key %02x additional %04x\n",
|
||||
( response->sense.code & SCSI_SENSE_CODE_MASK ),
|
||||
( response->sense.key & SCSI_SENSE_KEY_MASK ),
|
||||
ntohs ( response->sense.additional ) );
|
||||
|
||||
/* Construct error number from sense data */
|
||||
rc = -EIO_SENSE ( response->sense.key & SCSI_SENSE_KEY_MASK );
|
||||
|
||||
@@ -476,12 +476,14 @@ static int srp_rsp ( struct srp_device *srpdev,
|
||||
const struct srp_rsp *rsp = data;
|
||||
struct srp_command *srpcmd;
|
||||
struct scsi_rsp response;
|
||||
const void *sense;
|
||||
ssize_t data_out_residual_count;
|
||||
ssize_t data_in_residual_count;
|
||||
|
||||
/* Sanity check */
|
||||
if ( len < sizeof ( *rsp ) ) {
|
||||
if ( ( len < sizeof ( *rsp ) ) ||
|
||||
( len < ( sizeof ( *rsp ) +
|
||||
srp_rsp_response_data_len ( rsp ) +
|
||||
srp_rsp_sense_data_len ( rsp ) ) ) ) {
|
||||
DBGC ( srpdev, "SRP %p RSP too short (%zd bytes)\n",
|
||||
srpdev, len );
|
||||
return -EINVAL;
|
||||
@@ -523,9 +525,8 @@ static int srp_rsp ( struct srp_device *srpdev,
|
||||
} else if ( rsp->valid & SRP_RSP_VALID_DIUNDER ) {
|
||||
response.overrun = -(data_in_residual_count);
|
||||
}
|
||||
sense = srp_rsp_sense_data ( rsp );
|
||||
if ( sense )
|
||||
memcpy ( &response.sense, sense, sizeof ( response.sense ) );
|
||||
scsi_parse_sense ( srp_rsp_sense_data ( rsp ),
|
||||
srp_rsp_sense_data_len ( rsp ), &response.sense );
|
||||
|
||||
/* Report SCSI response */
|
||||
scsi_response ( &srpcmd->scsi, &response );
|
||||
|
||||
Reference in New Issue
Block a user