2
0
mirror of https://github.com/xcat2/xNBA.git synced 2025-02-19 03:54:38 +00:00

[scsi] Make SCSI command issuing partially asynchronous

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.
This commit is contained in:
Michael Brown 2009-07-07 23:00:11 +01:00
parent 51172783e2
commit 1d8d8ef2c8
4 changed files with 33 additions and 30 deletions

View File

@ -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
@ -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;

View File

@ -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

View File

@ -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 */
@ -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 );

View File

@ -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;
}
/****************************************************************************
@ -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,