mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 20:40:25 +03:00
[block] Retry any SAN device operation
The SCSI layer currently implements a retry loop in order to retry commands that fail due to spurious "error" conditions such as "power on occurred". Move this retry loop to the generic SAN device layer: this allow for retries due to other transient error conditions such as an iSCSI target having dropped the connection due to inactivity. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -40,9 +40,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
/** 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 \
|
||||
@@ -283,9 +280,6 @@ struct scsi_command {
|
||||
/** Command tag */
|
||||
uint32_t tag;
|
||||
|
||||
/** Retry count */
|
||||
unsigned int retries;
|
||||
|
||||
/** Private data */
|
||||
uint8_t priv[0];
|
||||
};
|
||||
@@ -449,28 +443,11 @@ static int scsicmd_command ( struct scsi_command *scsicmd ) {
|
||||
* @v rc Reason for close
|
||||
*/
|
||||
static void scsicmd_done ( struct scsi_command *scsicmd, int rc ) {
|
||||
struct scsi_device *scsidev = scsicmd->scsidev;
|
||||
|
||||
/* Restart SCSI interface */
|
||||
intf_restart ( &scsicmd->scsi, rc );
|
||||
|
||||
/* SCSI targets have an annoying habit of returning occasional
|
||||
* pointless "error" messages such as "power-on occurred", so
|
||||
* we have to be prepared to retry commands.
|
||||
*/
|
||||
if ( ( rc != 0 ) && ( scsicmd->retries++ < SCSICMD_MAX_RETRIES ) ) {
|
||||
/* Retry command */
|
||||
DBGC ( scsidev, "SCSI %p tag %08x failed: %s\n",
|
||||
scsidev, scsicmd->tag, strerror ( rc ) );
|
||||
DBGC ( scsidev, "SCSI %p tag %08x retrying (retry %d)\n",
|
||||
scsidev, scsicmd->tag, scsicmd->retries );
|
||||
if ( ( rc = scsicmd_command ( scsicmd ) ) == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we didn't (successfully) reissue the command, hand over
|
||||
* to the command completion handler.
|
||||
*/
|
||||
/* Hand over to the command completion handler */
|
||||
scsicmd->type->done ( scsicmd, rc );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user