summaryrefslogtreecommitdiffstats
path: root/src/net/fc.c
diff options
context:
space:
mode:
authorMichael Brown2011-06-24 23:49:10 +0200
committerMichael Brown2011-06-28 15:45:01 +0200
commitbf8bfa23e2364793ccdfc32627d8094a74ae87aa (patch)
tree53d20e95786d13330f92b1d1df539d608bcd7bf1 /src/net/fc.c
parent[ftp] Remove redundant ftp_data_deliver() method (diff)
downloadipxe-bf8bfa23e2364793ccdfc32627d8094a74ae87aa.tar.gz
ipxe-bf8bfa23e2364793ccdfc32627d8094a74ae87aa.tar.xz
ipxe-bf8bfa23e2364793ccdfc32627d8094a74ae87aa.zip
[fc] Maintain a list of Fibre Channel upper-layer protocol users
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/fc.c')
-rw-r--r--src/net/fc.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/src/net/fc.c b/src/net/fc.c
index 1934fab3..a94456c8 100644
--- a/src/net/fc.c
+++ b/src/net/fc.c
@@ -1580,7 +1580,7 @@ static void fc_ulp_close ( struct fc_ulp *ulp, int rc ) {
fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
/* Sanity check */
- assert ( ulp->usage == 0 );
+ assert ( list_empty ( &ulp->users ) );
/* Stop link monitor */
fc_link_stop ( &ulp->link );
@@ -1594,35 +1594,50 @@ static void fc_ulp_close ( struct fc_ulp *ulp, int rc ) {
}
/**
- * Increment Fibre Channel upper-layer protocol active usage count
+ * Attach Fibre Channel upper-layer protocol user
*
- * @v ulp Fibre Channel ulp
+ * @v ulp Fibre Channel upper-layer protocol
+ * @v user Fibre Channel upper-layer protocol user
*/
-void fc_ulp_increment ( struct fc_ulp *ulp ) {
+void fc_ulp_attach ( struct fc_ulp *ulp, struct fc_ulp_user *user ) {
+
+ /* Sanity check */
+ assert ( user->ulp == NULL );
/* Increment peer's usage count */
fc_peer_increment ( ulp->peer );
- /* Increment our usage count */
- ulp->usage++;
+ /* Attach user */
+ user->ulp = fc_ulp_get ( ulp );
+ list_add ( &user->list, &ulp->users );
}
/**
- * Decrement Fibre Channel upper-layer protocol active usage count
+ * Detach Fibre Channel upper-layer protocol user
*
- * @v ulp Fibre Channel ulp
+ * @v user Fibre Channel upper-layer protocol user
*/
-void fc_ulp_decrement ( struct fc_ulp *ulp ) {
+void fc_ulp_detach ( struct fc_ulp_user *user ) {
+ struct fc_ulp *ulp = user->ulp;
- /* Sanity check */
- assert ( ulp->usage > 0 );
+ /* Do nothing if not attached */
+ if ( ! ulp )
+ return;
- /* Decrement our usage count and log out if we reach zero */
- if ( --(ulp->usage) == 0 )
+ /* Sanity checks */
+ list_check_contains ( user, &ulp->users, list );
+
+ /* Detach user and log out if no users remain */
+ list_del ( &user->list );
+ if ( list_empty ( &ulp->users ) )
fc_ulp_logout ( ulp, 0 );
/* Decrement our peer's usage count */
fc_peer_decrement ( ulp->peer );
+
+ /* Drop reference */
+ user->ulp = NULL;
+ fc_ulp_put ( ulp );
}
/**
@@ -1712,7 +1727,7 @@ void fc_ulp_logout ( struct fc_ulp *ulp, int rc ) {
fc_link_err ( &ulp->link, rc );
/* Close ULP if there are no clients attached */
- if ( ulp->usage == 0 )
+ if ( list_empty ( &ulp->users ) )
fc_ulp_close ( ulp, rc );
}
@@ -1795,6 +1810,7 @@ static struct fc_ulp * fc_ulp_create ( struct fc_peer *peer,
ulp->peer = fc_peer_get ( peer );
list_add_tail ( &ulp->list, &peer->ulps );
ulp->type = type;
+ INIT_LIST_HEAD ( &ulp->users );
/* Start link state monitor */
fc_link_start ( &ulp->link );