From 54ec3673cc319a5646c21a87bbf41198b1f462b5 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 7 Jul 2009 23:01:28 +0100 Subject: [PATCH] [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. --- src/drivers/block/ata.c | 25 ++++++++++++++++++++++++- src/include/gpxe/ata.h | 2 ++ src/include/gpxe/errfile.h | 1 + src/net/aoe.c | 10 ++-------- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/drivers/block/ata.c b/src/drivers/block/ata.c index fd636458..dc851d72 100644 --- a/src/drivers/block/ata.c +++ b/src/drivers/block/ata.c @@ -21,8 +21,10 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include +#include #include /** @file @@ -45,13 +47,34 @@ block_to_ata ( struct block_device *blockdev ) { */ static inline __attribute__ (( always_inline )) int ata_command ( struct ata_device *ata, struct ata_command *command ) { + int rc; + DBG ( "ATA cmd %02x dev %02x LBA%s %llx count %04x\n", command->cb.cmd_stat, command->cb.device, ( command->cb.lba48 ? "48" : "" ), ( unsigned long long ) command->cb.lba.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; } /** diff --git a/src/include/gpxe/ata.h b/src/include/gpxe/ata.h index 643b7cd9..3c565844 100644 --- a/src/include/gpxe/ata.h +++ b/src/include/gpxe/ata.h @@ -154,6 +154,8 @@ struct ata_command { * sectors in size. */ userptr_t data_in; + /** Command status code */ + int rc; }; /** diff --git a/src/include/gpxe/errfile.h b/src/include/gpxe/errfile.h index 7ca9c998..1312cbc9 100644 --- a/src/include/gpxe/errfile.h +++ b/src/include/gpxe/errfile.h @@ -115,6 +115,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 ) #define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 ) #define ERRFILE_linda ( ERRFILE_DRIVER | 0x00730000 ) +#define ERRFILE_ata ( ERRFILE_DRIVER | 0x00740000 ) #define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 ) #define ERRFILE_arp ( ERRFILE_NET | 0x00010000 ) diff --git a/src/net/aoe.c b/src/net/aoe.c index 9e6a99e2..f274ddf5 100644 --- a/src/net/aoe.c +++ b/src/net/aoe.c @@ -68,6 +68,7 @@ static void aoe_done ( struct aoe_session *aoe, int rc ) { /* Record overall command status */ if ( aoe->command ) { aoe->command->cb.cmd_stat = aoe->status; + aoe->command->rc = rc; aoe->command = NULL; } @@ -356,7 +357,6 @@ static int aoe_command ( struct ata_device *ata, struct ata_command *command ) { struct aoe_session *aoe = container_of ( ata->backend, struct aoe_session, refcnt ); - int rc; aoe->command = command; aoe->status = 0; @@ -365,15 +365,9 @@ static int aoe_command ( struct ata_device *ata, aoe_send_command ( aoe ); - aoe->rc = -EINPROGRESS; - while ( aoe->rc == -EINPROGRESS ) - step(); - rc = aoe->rc; - - return rc; + return 0; } - /** * Issue AoE config query for AoE target discovery *