[ata] Make ATA command issuing partially asynchronous
Move the icky call to step() from aoe.c to ata.c; this takes it at least one step further away from where it really doesn't belong. Unfortunately, AoE has the ugly aoe_discover() mechanism which means that we still have a step() loop in aoe.c for now; this needs to be replaced at some future point.
This commit is contained in:
parent
acfd7cc609
commit
54ec3673cc
|
@ -21,8 +21,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <gpxe/blockdev.h>
|
#include <gpxe/blockdev.h>
|
||||||
|
#include <gpxe/process.h>
|
||||||
#include <gpxe/ata.h>
|
#include <gpxe/ata.h>
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
|
@ -45,13 +47,34 @@ block_to_ata ( struct block_device *blockdev ) {
|
||||||
*/
|
*/
|
||||||
static inline __attribute__ (( always_inline )) int
|
static inline __attribute__ (( always_inline )) int
|
||||||
ata_command ( struct ata_device *ata, struct ata_command *command ) {
|
ata_command ( struct ata_device *ata, struct ata_command *command ) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
DBG ( "ATA cmd %02x dev %02x LBA%s %llx count %04x\n",
|
DBG ( "ATA cmd %02x dev %02x LBA%s %llx count %04x\n",
|
||||||
command->cb.cmd_stat, command->cb.device,
|
command->cb.cmd_stat, command->cb.device,
|
||||||
( command->cb.lba48 ? "48" : "" ),
|
( command->cb.lba48 ? "48" : "" ),
|
||||||
( unsigned long long ) command->cb.lba.native,
|
( unsigned long long ) command->cb.lba.native,
|
||||||
command->cb.count.native );
|
command->cb.count.native );
|
||||||
|
|
||||||
return ata->command ( ata, command );
|
/* Flag command as in-progress */
|
||||||
|
command->rc = -EINPROGRESS;
|
||||||
|
|
||||||
|
/* Issue ATA command */
|
||||||
|
if ( ( rc = ata->command ( ata, command ) ) != 0 ) {
|
||||||
|
/* Something went wrong with the issuing mechanism */
|
||||||
|
DBG ( "ATA could not issue command: %s\n", 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 ( "ATA command failed: %s\n", strerror ( rc ) );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -154,6 +154,8 @@ struct ata_command {
|
||||||
* sectors in size.
|
* sectors in size.
|
||||||
*/
|
*/
|
||||||
userptr_t data_in;
|
userptr_t data_in;
|
||||||
|
/** Command status code */
|
||||||
|
int rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -115,6 +115,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 )
|
#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 )
|
||||||
#define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 )
|
#define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 )
|
||||||
#define ERRFILE_linda ( ERRFILE_DRIVER | 0x00730000 )
|
#define ERRFILE_linda ( ERRFILE_DRIVER | 0x00730000 )
|
||||||
|
#define ERRFILE_ata ( ERRFILE_DRIVER | 0x00740000 )
|
||||||
|
|
||||||
#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 )
|
#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 )
|
||||||
#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 )
|
#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 )
|
||||||
|
|
|
@ -68,6 +68,7 @@ static void aoe_done ( struct aoe_session *aoe, int rc ) {
|
||||||
/* Record overall command status */
|
/* Record overall command status */
|
||||||
if ( aoe->command ) {
|
if ( aoe->command ) {
|
||||||
aoe->command->cb.cmd_stat = aoe->status;
|
aoe->command->cb.cmd_stat = aoe->status;
|
||||||
|
aoe->command->rc = rc;
|
||||||
aoe->command = NULL;
|
aoe->command = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +357,6 @@ static int aoe_command ( struct ata_device *ata,
|
||||||
struct ata_command *command ) {
|
struct ata_command *command ) {
|
||||||
struct aoe_session *aoe =
|
struct aoe_session *aoe =
|
||||||
container_of ( ata->backend, struct aoe_session, refcnt );
|
container_of ( ata->backend, struct aoe_session, refcnt );
|
||||||
int rc;
|
|
||||||
|
|
||||||
aoe->command = command;
|
aoe->command = command;
|
||||||
aoe->status = 0;
|
aoe->status = 0;
|
||||||
|
@ -365,15 +365,9 @@ static int aoe_command ( struct ata_device *ata,
|
||||||
|
|
||||||
aoe_send_command ( aoe );
|
aoe_send_command ( aoe );
|
||||||
|
|
||||||
aoe->rc = -EINPROGRESS;
|
return 0;
|
||||||
while ( aoe->rc == -EINPROGRESS )
|
|
||||||
step();
|
|
||||||
rc = aoe->rc;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issue AoE config query for AoE target discovery
|
* Issue AoE config query for AoE target discovery
|
||||||
*
|
*
|
||||||
|
|
Reference in New Issue