Skip to content

Commit

Permalink
[scsi] Make SCSI command issuing partially asynchronous
Browse files Browse the repository at this point in the history
Move the icky call to step() from iscsi.c to scsi.c; this takes it at
least one step further away from where it really doesn't belong.
  • Loading branch information
Michael Brown committed Jul 17, 2009
1 parent 5117278 commit 1d8d8ef
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 30 deletions.
18 changes: 15 additions & 3 deletions src/drivers/block/scsi.c
Expand Up @@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <byteswap.h>
#include <errno.h>
#include <gpxe/blockdev.h>
#include <gpxe/process.h>
#include <gpxe/scsi.h>

/** @file
Expand Down Expand Up @@ -57,11 +58,22 @@ static int scsi_command ( struct scsi_device *scsi,
/* Clear sense response code before issuing command */
command->sense_response = 0;

/* Flag command as in-progress */
command->rc = -EINPROGRESS;

/* Issue SCSI command */
if ( ( rc = scsi->command ( scsi, command ) ) != 0 ) {
/* Something went wrong with the issuing mechanism,
* (rather than with the command itself)
*/
/* Something went wrong with the issuing mechanism */
DBG ( "SCSI %p " SCSI_CDB_FORMAT " err %s\n",
scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) );
return rc;
}

/* Wait for command to complete */
while ( command->rc == -EINPROGRESS )
step();
if ( ( rc = command->rc ) != 0 ) {
/* Something went wrong with the command execution */
DBG ( "SCSI %p " SCSI_CDB_FORMAT " err %s\n",
scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) );
return rc;
Expand Down
5 changes: 0 additions & 5 deletions src/include/gpxe/iscsi.h
Expand Up @@ -614,11 +614,6 @@ struct iscsi_session {
* Set to NULL when command is complete.
*/
struct scsi_command *command;
/** SCSI command return code
*
* Set to -EINPROGRESS while command is processing.
*/
int rc;
/** Instant return code
*
* Set to a non-zero value if all requests should return
Expand Down
11 changes: 7 additions & 4 deletions src/include/gpxe/scsi.h
Expand Up @@ -236,6 +236,8 @@ struct scsi_command {
uint8_t status;
/** SCSI sense response code */
uint8_t sense_response;
/** Command status code */
int rc;
};

/** A SCSI device */
Expand All @@ -256,10 +258,11 @@ struct scsi_device {
* @ret rc Return status code
*
* Note that a successful return status code indicates only
* that the SCSI command completed. The caller must check the
* status field in the command structure to see if, for
* example, the device returned CHECK CONDITION or some other
* non-success status code.
* that the SCSI command was issued. The caller must check
* the status field in the command structure to see when the
* command completes and whether, for example, the device
* returned CHECK CONDITION or some other non-success status
* code.
*/
int ( * command ) ( struct scsi_device *scsi,
struct scsi_command *command );
Expand Down
29 changes: 11 additions & 18 deletions src/net/tcp/iscsi.c
Expand Up @@ -182,9 +182,10 @@ static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) {
static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc ) {

assert ( iscsi->tx_state == ISCSI_TX_IDLE );
assert ( iscsi->command != NULL );

iscsi->command->rc = rc;
iscsi->command = NULL;
iscsi->rc = rc;
}

/****************************************************************************
Expand Down Expand Up @@ -1550,32 +1551,24 @@ static int iscsi_command ( struct scsi_device *scsi,
container_of ( scsi->backend, struct iscsi_session, refcnt );
int rc;

/* Abort immediately if we have a recorded permanent failure */
if ( iscsi->instant_rc )
return iscsi->instant_rc;

/* Record SCSI command */
iscsi->command = command;

/* Abort immediately if we have a recorded permanent failure */
if ( iscsi->instant_rc ) {
rc = iscsi->instant_rc;
goto done;
}

/* Issue command or open connection as appropriate */
if ( iscsi->status ) {
iscsi_start_command ( iscsi );
} else {
if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
goto done;
if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
iscsi->command = NULL;
return rc;
}
}

/* Wait for command to complete */
iscsi->rc = -EINPROGRESS;
while ( iscsi->rc == -EINPROGRESS )
step();
rc = iscsi->rc;

done:
iscsi->command = NULL;
return rc;
return 0;
}

static int iscsi_detached_command ( struct scsi_device *scsi __unused,
Expand Down

0 comments on commit 1d8d8ef

Please sign in to comment.