diff options
author | Michael Brown | 2009-07-08 00:01:28 +0200 |
---|---|---|
committer | Michael Brown | 2009-07-18 00:01:20 +0200 |
commit | 54ec3673cc319a5646c21a87bbf41198b1f462b5 (patch) | |
tree | 1f9082322c78bc0b6110784198782126dd0394ee /src/drivers/block | |
parent | [scsi] Improve SCSI debugging (diff) | |
download | ipxe-54ec3673cc319a5646c21a87bbf41198b1f462b5.tar.gz ipxe-54ec3673cc319a5646c21a87bbf41198b1f462b5.tar.xz ipxe-54ec3673cc319a5646c21a87bbf41198b1f462b5.zip |
[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.
Diffstat (limited to 'src/drivers/block')
-rw-r--r-- | src/drivers/block/ata.c | 25 |
1 files changed, 24 insertions, 1 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 <stddef.h> #include <string.h> #include <assert.h> +#include <errno.h> #include <byteswap.h> #include <gpxe/blockdev.h> +#include <gpxe/process.h> #include <gpxe/ata.h> /** @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; } /** |