Selaa lähdekoodia

[fc] Maintain a list of Fibre Channel upper-layer protocol users

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 vuotta sitten
vanhempi
commit
bf8bfa23e2
4 muutettua tiedostoa jossa 73 lisäystä ja 39 poistoa
  1. 28
    5
      src/include/ipxe/fc.h
  2. 30
    14
      src/net/fc.c
  3. 14
    18
      src/net/fcp.c
  4. 1
    2
      src/usr/fcmgmt.c

+ 28
- 5
src/include/ipxe/fc.h Näytä tiedosto

357
 
357
 
358
 	/** List of upper-layer protocols */
358
 	/** List of upper-layer protocols */
359
 	struct list_head ulps;
359
 	struct list_head ulps;
360
-	/** Active usage count */
360
+	/** Active usage count
361
+	 *
362
+	 * A peer (and attached ULPs) may be created in response to
363
+	 * unsolicited login requests received via the fabric.  We
364
+	 * track our own active usage count independently of the
365
+	 * existence of the peer, so that if the peer becomes logged
366
+	 * out (e.g. due to a link failure) then we know whether or
367
+	 * not we should attempt to relogin.
368
+	 */
361
 	unsigned int usage;
369
 	unsigned int usage;
362
 };
370
 };
363
 
371
 
424
 	/** Service parameter length */
432
 	/** Service parameter length */
425
 	size_t param_len;
433
 	size_t param_len;
426
 
434
 
427
-	/** Active usage count */
428
-	unsigned int usage;
435
+	/** Active users of this upper-layer protocol
436
+	 *
437
+	 * As with peers, an upper-layer protocol may be created in
438
+	 * response to an unsolicited login request received via the
439
+	 * fabric.  This list records the number of active users of
440
+	 * the ULP; the number of entries in the list is equivalent to
441
+	 * the peer usage count.
442
+	 */
443
+	struct list_head users;
429
 };
444
 };
430
 
445
 
431
 /** Fibre Channel upper-layer protocol flags */
446
 /** Fibre Channel upper-layer protocol flags */
434
 	FC_ULP_ORIGINATED_LOGIN_OK = 0x0001,
449
 	FC_ULP_ORIGINATED_LOGIN_OK = 0x0001,
435
 };
450
 };
436
 
451
 
452
+/** A Fibre Channel upper-layer protocol user */
453
+struct fc_ulp_user {
454
+	/** Fibre Channel upper layer protocol */
455
+	struct fc_ulp *ulp;
456
+	/** List of users */
457
+	struct list_head list;
458
+};
459
+
437
 /**
460
 /**
438
  * Get reference to Fibre Channel upper-layer protocol
461
  * Get reference to Fibre Channel upper-layer protocol
439
  *
462
  *
462
 fc_ulp_get_port_id_type ( struct fc_port *port,
485
 fc_ulp_get_port_id_type ( struct fc_port *port,
463
 			  const struct fc_port_id *peer_port_id,
486
 			  const struct fc_port_id *peer_port_id,
464
 			  unsigned int type );
487
 			  unsigned int type );
465
-extern void fc_ulp_increment ( struct fc_ulp *ulp );
466
-extern void fc_ulp_decrement ( struct fc_ulp *ulp );
488
+extern void fc_ulp_attach ( struct fc_ulp *ulp, struct fc_ulp_user *user );
489
+extern void fc_ulp_detach ( struct fc_ulp_user *user );
467
 extern int fc_ulp_login ( struct fc_ulp *ulp, const void *param,
490
 extern int fc_ulp_login ( struct fc_ulp *ulp, const void *param,
468
 			  size_t param_len, int originated );
491
 			  size_t param_len, int originated );
469
 extern void fc_ulp_logout ( struct fc_ulp *ulp, int rc );
492
 extern void fc_ulp_logout ( struct fc_ulp *ulp, int rc );

+ 30
- 14
src/net/fc.c Näytä tiedosto

1580
 	       fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
1580
 	       fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
1581
 
1581
 
1582
 	/* Sanity check */
1582
 	/* Sanity check */
1583
-	assert ( ulp->usage == 0 );
1583
+	assert ( list_empty ( &ulp->users ) );
1584
 
1584
 
1585
 	/* Stop link monitor */
1585
 	/* Stop link monitor */
1586
 	fc_link_stop ( &ulp->link );
1586
 	fc_link_stop ( &ulp->link );
1594
 }
1594
 }
1595
 
1595
 
1596
 /**
1596
 /**
1597
- * Increment Fibre Channel upper-layer protocol active usage count
1597
+ * Attach Fibre Channel upper-layer protocol user
1598
  *
1598
  *
1599
- * @v ulp		Fibre Channel ulp
1599
+ * @v ulp		Fibre Channel upper-layer protocol
1600
+ * @v user		Fibre Channel upper-layer protocol user
1600
  */
1601
  */
1601
-void fc_ulp_increment ( struct fc_ulp *ulp ) {
1602
+void fc_ulp_attach ( struct fc_ulp *ulp, struct fc_ulp_user *user ) {
1603
+
1604
+	/* Sanity check */
1605
+	assert ( user->ulp == NULL );
1602
 
1606
 
1603
 	/* Increment peer's usage count */
1607
 	/* Increment peer's usage count */
1604
 	fc_peer_increment ( ulp->peer );
1608
 	fc_peer_increment ( ulp->peer );
1605
 
1609
 
1606
-	/* Increment our usage count */
1607
-	ulp->usage++;
1610
+	/* Attach user */
1611
+	user->ulp = fc_ulp_get ( ulp );
1612
+	list_add ( &user->list, &ulp->users );
1608
 }
1613
 }
1609
 
1614
 
1610
 /**
1615
 /**
1611
- * Decrement Fibre Channel upper-layer protocol active usage count
1616
+ * Detach Fibre Channel upper-layer protocol user
1612
  *
1617
  *
1613
- * @v ulp		Fibre Channel ulp
1618
+ * @v user		Fibre Channel upper-layer protocol user
1614
  */
1619
  */
1615
-void fc_ulp_decrement ( struct fc_ulp *ulp ) {
1620
+void fc_ulp_detach ( struct fc_ulp_user *user ) {
1621
+	struct fc_ulp *ulp = user->ulp;
1616
 
1622
 
1617
-	/* Sanity check */
1618
-	assert ( ulp->usage > 0 );
1623
+	/* Do nothing if not attached */
1624
+	if ( ! ulp )
1625
+		return;
1619
 
1626
 
1620
-	/* Decrement our usage count and log out if we reach zero */
1621
-	if ( --(ulp->usage) == 0 )
1627
+	/* Sanity checks */
1628
+	list_check_contains ( user, &ulp->users, list );
1629
+
1630
+	/* Detach user and log out if no users remain */
1631
+	list_del ( &user->list );
1632
+	if ( list_empty ( &ulp->users ) )
1622
 		fc_ulp_logout ( ulp, 0 );
1633
 		fc_ulp_logout ( ulp, 0 );
1623
 
1634
 
1624
 	/* Decrement our peer's usage count */
1635
 	/* Decrement our peer's usage count */
1625
 	fc_peer_decrement ( ulp->peer );
1636
 	fc_peer_decrement ( ulp->peer );
1637
+
1638
+	/* Drop reference */
1639
+	user->ulp = NULL;
1640
+	fc_ulp_put ( ulp );
1626
 }
1641
 }
1627
 
1642
 
1628
 /**
1643
 /**
1712
 	fc_link_err ( &ulp->link, rc );
1727
 	fc_link_err ( &ulp->link, rc );
1713
 
1728
 
1714
 	/* Close ULP if there are no clients attached */
1729
 	/* Close ULP if there are no clients attached */
1715
-	if ( ulp->usage == 0 )
1730
+	if ( list_empty ( &ulp->users ) )
1716
 		fc_ulp_close ( ulp, rc );
1731
 		fc_ulp_close ( ulp, rc );
1717
 }
1732
 }
1718
 
1733
 
1795
 	ulp->peer = fc_peer_get ( peer );
1810
 	ulp->peer = fc_peer_get ( peer );
1796
 	list_add_tail ( &ulp->list, &peer->ulps );
1811
 	list_add_tail ( &ulp->list, &peer->ulps );
1797
 	ulp->type = type;
1812
 	ulp->type = type;
1813
+	INIT_LIST_HEAD ( &ulp->users );
1798
 
1814
 
1799
 	/* Start link state monitor */
1815
 	/* Start link state monitor */
1800
 	fc_link_start ( &ulp->link );
1816
 	fc_link_start ( &ulp->link );

+ 14
- 18
src/net/fcp.c Näytä tiedosto

146
 struct fcp_device {
146
 struct fcp_device {
147
 	/** Reference count */
147
 	/** Reference count */
148
 	struct refcnt refcnt;
148
 	struct refcnt refcnt;
149
-	/** Fibre Channel upper-layer protocol */
150
-	struct fc_ulp *ulp;
149
+	/** Fibre Channel upper-layer protocol user */
150
+	struct fc_ulp_user user;
151
 	/** SCSI command issuing interface */
151
 	/** SCSI command issuing interface */
152
 	struct interface scsi;
152
 	struct interface scsi;
153
 	/** List of active commands */
153
 	/** List of active commands */
734
 static int fcpdev_scsi_command ( struct fcp_device *fcpdev,
734
 static int fcpdev_scsi_command ( struct fcp_device *fcpdev,
735
 				 struct interface *parent,
735
 				 struct interface *parent,
736
 				 struct scsi_cmd *command ) {
736
 				 struct scsi_cmd *command ) {
737
-	struct fcp_prli_service_parameters *param = fcpdev->ulp->param;
737
+	struct fcp_prli_service_parameters *param = fcpdev->user.ulp->param;
738
 	struct fcp_command *fcpcmd;
738
 	struct fcp_command *fcpcmd;
739
 	int xchg_id;
739
 	int xchg_id;
740
 	int rc;
740
 	int rc;
741
 
741
 
742
 	/* Check link */
742
 	/* Check link */
743
-	if ( ( rc = fcpdev->ulp->link.rc ) != 0 ) {
743
+	if ( ( rc = fcpdev->user.ulp->link.rc ) != 0 ) {
744
 		DBGC ( fcpdev, "FCP %p could not issue command while link is "
744
 		DBGC ( fcpdev, "FCP %p could not issue command while link is "
745
 		       "down: %s\n", fcpdev, strerror ( rc ) );
745
 		       "down: %s\n", fcpdev, strerror ( rc ) );
746
 		goto err_link;
746
 		goto err_link;
748
 
748
 
749
 	/* Check target capability */
749
 	/* Check target capability */
750
 	assert ( param != NULL );
750
 	assert ( param != NULL );
751
-	assert ( fcpdev->ulp->param_len >= sizeof ( *param ) );
751
+	assert ( fcpdev->user.ulp->param_len >= sizeof ( *param ) );
752
 	if ( ! ( param->flags & htonl ( FCP_PRLI_TARGET ) ) ) {
752
 	if ( ! ( param->flags & htonl ( FCP_PRLI_TARGET ) ) ) {
753
 		DBGC ( fcpdev, "FCP %p could not issue command: not a target\n",
753
 		DBGC ( fcpdev, "FCP %p could not issue command: not a target\n",
754
 		       fcpdev );
754
 		       fcpdev );
772
 
772
 
773
 	/* Create new exchange */
773
 	/* Create new exchange */
774
 	if ( ( xchg_id = fc_xchg_originate ( &fcpcmd->xchg,
774
 	if ( ( xchg_id = fc_xchg_originate ( &fcpcmd->xchg,
775
-					     fcpdev->ulp->peer->port,
776
-					     &fcpdev->ulp->peer->port_id,
775
+					     fcpdev->user.ulp->peer->port,
776
+					     &fcpdev->user.ulp->peer->port_id,
777
 					     FC_TYPE_FCP ) ) < 0 ) {
777
 					     FC_TYPE_FCP ) ) < 0 ) {
778
 		rc = xchg_id;
778
 		rc = xchg_id;
779
 		DBGC ( fcpdev, "FCP %p could not create exchange: %s\n",
779
 		DBGC ( fcpdev, "FCP %p could not create exchange: %s\n",
822
 	}
822
 	}
823
 
823
 
824
 	/* Drop reference to ULP */
824
 	/* Drop reference to ULP */
825
-	if ( fcpdev->ulp ) {
826
-		fc_ulp_decrement ( fcpdev->ulp );
827
-		fc_ulp_put ( fcpdev->ulp );
828
-		fcpdev->ulp = NULL;
829
-	}
825
+	fc_ulp_detach ( &fcpdev->user );
830
 }
826
 }
831
 
827
 
832
 /**
828
 /**
836
  * @ret len		Length of window
832
  * @ret len		Length of window
837
  */
833
  */
838
 static size_t fcpdev_window ( struct fcp_device *fcpdev ) {
834
 static size_t fcpdev_window ( struct fcp_device *fcpdev ) {
839
-	return ( fc_link_ok ( &fcpdev->ulp->link ) ? ~( ( size_t ) 0 ) : 0 );
835
+	return ( fc_link_ok ( &fcpdev->user.ulp->link ) ?
836
+		 ~( ( size_t ) 0 ) : 0 );
840
 }
837
 }
841
 
838
 
842
 /**
839
 /**
897
 	/* We know the underlying device only if the link is up;
894
 	/* We know the underlying device only if the link is up;
898
 	 * otherwise we don't have a port to examine.
895
 	 * otherwise we don't have a port to examine.
899
 	 */
896
 	 */
900
-	if ( ! fc_link_ok ( &fcpdev->ulp->link ) ) {
897
+	if ( ! fc_link_ok ( &fcpdev->user.ulp->link ) ) {
901
 		DBGC ( fcpdev, "FCP %p doesn't know underlying device "
898
 		DBGC ( fcpdev, "FCP %p doesn't know underlying device "
902
 		       "until link is up\n", fcpdev );
899
 		       "until link is up\n", fcpdev );
903
 		return NULL;
900
 		return NULL;
904
 	}
901
 	}
905
 
902
 
906
 	/* Hand off to port's transport interface */
903
 	/* Hand off to port's transport interface */
907
-	assert ( fcpdev->ulp->peer->port != NULL );
908
-	return identify_device ( &fcpdev->ulp->peer->port->transport );
904
+	assert ( fcpdev->user.ulp->peer->port != NULL );
905
+	return identify_device ( &fcpdev->user.ulp->peer->port->transport );
909
 }
906
 }
910
 
907
 
911
 /** FCP device SCSI interface operations */
908
 /** FCP device SCSI interface operations */
953
 	ref_init ( &fcpdev->refcnt, NULL );
950
 	ref_init ( &fcpdev->refcnt, NULL );
954
 	intf_init ( &fcpdev->scsi, &fcpdev_scsi_desc, &fcpdev->refcnt );
951
 	intf_init ( &fcpdev->scsi, &fcpdev_scsi_desc, &fcpdev->refcnt );
955
 	INIT_LIST_HEAD ( &fcpdev->fcpcmds );
952
 	INIT_LIST_HEAD ( &fcpdev->fcpcmds );
956
-	fcpdev->ulp = fc_ulp_get ( ulp );
957
-	fc_ulp_increment ( fcpdev->ulp );
953
+	fc_ulp_attach ( ulp, &fcpdev->user );
958
 
954
 
959
 	DBGC ( fcpdev, "FCP %p opened for %s\n", fcpdev, fc_ntoa ( wwn ) );
955
 	DBGC ( fcpdev, "FCP %p opened for %s\n", fcpdev, fc_ntoa ( wwn ) );
960
 
956
 

+ 1
- 2
src/usr/fcmgmt.c Näytä tiedosto

74
 	}
74
 	}
75
 
75
 
76
 	list_for_each_entry ( ulp, &peer->ulps, list ) {
76
 	list_for_each_entry ( ulp, &peer->ulps, list ) {
77
-		printf ( "  [Type %02x usage %d link:",
78
-			 ulp->type, ulp->usage );
77
+		printf ( "  [Type %02x link:", ulp->type );
79
 		if ( fc_link_ok ( &ulp->link ) ) {
78
 		if ( fc_link_ok ( &ulp->link ) ) {
80
 			printf ( " up, params" );
79
 			printf ( " up, params" );
81
 			param = ulp->param;
80
 			param = ulp->param;

Loading…
Peruuta
Tallenna