diff options
author | Michael Brown | 2007-01-04 04:21:45 +0100 |
---|---|---|
committer | Michael Brown | 2007-01-04 04:21:45 +0100 |
commit | b22d4405c0c74aaac8a7f20c7bb13c4eb4f4af71 (patch) | |
tree | 15fa26d10adf7636db33fd4e39d8bf50dcd4f8f5 /src/net/aoe.c | |
parent | Minirouting table entries hold a persistent reference to a net_device. (diff) | |
download | ipxe-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.c | 23 |
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 ); } |