|
@@ -1651,6 +1651,8 @@ void fc_ulp_detach ( struct fc_ulp_user *user ) {
|
1651
|
1651
|
*/
|
1652
|
1652
|
int fc_ulp_login ( struct fc_ulp *ulp, const void *param, size_t param_len,
|
1653
|
1653
|
int originated ) {
|
|
1654
|
+ struct fc_ulp_user *user;
|
|
1655
|
+ struct fc_ulp_user *tmp;
|
1654
|
1656
|
|
1655
|
1657
|
/* Perform implicit logout if logged in and service parameters differ */
|
1656
|
1658
|
if ( fc_link_ok ( &ulp->link ) &&
|
|
@@ -1659,6 +1661,22 @@ int fc_ulp_login ( struct fc_ulp *ulp, const void *param, size_t param_len,
|
1659
|
1661
|
fc_ulp_logout ( ulp, 0 );
|
1660
|
1662
|
}
|
1661
|
1663
|
|
|
1664
|
+ /* Work around a bug in some versions of the Linux Fibre
|
|
1665
|
+ * Channel stack, which fail to fully initialise image pairs
|
|
1666
|
+ * established via a PRLI originated by the Linux stack
|
|
1667
|
+ * itself.
|
|
1668
|
+ */
|
|
1669
|
+ if ( originated )
|
|
1670
|
+ ulp->flags |= FC_ULP_ORIGINATED_LOGIN_OK;
|
|
1671
|
+ if ( ! ( ulp->flags & FC_ULP_ORIGINATED_LOGIN_OK ) ) {
|
|
1672
|
+ DBGC ( ulp, "FCULP %s/%02x sending extra PRLI to work around "
|
|
1673
|
+ "Linux bug\n",
|
|
1674
|
+ fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
|
|
1675
|
+ fc_link_stop ( &ulp->link );
|
|
1676
|
+ fc_link_start ( &ulp->link );
|
|
1677
|
+ return 0;
|
|
1678
|
+ }
|
|
1679
|
+
|
1662
|
1680
|
/* Log in, if applicable */
|
1663
|
1681
|
if ( ! fc_link_ok ( &ulp->link ) ) {
|
1664
|
1682
|
|
|
@@ -1685,18 +1703,11 @@ int fc_ulp_login ( struct fc_ulp *ulp, const void *param, size_t param_len,
|
1685
|
1703
|
/* Record login */
|
1686
|
1704
|
fc_link_up ( &ulp->link );
|
1687
|
1705
|
|
1688
|
|
- /* Work around a bug in some versions of the Linux Fibre
|
1689
|
|
- * Channel stack, which fail to fully initialise image pairs
|
1690
|
|
- * established via a PRLI originated by the Linux stack
|
1691
|
|
- * itself.
|
1692
|
|
- */
|
1693
|
|
- if ( originated )
|
1694
|
|
- ulp->flags |= FC_ULP_ORIGINATED_LOGIN_OK;
|
1695
|
|
- if ( ! ( ulp->flags & FC_ULP_ORIGINATED_LOGIN_OK ) ) {
|
1696
|
|
- DBGC ( ulp, "FCULP %s/%02x sending extra PRLI to work around "
|
1697
|
|
- "Linux bug\n",
|
1698
|
|
- fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
|
1699
|
|
- fc_link_start ( &ulp->link );
|
|
1706
|
+ /* Notify users of link state change */
|
|
1707
|
+ list_for_each_entry_safe ( user, tmp, &ulp->users, list ) {
|
|
1708
|
+ fc_ulp_user_get ( user );
|
|
1709
|
+ user->examine ( user );
|
|
1710
|
+ fc_ulp_user_put ( user );
|
1700
|
1711
|
}
|
1701
|
1712
|
|
1702
|
1713
|
return 0;
|
|
@@ -1709,6 +1720,8 @@ int fc_ulp_login ( struct fc_ulp *ulp, const void *param, size_t param_len,
|
1709
|
1720
|
* @v rc Reason for logout
|
1710
|
1721
|
*/
|
1711
|
1722
|
void fc_ulp_logout ( struct fc_ulp *ulp, int rc ) {
|
|
1723
|
+ struct fc_ulp_user *user;
|
|
1724
|
+ struct fc_ulp_user *tmp;
|
1712
|
1725
|
|
1713
|
1726
|
DBGC ( ulp, "FCULP %s/%02x logged out: %s\n",
|
1714
|
1727
|
fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
|
|
@@ -1726,6 +1739,13 @@ void fc_ulp_logout ( struct fc_ulp *ulp, int rc ) {
|
1726
|
1739
|
/* Record logout */
|
1727
|
1740
|
fc_link_err ( &ulp->link, rc );
|
1728
|
1741
|
|
|
1742
|
+ /* Notify users of link state change */
|
|
1743
|
+ list_for_each_entry_safe ( user, tmp, &ulp->users, list ) {
|
|
1744
|
+ fc_ulp_user_get ( user );
|
|
1745
|
+ user->examine ( user );
|
|
1746
|
+ fc_ulp_user_put ( user );
|
|
1747
|
+ }
|
|
1748
|
+
|
1729
|
1749
|
/* Close ULP if there are no clients attached */
|
1730
|
1750
|
if ( list_empty ( &ulp->users ) )
|
1731
|
1751
|
fc_ulp_close ( ulp, rc );
|