summaryrefslogtreecommitdiffstats
path: root/src/net/aoe.c
diff options
context:
space:
mode:
authorMichael Brown2007-07-29 03:31:14 +0200
committerMichael Brown2007-07-29 03:31:14 +0200
commit43013da9bf02439b4726d8afef15f7ce97d1c469 (patch)
treeb9cacbe294de8d0b06e04799746fc9377010ccb5 /src/net/aoe.c
parentApplied a modified version of holger's regparm patches. (diff)
downloadipxe-43013da9bf02439b4726d8afef15f7ce97d1c469.tar.gz
ipxe-43013da9bf02439b4726d8afef15f7ce97d1c469.tar.xz
ipxe-43013da9bf02439b4726d8afef15f7ce97d1c469.zip
Quick hack to get AoE back in to the tree, on a par with the current
iSCSI hack.
Diffstat (limited to 'src/net/aoe.c')
-rw-r--r--src/net/aoe.c130
1 files changed, 96 insertions, 34 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c
index 36721df6..fd82665d 100644
--- a/src/net/aoe.c
+++ b/src/net/aoe.c
@@ -19,6 +19,7 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
@@ -29,7 +30,7 @@
#include <gpxe/uaccess.h>
#include <gpxe/ata.h>
#include <gpxe/netdevice.h>
-#include <gpxe/async.h>
+#include <gpxe/process.h>
#include <gpxe/aoe.h>
/** @file
@@ -43,6 +44,14 @@ struct net_protocol aoe_protocol;
/** List of all AoE sessions */
static LIST_HEAD ( aoe_sessions );
+static void aoe_free ( struct refcnt *refcnt ) {
+ struct aoe_session *aoe =
+ container_of ( refcnt, struct aoe_session, refcnt );
+
+ netdev_put ( aoe->netdev );
+ free ( aoe );
+}
+
/**
* Mark current AoE command complete
*
@@ -55,8 +64,8 @@ static void aoe_done ( struct aoe_session *aoe, int rc ) {
aoe->command->cb.cmd_stat = aoe->status;
aoe->command = NULL;
- /* Mark async operation as complete */
- async_done ( &aoe->async, rc );
+ /* Mark operation as complete */
+ aoe->rc = rc;
}
/**
@@ -266,45 +275,98 @@ struct net_protocol aoe_protocol __net_protocol = {
};
/**
- * Open AoE session
- *
- * @v aoe AoE session
- */
-void aoe_open ( struct aoe_session *aoe ) {
- memcpy ( aoe->target, ethernet_protocol.ll_broadcast,
- sizeof ( aoe->target ) );
- aoe->tag = AOE_TAG_MAGIC;
- aoe->timer.expired = aoe_timer_expired;
- list_add ( &aoe->list, &aoe_sessions );
-}
-
-/**
- * Close AoE session
- *
- * @v aoe AoE session
- */
-void aoe_close ( struct aoe_session *aoe ) {
- list_del ( &aoe->list );
-}
-
-/**
* Issue ATA command via an open AoE session
*
- * @v aoe AoE session
+ * @v ata ATA device
* @v command ATA command
- * @v parent Parent asynchronous operation
* @ret rc Return status code
- *
- * Only one command may be issued concurrently per session. This call
- * is non-blocking; use async_wait() to wait for the command to
- * complete.
*/
-int aoe_issue ( struct aoe_session *aoe, struct ata_command *command,
- struct async *parent ) {
+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;
aoe->command_offset = 0;
aoe_send_command ( aoe );
- async_init ( &aoe->async, &default_async_operations, parent );
+
+ aoe->rc = -EINPROGRESS;
+ while ( aoe->rc == -EINPROGRESS )
+ step();
+ rc = aoe->rc;
+
+ return rc;
+}
+
+static int aoe_detached_command ( struct ata_device *ata __unused,
+ struct ata_command *command __unused ) {
+ return -ENODEV;
+}
+
+void aoe_detach ( struct ata_device *ata ) {
+ struct aoe_session *aoe =
+ container_of ( ata->backend, struct aoe_session, refcnt );
+
+ stop_timer ( &aoe->timer );
+ ata->command = aoe_detached_command;
+ list_del ( &aoe->list );
+ ref_put ( ata->backend );
+ ata->backend = NULL;
+}
+
+static int aoe_parse_root_path ( struct aoe_session *aoe,
+ const char *root_path ) {
+ char *ptr;
+
+ if ( strncmp ( root_path, "aoe:", 4 ) != 0 )
+ return -EINVAL;
+ ptr = ( ( char * ) root_path + 4 );
+
+ if ( *ptr++ != 'e' )
+ return -EINVAL;
+
+ aoe->major = strtoul ( ptr, &ptr, 10 );
+ if ( *ptr++ != '.' )
+ return -EINVAL;
+
+ aoe->minor = strtoul ( ptr, &ptr, 10 );
+ if ( *ptr )
+ return -EINVAL;
+
return 0;
}
+
+int aoe_attach ( struct ata_device *ata, struct net_device *netdev,
+ const char *root_path ) {
+ struct aoe_session *aoe;
+ int rc;
+
+ /* Allocate and initialise structure */
+ aoe = zalloc ( sizeof ( *aoe ) );
+ if ( ! aoe )
+ return -ENOMEM;
+ aoe->refcnt.free = aoe_free;
+ aoe->netdev = netdev_get ( netdev );
+ memcpy ( aoe->target, ethernet_protocol.ll_broadcast,
+ sizeof ( aoe->target ) );
+ aoe->tag = AOE_TAG_MAGIC;
+ aoe->timer.expired = aoe_timer_expired;
+
+ /* Parse root path */
+ if ( ( rc = aoe_parse_root_path ( aoe, root_path ) ) != 0 )
+ goto err;
+
+ /* Attach parent interface, transfer reference to connection
+ * list, and return
+ */
+ ata->backend = ref_get ( &aoe->refcnt );
+ ata->command = aoe_command;
+ list_add ( &aoe->list, &aoe_sessions );
+ return 0;
+
+ err:
+ ref_put ( &aoe->refcnt );
+ return rc;
+}