summaryrefslogtreecommitdiffstats
path: root/src/net/aoe.c
diff options
context:
space:
mode:
authorMichael Brown2007-01-04 04:21:45 +0100
committerMichael Brown2007-01-04 04:21:45 +0100
commitb22d4405c0c74aaac8a7f20c7bb13c4eb4f4af71 (patch)
tree15fa26d10adf7636db33fd4e39d8bf50dcd4f8f5 /src/net/aoe.c
parentMinirouting table entries hold a persistent reference to a net_device. (diff)
downloadipxe-b22d4405c0c74aaac8a7f20c7bb13c4eb4f4af71.tar.gz
ipxe-b22d4405c0c74aaac8a7f20c7bb13c4eb4f4af71.tar.xz
ipxe-b22d4405c0c74aaac8a7f20c7bb13c4eb4f4af71.zip
An AoE session holds a persistent reference to a net device.
Diffstat (limited to 'src/net/aoe.c')
-rw-r--r--src/net/aoe.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c
index 199cabf7..2dc5ed40 100644
--- a/src/net/aoe.c
+++ b/src/net/aoe.c
@@ -76,6 +76,12 @@ static int aoe_send_command ( struct aoe_session *aoe ) {
unsigned int count;
unsigned int data_out_len;
+ /* Fail immediately if we have no netdev to send on */
+ if ( ! aoe->netdev ) {
+ aoe_done ( aoe, -ENETUNREACH );
+ return -ENETUNREACH;
+ }
+
/* Calculate count and data_out_len for this subcommand */
count = command->cb.count.native;
if ( count > AOE_MAX_COUNT )
@@ -260,6 +266,19 @@ struct net_protocol aoe_protocol __net_protocol = {
};
/**
+ * Forget reference to net_device
+ *
+ * @v ref Persistent reference
+ */
+static void aoe_forget_netdev ( struct reference *ref ) {
+ struct aoe_session *aoe
+ = container_of ( ref, struct aoe_session, netdev_ref );
+
+ aoe->netdev = NULL;
+ ref_del ( &aoe->netdev_ref );
+}
+
+/**
* Open AoE session
*
* @v aoe AoE session
@@ -269,6 +288,8 @@ void aoe_open ( struct aoe_session *aoe ) {
sizeof ( aoe->target ) );
aoe->tag = AOE_TAG_MAGIC;
aoe->timer.expired = aoe_timer_expired;
+ aoe->netdev_ref.forget = aoe_forget_netdev;
+ ref_add ( &aoe->netdev_ref, &aoe->netdev->references );
list_add ( &aoe->list, &aoe_sessions );
}
@@ -278,6 +299,8 @@ void aoe_open ( struct aoe_session *aoe ) {
* @v aoe AoE session
*/
void aoe_close ( struct aoe_session *aoe ) {
+ if ( aoe->netdev )
+ ref_del ( &aoe->netdev_ref );
list_del ( &aoe->list );
}