[ata] Make ATA command issuing partially asynchronous
authorMichael Brown <mcb30@etherboot.org>
Tue, 7 Jul 2009 22:01:28 +0000 (23:01 +0100)
committerMichael Brown <mcb30@etherboot.org>
Fri, 17 Jul 2009 22:01:20 +0000 (23:01 +0100)
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
src/include/gpxe/ata.h
src/include/gpxe/errfile.h
src/net/aoe.c

index fd63645..dc851d7 100644 (file)
@@ -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;
 }
 
 /**
index 643b7cd..3c56584 100644 (file)
@@ -154,6 +154,8 @@ struct ata_command {
         * sectors in size.
         */
        userptr_t data_in;
+       /** Command status code */
+       int rc;
 };
 
 /**
index 7ca9c99..1312cbc 100644 (file)
@@ -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 )
index 9e6a99e..f274ddf 100644 (file)
@@ -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
  *