Action Functions (called without LP lock, locks, calls an _enter_ and unlocks)
 fc_lport_rport_event
 fc_fabric_login
 fc_linkup
 fc_linkdown
 fc_pause
 fc_unpause
 fc_fabric_logoff
 fc_lport_destroy
 fc_lport_timeout
        - needs to be called from a work thread

 fc_lport_recv
        - Calls one of the request handlers with the lock held
        - should it just call fc_lport_recv_req or call rport_recv?

Request Handlers (called without lock, will lock process and unlock)
 fc_lport_rlir_req
 fc_lport_echo_req
 fc_lport_rnid_req
 fc_lport_recv_logo_req
 fc_lport_recv_flogi_req

Response Handlers (called without lock, lock, call an _enter_ function and 
unlock)
 fc_lport_rpn_id_resp
 fc_lport_rft_id_resp
 fc_lport_scr_resp
 fc_lport_logo_resp
 fc_lport_flogi_resp

Enter Functions (called with lock held)
 fc_lport_enter_reset
 fc_lport_enter_flogi
 fc_lport_enter_scr
 fc_lport_enter_rft_id
 fc_lport_enter_rpn_id
 fc_lport_enter_dns
 fc_lport_enter_ready
 fc_lport_enter_logo

Helper Functions (need lock held)
 fc_lport_flogi_fill (mfs, wwnn, wwpn, tovs)
 fc_lport_set_fid
 fc_lport_add_fc4_type
 fc_set_mfs
 fc_lport_error
 - should start a work thread for fc_lport_timeout or call fc_lport_reject
 - rename fc_lport_enter_reject to fc_lport_reject

Helper Functions (don't need lock held)
 fc_frame_drop
 fc_lport_state
 fc_lport_ptp_setup
 fc_lport_ptp_clear
 fc_lport_dns_acc
 fc_lport_config
 fc_lport_init

Unknown
 fc_lport_enter_retry (likely to merge into fc_lport_error)
 fc_lport_retry (likely to merge into fc_lport_error)
 fc_lport_enter_reject
 fc_lport_flogi_send
        - Do we need a "send" function? Can't enter_flogi() do this?

Signed-off-by: Robert Love <[EMAIL PROTECTED]>
---

 drivers/scsi/fcoe/fcoeinit.c  |    4 
 drivers/scsi/libfc/fc_lport.c |  674 +++++++++++++++++++++++++++--------------
 drivers/scsi/libfc/fc_ns.c    |   10 -
 include/scsi/libfc/libfc.h    |   33 --
 4 files changed, 449 insertions(+), 272 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoeinit.c b/drivers/scsi/fcoe/fcoeinit.c
index e069835..38dd8cc 100644
--- a/drivers/scsi/fcoe/fcoeinit.c
+++ b/drivers/scsi/fcoe/fcoeinit.c
@@ -53,8 +53,8 @@ struct scsi_transport_template *fcoe_transport_template;
 
 static int fcoe_reset(struct Scsi_Host *shost)
 {
-       struct fc_lport *lp = shost_priv(shost);
-       fc_lport_enter_reset(lp);
+       struct fc_lport *lport = shost_priv(shost);
+       fc_lport_reset(lport);
        return 0;
 }
 
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 708332f..6f1e890 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -38,10 +38,11 @@ static int fc_lport_debug;
 
 static void fc_lport_error(struct fc_lport *, struct fc_frame *);
 
+static void fc_lport_enter_reset(struct fc_lport *);
 static void fc_lport_enter_flogi(struct fc_lport *);
 static void fc_lport_enter_dns(struct fc_lport *);
-static void fc_lport_enter_reg_pn(struct fc_lport *);
-static void fc_lport_enter_reg_ft(struct fc_lport *);
+static void fc_lport_enter_rpn_id(struct fc_lport *);
+static void fc_lport_enter_rft_id(struct fc_lport *);
 static void fc_lport_enter_scr(struct fc_lport *);
 static void fc_lport_enter_ready(struct fc_lport *);
 static void fc_lport_enter_logo(struct fc_lport *);
@@ -50,8 +51,8 @@ static const char *fc_lport_state_names[] = {
        [LPORT_ST_NONE] =     "none",
        [LPORT_ST_FLOGI] =    "FLOGI",
        [LPORT_ST_DNS] =      "dNS",
-       [LPORT_ST_REG_PN] =   "REG_PN",
-       [LPORT_ST_REG_FT] =   "REG_FT",
+       [LPORT_ST_RPN_ID] =   "RPN_ID",
+       [LPORT_ST_RFT_ID] =   "RFT_ID",
        [LPORT_ST_SCR] =      "SCR",
        [LPORT_ST_READY] =    "Ready",
        [LPORT_ST_LOGO] =     "LOGO",
@@ -67,23 +68,22 @@ static int fc_frame_drop(struct fc_lport *lport, struct 
fc_frame *fp)
 static void fc_lport_rport_event(struct fc_lport *lport, struct fc_rport 
*rport,
                                 enum fc_lport_event event)
 {
-       fc_lport_lock(lport);
+       mutex_lock(&lport->lp_mutex);
+
        if (rport->port_id == FC_FID_DIR_SERV) {
                switch (event) {
                case LPORT_EV_RPORT_CREATED:
                        lport->dns_rp = rport;
-                       fc_lport_enter_dns(lport);
+                       fc_lport_enter_rpn_id(lport);
                        break;
                case LPORT_EV_RPORT_LOGO:
                case LPORT_EV_RPORT_FAILED:
                        lport->dns_rp = NULL;
-                       fc_lport_lock(lport);
-                       fc_lport_enter_reset(lport);
-                       fc_lport_unlock(lport);
+                       fc_lport_enter_dns(lport);
                        break;
                }
        }
-       fc_lport_unlock(lport);
+       mutex_unlock(&lport->lp_mutex);
 }
 
 static const char *fc_lport_state(struct fc_lport *lport)
@@ -111,11 +111,11 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
         * if we have to create a rport the fc class can sleep so we must
         * drop the lock here
         */
-       fc_lport_unlock(lport);
+
        rport = lport->tt.rport_lookup(lport, ids.port_id); /* lookup and hold 
*/
        if (!rport)
                rport = lport->tt.rport_create(lport, &ids); /* create and hold 
*/
-       fc_lport_lock(lport);
+
        if (rport) {
                if (lport->ptp_rp)
                        fc_remote_port_delete(lport->ptp_rp);
@@ -147,26 +147,6 @@ void fc_get_host_port_state(struct Scsi_Host *shost)
 EXPORT_SYMBOL(fc_get_host_port_state);
 
 /*
- * Test for dNS accept in response payload.
- */
-static int fc_lport_dns_acc(struct fc_frame *fp)
-{
-       struct fc_frame_header *fh;
-       struct fc_ct_hdr *ct;
-       int rc = 0;
-
-       fh = fc_frame_header_get(fp);
-       ct = fc_frame_payload_get(fp, sizeof(*ct));
-       if (fh && ct && fh->fh_type == FC_TYPE_CT &&
-           ct->ct_fs_type == FC_FST_DIR &&
-           ct->ct_fs_subtype == FC_NS_SUBTYPE &&
-           ntohs(ct->ct_cmd) == FC_FS_ACC) {
-               rc = 1;
-       }
-       return rc;
-}
-
-/*
  * Fill in FLOGI command for request.
  */
 static void
@@ -210,21 +190,37 @@ static void fc_lport_add_fc4_type(struct fc_lport *lport, 
enum fc_fh_type type)
        *mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW));
 }
 
-/*
- * Handle received RLIR - registered link incident report.
+/**
+ * fc_lport_recv_rlir_req - Handle received Registered Link Incident Report.
+ * @lport: Fibre Channel local port recieving the RLIR
+ * @sp: current sequence in the RLIR exchange
+ * @fp: RLIR request frame
+ *
+ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
  */
-static void fc_lport_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
-                             struct fc_lport *lport)
+static void fc_lport_recv_rlir_req(struct fc_seq *sp, struct fc_frame *fp,
+                                  struct fc_lport *lport)
 {
+       if (fc_lport_debug)
+               FC_DBG("Received RLIR request while in state %s\n",
+                      fc_lport_state(lport));
+
        lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
        fc_frame_free(fp);
 }
 
-/*
- * Handle received ECHO.
+/**
+ * fc_lport_recv_echo_req - Handle received ECHO request
+ * @lport: Fibre Channel local port recieving the ECHO
+ * @sp: current sequence in the ECHO exchange
+ * @fp: ECHO request frame
+ *
+ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
  */
-static void fc_lport_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
-                             struct fc_lport *lport)
+static void fc_lport_recv_echo_req(struct fc_seq *sp, struct fc_frame *in_fp,
+                                  struct fc_lport *lport)
 {
        struct fc_frame *fp;
        unsigned int len;
@@ -232,11 +228,16 @@ static void fc_lport_echo_req(struct fc_seq *sp, struct 
fc_frame *in_fp,
        void *dp;
        u32 f_ctl;
 
+       if (fc_lport_debug)
+               FC_DBG("Received RLIR request while in state %s\n",
+                      fc_lport_state(lport));
+
        len = fr_len(in_fp) - sizeof(struct fc_frame_header);
        pp = fc_frame_payload_get(in_fp, len);
 
        if (len < sizeof(__be32))
                len = sizeof(__be32);
+
        fp = fc_frame_alloc(lport, len);
        if (fp) {
                dp = fc_frame_payload_get(fp, len);
@@ -250,11 +251,17 @@ static void fc_lport_echo_req(struct fc_seq *sp, struct 
fc_frame *in_fp,
        fc_frame_free(in_fp);
 }
 
-/*
- * Handle received RNID.
+/**
+ * fc_lport_recv_echo_req - Handle received Request Node ID data request
+ * @lport: Fibre Channel local port recieving the RNID
+ * @sp: current sequence in the RNID exchange
+ * @fp: RNID request frame
+ *
+ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
  */
-static void fc_lport_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
-                             struct fc_lport *lport)
+static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
+                                  struct fc_lport *lport)
 {
        struct fc_frame *fp;
        struct fc_els_rnid *req;
@@ -268,6 +275,10 @@ static void fc_lport_rnid_req(struct fc_seq *sp, struct 
fc_frame *in_fp,
        size_t len;
        u32 f_ctl;
 
+       if (fc_lport_debug)
+               FC_DBG("Received RNID request while in state %s\n",
+                      fc_lport_state(lport));
+
        req = fc_frame_payload_get(in_fp, sizeof(*req));
        if (!req) {
                rjt_data.fp = NULL;
@@ -305,31 +316,34 @@ static void fc_lport_rnid_req(struct fc_seq *sp, struct 
fc_frame *in_fp,
        fc_frame_free(in_fp);
 }
 
-/*
- * Handle received fabric logout request.
+/**
+ * fc_lport_recv_logo_req - Handle received fabric LOGO request
+ * @lport: Fibre Channel local port recieving the LOGO
+ * @sp: current sequence in the LOGO exchange
+ * @fp: LOGO request frame
+ *
+ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
  */
 static void fc_lport_recv_logo_req(struct fc_seq *sp, struct fc_frame *fp,
-                                  struct fc_lport *lp)
+                                  struct fc_lport *lport)
 {
-       lp->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
-       fc_lport_enter_reset(lp);
+       lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
+       fc_lport_enter_reset(lport);
        fc_frame_free(fp);
 }
 
-/*
- * Receive request frame
- */
-
 int fc_fabric_login(struct fc_lport *lport)
 {
        int rc = -1;
 
+       mutex_lock(&lport->lp_mutex);
        if (lport->state == LPORT_ST_NONE) {
-               fc_lport_lock(lport);
                fc_lport_enter_reset(lport);
-               fc_lport_unlock(lport);
                rc = 0;
        }
+       mutex_unlock(&lport->lp_mutex);
+
        return rc;
 }
 EXPORT_SYMBOL(fc_fabric_login);
@@ -340,55 +354,79 @@ EXPORT_SYMBOL(fc_fabric_login);
  **/
 void fc_linkup(struct fc_lport *lport)
 {
+       mutex_lock(&lport->lp_mutex);
        if ((lport->link_status & FC_LINK_UP) != FC_LINK_UP) {
                lport->link_status |= FC_LINK_UP;
-               fc_lport_lock(lport);
+               
                if (lport->state == LPORT_ST_RESET)
                        fc_lport_enter_flogi(lport);
-               fc_lport_unlock(lport);
        }
+       mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_linkup);
 
 /**
  * fc_linkdown -  link down notification
- * @dev:      Pointer to fc_lport .
+ * @lport:        Pointer to fc_lport
  **/
 void fc_linkdown(struct fc_lport *lport)
 {
+       mutex_lock(&lport->lp_mutex);
+
        if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP) {
                lport->link_status &= ~(FC_LINK_UP);
                fc_lport_enter_reset(lport);
                lport->tt.scsi_cleanup(lport);
        }
+
+       mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_linkdown);
 
+/**
+ * fc_pause -     Pause the flow of frames
+ * @lport:        Pointer to fc_lport
+ **/
 void fc_pause(struct fc_lport *lport)
 {
+       mutex_lock(&lport->lp_mutex);
        lport->link_status |= FC_PAUSE;
+       mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_pause);
 
+/**
+ * fc_unpause -   Unpause the flow of frames
+ * @lport:        Pointer to fc_lport
+ **/
 void fc_unpause(struct fc_lport *lport)
 {
+       mutex_lock(&lport->lp_mutex);
        lport->link_status &= ~(FC_PAUSE);
+       mutex_unlock(&lport->lp_mutex);
 }
 EXPORT_SYMBOL(fc_unpause);
 
+/**
+ * fc_fabric_logoff - Logout of the fabric
+ * @lport:           fc_lport pointer to logoff the fabric
+ *
+ * Return value:
+ *     0 for success, -1 for failure
+ **/
 int fc_fabric_logoff(struct fc_lport *lport)
 {
-       fc_lport_lock(lport);
+       mutex_lock(&lport->lp_mutex);
        fc_lport_enter_logo(lport);
-       fc_lport_unlock(lport);
        lport->tt.scsi_cleanup(lport);
+       mutex_unlock(&lport->lp_mutex);
        return 0;
 }
 EXPORT_SYMBOL(fc_fabric_logoff);
 
 /**
  * fc_lport_destroy - unregister a fc_lport
- * @lport:        fc_lport pointer to unregister
+ * @lport:           fc_lport pointer to unregister
  *
  * Return value:
  *     None
@@ -400,18 +438,12 @@ EXPORT_SYMBOL(fc_fabric_logoff);
  **/
 int fc_lport_destroy(struct fc_lport *lport)
 {
-       fc_lport_lock(lport);
-       fc_lport_state_enter(lport, LPORT_ST_LOGO);
-       fc_lport_unlock(lport);
-
+       mutex_lock(&lport->lp_mutex);
        cancel_delayed_work_sync(&lport->ns_disc_work);
-
        lport->tt.scsi_abort_io(lport);
-
        lport->tt.frame_send = fc_frame_drop;
-
        lport->tt.exch_mgr_reset(lport->emp, 0, 0);
-
+       mutex_unlock(&lport->lp_mutex);
        return 0;
 }
 EXPORT_SYMBOL(fc_lport_destroy);
@@ -421,6 +453,8 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs)
        unsigned int old_mfs;
        int rc = -1;
 
+       mutex_lock(&lport->lp_mutex);
+
        old_mfs = lport->mfs;
 
        if (mfs >= FC_MIN_MAX_FRAME) {
@@ -437,17 +471,29 @@ int fc_set_mfs(struct fc_lport *lport, u32 mfs)
                lport->ns_disc_done = 0;
                fc_lport_enter_reset(lport);
        }
+
+       mutex_unlock(&lport->lp_mutex);
+
        return rc;
 }
 EXPORT_SYMBOL(fc_set_mfs);
 
+/**
+ * fc_rport_enter_ready - Enter the ready state and start discovery
+ * @lport: Fibre Channel local port that is ready
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
 static void fc_lport_enter_ready(struct fc_lport *lport)
 {
        if (fc_lport_debug)
                FC_DBG("Port (%6x) entered Ready from state %s\n",
                       lport->fid, fc_lport_state(lport));
-
+       
        fc_lport_state_enter(lport, LPORT_ST_READY);
+
+       lport->tt.disc_start(lport);
 }
 
 /*
@@ -460,8 +506,8 @@ static void fc_lport_reject(struct fc_lport *lport)
        case LPORT_ST_NONE:
        case LPORT_ST_READY:
        case LPORT_ST_RESET:
-       case LPORT_ST_REG_PN:
-       case LPORT_ST_REG_FT:
+       case LPORT_ST_RPN_ID:
+       case LPORT_ST_RFT_ID:
        case LPORT_ST_SCR:
        case LPORT_ST_DNS:
        case LPORT_ST_FLOGI:
@@ -471,10 +517,18 @@ static void fc_lport_reject(struct fc_lport *lport)
        }
 }
 
-/*
+/**
+ * fc_lport_recv_flogi_req - Handle received FLOGI request
+ * @lport: Fibre Channel local port recieving the FLOGI
+ * @sp: current sequence in the FLOGI exchange
+ * @fp: FLOGI request frame
+ *
  * A received FLOGI request indicates a point-to-point connection.
  * Accept it with the common service parameters indicating our N port.
  * Set up to do a PLOGI if we have the higher-number WWPN.
+ *
+ * Locking Note: The lport lock is exected to be held before calling
+ * this function.
  */
 static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
                                    struct fc_frame *rx_fp,
@@ -489,6 +543,10 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
        u32 remote_fid;
        u32 local_fid;
        u32 f_ctl;
+       
+       if (fc_lport_debug)
+               FC_DBG("Received FLOGI request while in state %s\n",
+                      fc_lport_state(lport));
 
        fh = fc_frame_header_get(rx_fp);
        remote_fid = ntoh24(fh->fh_s_id);
@@ -502,7 +560,6 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
                goto out;
        }
        FC_DBG("FLOGI from port WWPN %llx\n", remote_wwpn);
-       fc_lport_lock(lport);
 
        /*
         * XXX what is the right thing to do for FIDs?
@@ -540,7 +597,7 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
        }
        fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
                           get_unaligned_be64(&flp->fl_wwnn));
-       fc_lport_unlock(lport);
+
        if (lport->tt.disc_start(lport))
                FC_DBG("target discovery start error\n");
 out:
@@ -548,8 +605,8 @@ out:
        fc_frame_free(rx_fp);
 }
 
-static void fc_lport_recv(struct fc_lport *lport, struct fc_seq *sp,
-                         struct fc_frame *fp)
+static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
+                             struct fc_frame *fp)
 {
        struct fc_frame_header *fh = fc_frame_header_get(fp);
        void (*recv) (struct fc_seq *, struct fc_frame *, struct fc_lport *);
@@ -558,6 +615,8 @@ static void fc_lport_recv(struct fc_lport *lport, struct 
fc_seq *sp,
        u32 d_id;
        struct fc_seq_els_data rjt_data;
 
+       mutex_lock(&lport->lp_mutex);
+
        /*
         * Handle special ELS cases like FLOGI, LOGO, and
         * RSCN here.  These don't require a session.
@@ -581,13 +640,13 @@ static void fc_lport_recv(struct fc_lport *lport, struct 
fc_seq *sp,
                        recv = lport->tt.disc_recv_req;
                        break;
                case ELS_ECHO:
-                       recv = fc_lport_echo_req;
+                       recv = fc_lport_recv_echo_req;
                        break;
                case ELS_RLIR:
-                       recv = fc_lport_rlir_req;
+                       recv = fc_lport_recv_rlir_req;
                        break;
                case ELS_RNID:
-                       recv = fc_lport_rnid_req;
+                       recv = fc_lport_recv_rnid_req;
                        break;
                }
 
@@ -618,23 +677,32 @@ static void fc_lport_recv(struct fc_lport *lport, struct 
fc_seq *sp,
                FC_DBG("dropping invalid frame (eof %x)\n", fr_eof(fp));
                fc_frame_free(fp);
        }
+       mutex_unlock(&lport->lp_mutex);
+}
 
-       /*
-        *  The common exch_done for all request may not be good
-        *  if any request requires longer hold on exhange. XXX
-        */
-       lport->tt.exch_done(sp);
+int fc_lport_reset(struct fc_lport *lport)
+{
+       mutex_lock(&lport->lp_mutex);
+       fc_lport_enter_reset(lport);
+       mutex_unlock(&lport->lp_mutex);
+       return 0;
 }
+EXPORT_SYMBOL(fc_lport_reset);
 
-/*
- * Put the local port back into the initial state.  Reset all sessions.
- * This is called after a SCSI reset or the driver is unloading
- * or the program is exiting.
+/**
+ * fc_rport_enter_reset - Reset the local port
+ * @lport: Fibre Channel local port to be reset
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
-int fc_lport_enter_reset(struct fc_lport *lport)
+static void fc_lport_enter_reset(struct fc_lport *lport)
 {
        if (fc_lport_debug)
-               FC_DBG("Processing RESET state\n");
+               FC_DBG("Port (%6x) entered RESET state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
+
+       fc_lport_state_enter(lport, LPORT_ST_RESET);
 
        if (lport->dns_rp) {
                fc_remote_port_delete(lport->dns_rp);
@@ -643,23 +711,13 @@ int fc_lport_enter_reset(struct fc_lport *lport)
        fc_lport_ptp_clear(lport);
 
        lport->tt.rport_reset_list(lport);
-
-       /*
-        * Setting state RESET keeps fc_lport_error() callbacks
-        * by exch_mgr_reset() from recursing on the lock.
-        * It also causes fc_lport_sess_event() to ignore events.
-        * The lock is held for the duration of the time in RESET state.
-        */
-       fc_lport_state_enter(lport, LPORT_ST_RESET);
        lport->tt.exch_mgr_reset(lport->emp, 0, 0);
 
        lport->fid = 0;
 
        if ((lport->link_status & FC_LINK_UP) == FC_LINK_UP)
                fc_lport_enter_flogi(lport);
-       return 0;
 }
-EXPORT_SYMBOL(fc_lport_enter_reset);
 
 /**
  * fc_lport_error - Handler for any errors
@@ -691,60 +749,141 @@ static void fc_lport_error(struct fc_lport *lport, 
struct fc_frame *fp)
                fc_lport_reject(lport);
 }
 
-/*
- * Handle response from name server.
+/**
+ * fc_lport_rft_id_resp - Handle response to Register Fibre
+ *                        Channel Types by ID (RPN_ID) request
+ * @sp: current sequence in RPN_ID exchange
+ * @fp: response frame
+ * @lp_arg: Fibre Channel host port instance
  */
-static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
-                            void *lp_arg)
+static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
+                                void *lp_arg)
 {
        struct fc_lport *lport = lp_arg;
+       struct fc_frame_header *fh;
+       struct fc_ct_hdr *ct;
 
-       if (!IS_ERR(fp)) {
-               fc_lport_lock(lport);
-               cancel_delayed_work_sync(&lport->retry_work);
-               if (fc_lport_dns_acc(fp)) {
-                       if (lport->state == LPORT_ST_REG_PN)
-                               fc_lport_enter_reg_ft(lport);
-                       else
-                               fc_lport_enter_scr(lport);
+       mutex_lock(&lport->lp_mutex);
+       
+       if (fc_lport_debug)
+               FC_DBG("Received a RFT_ID response\n");
+       
+       if (lport->state != LPORT_ST_RFT_ID) {
+               FC_DBG("Received a RFT_ID response, but in state %s\n",
+                      fc_lport_state(lport));
+               goto out;
+       }
 
-               } else {
-                       fc_lport_error(lport, fp);
-               }
-               fc_lport_unlock(lport);
-               fc_frame_free(fp);
-       } else
+       if (IS_ERR(fp)) {
+               fc_lport_error(lport, fp);
+               goto out;
+       }
+
+       fh = fc_frame_header_get(fp);
+       ct = fc_frame_payload_get(fp, sizeof(*ct));
+
+       if (fh && ct && fh->fh_type == FC_TYPE_CT &&
+           ct->ct_fs_type == FC_FST_DIR &&
+           ct->ct_fs_subtype == FC_NS_SUBTYPE &&
+           ntohs(ct->ct_cmd) == FC_FS_ACC)
+               fc_lport_enter_scr(lport);
+       else
+               fc_lport_error(lport, fp);
+out:
+       mutex_unlock(&lport->lp_mutex);
+       fc_frame_free(fp);
+}
+
+/**
+ * fc_lport_rpn_id_resp - Handle response to Register Port
+ *                        Name by ID (RPN_ID) request
+ * @sp: current sequence in RPN_ID exchange
+ * @fp: response frame
+ * @lp_arg: Fibre Channel host port instance
+ */
+static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
+                                void *lp_arg)
+{
+       struct fc_lport *lport = lp_arg;
+       struct fc_frame_header *fh;
+       struct fc_ct_hdr *ct;
+
+       mutex_lock(&lport->lp_mutex);   
+       
+       if (fc_lport_debug)
+               FC_DBG("Received a RPN_ID response\n");
+       
+       if (lport->state != LPORT_ST_RPN_ID) {
+               FC_DBG("Received a RPN_ID response, but in state %s\n",
+                      fc_lport_state(lport));
+               goto out;
+       }
+
+       if (IS_ERR(fp)) {
+               fc_lport_error(lport, fp);
+               goto out;
+       }
+
+       fh = fc_frame_header_get(fp);
+       ct = fc_frame_payload_get(fp, sizeof(*ct));
+       if (fh && ct && fh->fh_type == FC_TYPE_CT &&
+           ct->ct_fs_type == FC_FST_DIR &&
+           ct->ct_fs_subtype == FC_NS_SUBTYPE &&
+           ntohs(ct->ct_cmd) == FC_FS_ACC)
+               fc_lport_enter_rft_id(lport);
+       else
                fc_lport_error(lport, fp);
+       
+out:
+       mutex_unlock(&lport->lp_mutex);
+       fc_frame_free(fp);
 }
 
 /**
  * fc_lport_scr_resp - Handle response to State Change Register (SCR) request
  * @sp: current sequence in SCR exchange
  * @fp: response frame
- * @lp_arg: Fibre Channel host port instance
+ * @lp_arg: Fibre Channel lport port instance that sent the registration 
request
  */
 static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
                              void *lp_arg)
 {
        struct fc_lport *lport = lp_arg;
-       int err;
+       u8 op;
 
-       if (IS_ERR(fp))
+       mutex_lock(&lport->lp_mutex);
+       
+       if (fc_lport_debug)
+               FC_DBG("Received a SCR response\n");
+       
+       if (lport->state != LPORT_ST_SCR) {
+               FC_DBG("Received a SCR response, but in state %s\n",
+                      fc_lport_state(lport));
+               goto out;
+       }
+
+       if (IS_ERR(fp)) {
                fc_lport_error(lport, fp);
-       else {
-               fc_lport_lock(lport);
-               fc_lport_enter_ready(lport);
-               fc_lport_unlock(lport);
-               err = lport->tt.disc_start(lport);
-               if (err)
-                       FC_DBG("target discovery start error\n");
-               fc_frame_free(fp);
+               goto out;
        }
+
+       op = fc_frame_payload_op(fp);
+       if (op == ELS_LS_ACC)
+               fc_lport_enter_ready(lport);
+       else
+               fc_lport_error(lport, fp);
+       
+out:
+       mutex_unlock(&lport->lp_mutex);
+       fc_frame_free(fp);
 }
 
 /**
- * fc_lport_enter scr - Send a State Change Register (SCR) request
- * @lp: Fibre Channel host port instance
+ * fc_lport_enter_scr - Send a State Change Register (SCR) request
+ * @lport: Fibre Channel local port to register for state changes
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
 static void fc_lport_enter_scr(struct fc_lport *lport)
 {
@@ -752,32 +891,40 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
        struct fc_els_scr *scr;
 
        if (fc_lport_debug)
-               FC_DBG("Processing SCR state\n");
+               FC_DBG("Port (%6x) entered SCR state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
 
        fc_lport_state_enter(lport, LPORT_ST_SCR);
 
        fp = fc_frame_alloc(lport, sizeof(*scr));
-       if (fp) {
-               scr = fc_frame_payload_get(fp, sizeof(*scr));
-               memset(scr, 0, sizeof(*scr));
-               scr->scr_cmd = ELS_SCR;
-               scr->scr_reg_func = ELS_SCRF_FULL;
+       if (!fp) {
+               fc_lport_error(lport, fp);
+               return;
        }
+
+       scr = fc_frame_payload_get(fp, sizeof(*scr));
+       memset(scr, 0, sizeof(*scr));
+       scr->scr_cmd = ELS_SCR;
+       scr->scr_reg_func = ELS_SCRF_FULL;
        fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
        fc_frame_set_offset(fp, 0);
 
-       lport->tt.exch_seq_send(lport, fp,
-                               fc_lport_scr_resp,
-                               lport, lport->e_d_tov,
-                               lport->fid, FC_FID_FCTRL,
-                               FC_FC_SEQ_INIT | FC_FC_END_SEQ);
+       if (!lport->tt.exch_seq_send(lport, fp,
+                                    fc_lport_scr_resp,
+                                    lport, lport->e_d_tov,
+                                    lport->fid, FC_FID_FCTRL,
+                                    FC_FC_SEQ_INIT | FC_FC_END_SEQ))
+               fc_lport_error(lport, fp);
 }
 
 /**
- * fc_lport_enter_reg_ft - Register FC4-types with the name server
- * @lp: Fibre Channel host port instance
+ * fc_lport_enter_rft_id - Register FC4-types with the name server
+ * @lport: Fibre Channel local port to register
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
-static void fc_lport_enter_reg_ft(struct fc_lport *lport)
+static void fc_lport_enter_rft_id(struct fc_lport *lport)
 {
        struct fc_frame *fp;
        struct req {
@@ -789,47 +936,54 @@ static void fc_lport_enter_reg_ft(struct fc_lport *lport)
        int i;
 
        if (fc_lport_debug)
-               FC_DBG("Processing REG_FT state\n");
+               FC_DBG("Port (%6x) entered RFT_ID state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
 
-       fc_lport_state_enter(lport, LPORT_ST_REG_FT);
+       fc_lport_state_enter(lport, LPORT_ST_RFT_ID);
 
        lps = &lport->fcts;
        i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]);
        while (--i >= 0)
                if (ntohl(lps->ff_type_map[i]) != 0)
                        break;
-       if (i >= 0) {
+       if (i < 0) {
+               /* nothing to register, move on to SCR */
+               fc_lport_enter_scr(lport);
+       } else {
                fp = fc_frame_alloc(lport, sizeof(*req));
-               if (fp) {
-                       req = fc_frame_payload_get(fp, sizeof(*req));
-                       fc_fill_dns_hdr(lport, &req->ct,
-                                       FC_NS_RFT_ID,
-                                       sizeof(*req) -
-                                       sizeof(struct fc_ct_hdr));
-                       hton24(req->fid.fp_fid, lport->fid);
-                       req->fts = *lps;
-                       fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
-
-                       if (!lport->tt.exch_seq_send(lport, fp,
-                                                    fc_lport_ns_resp, lport,
-                                                    lport->e_d_tov,
-                                                    lport->fid,
-                                                    FC_FID_DIR_SERV,
-                                                    FC_FC_SEQ_INIT |
-                                                    FC_FC_END_SEQ))
-                               fc_lport_error(lport, fp);
-               } else {
+               if (!fp) {
                        fc_lport_error(lport, fp);
+                       return;
                }
-       } else {
-               fc_lport_enter_scr(lport);
+
+               req = fc_frame_payload_get(fp, sizeof(*req));
+               fc_fill_dns_hdr(lport, &req->ct,
+                               FC_NS_RFT_ID,
+                               sizeof(*req) -
+                               sizeof(struct fc_ct_hdr));
+               hton24(req->fid.fp_fid, lport->fid);
+               req->fts = *lps;
+               fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
+               
+               if (!lport->tt.exch_seq_send(lport, fp,
+                                            fc_lport_rft_id_resp,
+                                            lport, lport->e_d_tov,
+                                            lport->fid,
+                                            FC_FID_DIR_SERV,
+                                            FC_FC_SEQ_INIT |
+                                            FC_FC_END_SEQ))
+                       fc_lport_error(lport, fp);
        }
 }
 
-/*
- * Register port name with name server.
+/**
+ * fc_rport_enter_rft_id - Register port name with the name server
+ * @lport: Fibre Channel local port to register
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
-static void fc_lport_enter_reg_pn(struct fc_lport *lport)
+static void fc_lport_enter_rpn_id(struct fc_lport *lport)
 {
        struct fc_frame *fp;
        struct req {
@@ -838,22 +992,26 @@ static void fc_lport_enter_reg_pn(struct fc_lport *lport)
        } *req;
 
        if (fc_lport_debug)
-               FC_DBG("Processing REG_PN state\n");
+               FC_DBG("Port (%6x) entered RPN_ID state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
+
+       fc_lport_state_enter(lport, LPORT_ST_RPN_ID);
 
-       fc_lport_state_enter(lport, LPORT_ST_REG_PN);
        fp = fc_frame_alloc(lport, sizeof(*req));
        if (!fp) {
                fc_lport_error(lport, fp);
                return;
        }
+
        req = fc_frame_payload_get(fp, sizeof(*req));
        memset(req, 0, sizeof(*req));
        fc_fill_dns_hdr(lport, &req->ct, FC_NS_RPN_ID, sizeof(req->rn));
        hton24(req->rn.fr_fid.fp_fid, lport->fid);
        put_unaligned_be64(lport->wwpn, &req->rn.fr_wwn);
        fc_frame_setup(fp, FC_RCTL_DD_UNSOL_CTL, FC_TYPE_CT);
+
        if (!lport->tt.exch_seq_send(lport, fp,
-                                    fc_lport_ns_resp, lport,
+                                    fc_lport_rpn_id_resp, lport,
                                     lport->e_d_tov,
                                     lport->fid,
                                     FC_FID_DIR_SERV,
@@ -861,8 +1019,12 @@ static void fc_lport_enter_reg_pn(struct fc_lport *lport)
                fc_lport_error(lport, fp);
 }
 
-/*
- * Setup session to dNS if not already set up.
+/**
+ * fc_rport_enter_dns - Create a rport to the name server
+ * @lport: Fibre Channel local port requesting a rport for the name server
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
 static void fc_lport_enter_dns(struct fc_lport *lport)
 {
@@ -876,15 +1038,15 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
        dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
 
        if (fc_lport_debug)
-               FC_DBG("Processing DNS state\n");
+               FC_DBG("Port (%6x) entered DNS state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
 
        fc_lport_state_enter(lport, LPORT_ST_DNS);
 
        if (!lport->dns_rp) {
                /* Set up a dummy rport to directory server */
-               fc_lport_unlock(lport);
                rport = fc_rport_dummy_create(&dp);
-               fc_lport_lock(lport);
+
                if (!rport)
                        goto err;
                lport->dns_rp = rport;
@@ -894,16 +1056,8 @@ static void fc_lport_enter_dns(struct fc_lport *lport)
        rdata = rport->dd_data;
        rdata->local_port = lport;
 
-       /*
-        * If dNS session isn't ready, start its logon.
-        */
-       if (rdata->rp_state != RPORT_ST_READY) {
-               rdata->event_callback = fc_lport_rport_event;
-               lport->tt.rport_login(rport);
-       } else {
-               cancel_delayed_work_sync(&lport->retry_work);
-               fc_lport_enter_reg_pn(lport);
-       }
+       rdata->event_callback = fc_lport_rport_event;
+       lport->tt.rport_login(rport);
        return;
 
 err:
@@ -920,7 +1074,7 @@ static void fc_lport_timeout(struct work_struct *work)
                container_of(work, struct fc_lport,
                             retry_work.work);
        
-       fc_lport_lock(lport);
+       mutex_lock(&lport->lp_mutex);
 
        switch (lport->state) {
        case LPORT_ST_NONE:
@@ -934,11 +1088,11 @@ static void fc_lport_timeout(struct work_struct *work)
        case LPORT_ST_DNS:
                fc_lport_enter_dns(lport);
                break;
-       case LPORT_ST_REG_PN:
-               fc_lport_enter_reg_pn(lport);
+       case LPORT_ST_RPN_ID:
+               fc_lport_enter_rpn_id(lport);
                break;
-       case LPORT_ST_REG_FT:
-               fc_lport_enter_reg_ft(lport);
+       case LPORT_ST_RFT_ID:
+               fc_lport_enter_rft_id(lport);
                break;
        case LPORT_ST_SCR:
                fc_lport_enter_scr(lport);
@@ -947,33 +1101,63 @@ static void fc_lport_timeout(struct work_struct *work)
                fc_lport_enter_logo(lport);
                break;
        }
-       
-       fc_lport_unlock(lport);
+       mutex_unlock(&lport->lp_mutex);
 }
 
+/**
+ * fc_lport_logo_resp - Handle response to LOGO request
+ * @sp: current sequence in LOGO exchange
+ * @fp: response frame
+ * @lp_arg: Fibre Channel lport port instance that sent the LOGO request
+ */
 static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
                               void *lp_arg)
 {
        struct fc_lport *lport = lp_arg;
+       u8 op;
+
+       mutex_lock(&lport->lp_mutex);
+       
+       if (fc_lport_debug)
+               FC_DBG("Received a LOGO response\n");
+       
+       if (lport->state != LPORT_ST_LOGO) {
+               FC_DBG("Received a LOGO response, but in state %s\n",
+                      fc_lport_state(lport));
+               goto out;
+       }
 
-       if (IS_ERR(fp))
+       if (IS_ERR(fp)) {
                fc_lport_error(lport, fp);
-       else {
-               fc_frame_free(fp);
-               fc_lport_lock(lport);
-               fc_lport_enter_reset(lport);
-               fc_lport_unlock(lport);
+               goto out;
        }
+
+       op = fc_frame_payload_op(fp);
+       if (op == ELS_LS_ACC)
+               fc_lport_enter_reset(lport);
+       else
+               fc_lport_error(lport, fp);
+       
+out:
+       mutex_unlock(&lport->lp_mutex);
+       fc_frame_free(fp);
 }
 
-/* Logout of the FC fabric */
+/**
+ * fc_rport_enter_logo - Logout of the fabric
+ * @lport: Fibre Channel local port to be logged out
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
 static void fc_lport_enter_logo(struct fc_lport *lport)
 {
        struct fc_frame *fp;
        struct fc_els_logo *logo;
-
+       
        if (fc_lport_debug)
-               FC_DBG("Processing LOGO state\n");
+               FC_DBG("Port (%6x) entered LOGO state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
 
        fc_lport_state_enter(lport, LPORT_ST_LOGO);
 
@@ -985,7 +1169,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
 
        fp = fc_frame_alloc(lport, sizeof(*logo));
        if (!fp) {
-               FC_DBG("failed to allocate frame\n");
+               fc_lport_error(lport, fp);
                return;
        }
 
@@ -994,20 +1178,22 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
        logo->fl_cmd = ELS_LOGO;
        hton24(logo->fl_n_port_id, lport->fid);
        logo->fl_n_port_wwn = htonll(lport->wwpn);
-
        fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
        fc_frame_set_offset(fp, 0);
 
-       lport->tt.exch_seq_send(lport, fp,
-                               fc_lport_logo_resp,
-                               lport, lport->e_d_tov,
-                               lport->fid, FC_FID_FLOGI,
-                               FC_FC_SEQ_INIT | FC_FC_END_SEQ);
+       if (!lport->tt.exch_seq_send(lport, fp,
+                                    fc_lport_logo_resp,
+                                    lport, lport->e_d_tov,
+                                    lport->fid, FC_FID_FLOGI,
+                                    FC_FC_SEQ_INIT | FC_FC_END_SEQ))
+               fc_lport_error(lport, fp);
 }
 
-/*
- * Handle incoming ELS FLOGI response.
- * Save parameters of remote switch.  Finish exchange.
+/**
+ * fc_lport_flogi_resp - Handle response to FLOGI request
+ * @sp: current sequence in FLOGI exchange
+ * @fp: response frame
+ * @lp_arg: Fibre Channel lport port instance that sent the FLOGI request
  */
 static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, void 
*lp_arg)
 {
@@ -1020,17 +1206,28 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, 
struct fc_frame *fp, void *lp
        unsigned int e_d_tov;
        u16 mfs;
 
+       mutex_lock(&lport->lp_mutex);
+       
+       if (fc_lport_debug)
+               FC_DBG("Received a FLOGI response\n");
+       
+       if (lport->state != LPORT_ST_FLOGI) {
+               FC_DBG("Received a FLOGI response, but in state %s\n",
+                      fc_lport_state(lport));
+               goto out;
+       }
+       
        if (IS_ERR(fp)) {
                fc_lport_error(lport, fp);
-               return;
+               goto out;
        }
-
+       
        fh = fc_frame_header_get(fp);
        did = ntoh24(fh->fh_d_id);
        if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {
                if (fc_lport_debug)
-                       FC_DBG("assigned fid %x\n", did);
-               fc_lport_lock(lport);
+                       FC_DBG("Assigned fid %x\n", did);
+
                lport->fid = did;
                flp = fc_frame_payload_get(fp, sizeof(*flp));
                if (flp) {
@@ -1048,7 +1245,7 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct 
fc_frame *fp, void *lp
                                if (e_d_tov > lport->e_d_tov)
                                        lport->e_d_tov = e_d_tov;
                                lport->r_a_tov = 2 * e_d_tov;
-                               FC_DBG("point-to-point mode\n");
+                               FC_DBG("Point-to-Point mode\n");
                                fc_lport_ptp_setup(lport, ntoh24(fh->fh_s_id),
                                                   get_unaligned_be64(
                                                           &flp->fl_wwpn),
@@ -1060,22 +1257,29 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, 
struct fc_frame *fp, void *lp
                                fc_lport_enter_dns(lport);
                        }
                }
-               fc_lport_unlock(lport);
+
                if (flp) {
                        csp_flags = ntohs(flp->fl_csp.sp_features);
                        if ((csp_flags & FC_SP_FT_FPORT) == 0) {
                                if (lport->tt.disc_start(lport))
-                                       FC_DBG("target disc start error\n");
+                                       FC_DBG("Target disc start error\n");
                        }
                }
        } else {
                FC_DBG("bad FLOGI response\n");
        }
+
+out:
+       mutex_unlock(&lport->lp_mutex);
        fc_frame_free(fp);
 }
 
-/*
- * Send ELS (extended link service) FLOGI request to peer.
+/**
+ * fc_rport_enter_flogi - Send a FLOGI request to the fabric manager
+ * @lport: Fibre Channel local port to be logged in to the fabric
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
  */
 void fc_lport_enter_flogi(struct fc_lport *lport)
 {
@@ -1083,17 +1287,19 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
        struct fc_els_flogi *flp;
 
        if (fc_lport_debug)
-               FC_DBG("Processing FLOGI state\n");
+               FC_DBG("Port (%6x) entered FLOGI state from %s state\n",
+                      lport->fid, fc_lport_state(lport));
 
        fc_lport_state_enter(lport, LPORT_ST_FLOGI);
 
        fp = fc_frame_alloc(lport, sizeof(*flp));
-       if (!fp)
-               return fc_lport_error(lport, fp);
+       if (!fp) {
+               fc_lport_error(lport, fp);
+               return;
+       }
 
        flp = fc_frame_payload_get(fp, sizeof(*flp));
        fc_lport_flogi_fill(lport, flp, ELS_FLOGI);
-
        fc_frame_setup(fp, FC_RCTL_ELS_REQ, FC_TYPE_ELS);
        fc_frame_set_offset(fp, 0);
 
@@ -1109,11 +1315,9 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
 int fc_lport_config(struct fc_lport *lport)
 {
        INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
-       spin_lock_init(&lport->state_lock);
+       mutex_init(&lport->lp_mutex);
 
-       fc_lport_lock(lport);
        fc_lport_state_enter(lport, LPORT_ST_NONE);
-       fc_lport_unlock(lport);
 
        lport->ns_disc_delay = DNS_DELAY;
 
@@ -1127,10 +1331,10 @@ EXPORT_SYMBOL(fc_lport_config);
 int fc_lport_init(struct fc_lport *lport)
 {
        if (!lport->tt.lport_recv)
-               lport->tt.lport_recv = fc_lport_recv;
+               lport->tt.lport_recv = fc_lport_recv_req;
 
        if (!lport->tt.lport_reset)
-               lport->tt.lport_reset = fc_lport_enter_reset;
+               lport->tt.lport_reset = fc_lport_reset;
 
        if (!lport->tt.event_callback)
                lport->tt.event_callback = fc_lport_rport_event;
diff --git a/drivers/scsi/libfc/fc_ns.c b/drivers/scsi/libfc/fc_ns.c
index 844c2f2..dec0e69 100644
--- a/drivers/scsi/libfc/fc_ns.c
+++ b/drivers/scsi/libfc/fc_ns.c
@@ -154,13 +154,11 @@ static void fc_ns_recv_req(struct fc_seq *sp, struct 
fc_frame *fp,
  */
 static int fc_ns_restart(struct fc_lport *lp)
 {
-       fc_lport_lock(lp);
        if (!lp->ns_disc_requested && !lp->ns_disc_pending) {
                schedule_delayed_work(&lp->ns_disc_work,
                                msecs_to_jiffies(lp->ns_disc_delay * 1000));
        }
        lp->ns_disc_requested = 1;
-       fc_lport_unlock(lp);
        return 0;
 }
 
@@ -225,14 +223,12 @@ int fc_ns_disc_start(struct fc_lport *lp)
        int error;
        struct fc_rport_identifiers ids;
 
-       fc_lport_lock(lp);
-
        /*
         * If not ready, or already running discovery, just set request flag.
         */
        if (!fc_lport_test_ready(lp) || lp->ns_disc_pending) {
                lp->ns_disc_requested = 1;
-               fc_lport_unlock(lp);
+
                return 0;
        }
        lp->ns_disc_pending = 1;
@@ -250,13 +246,13 @@ int fc_ns_disc_start(struct fc_lport *lp)
                ids.node_name = rport->node_name;
                ids.roles = FC_RPORT_ROLE_UNKNOWN;
                get_device(&rport->dev);
-               fc_lport_unlock(lp);
+
                error = fc_ns_new_target(lp, rport, &ids);
                put_device(&rport->dev);
                if (!error)
                        fc_ns_disc_done(lp);
        } else {
-               fc_lport_unlock(lp);
+
                fc_block_rports(lp);
                fc_ns_gpn_ft_req(lp);   /* get ports by FC-4 type */
                error = 0;
diff --git a/include/scsi/libfc/libfc.h b/include/scsi/libfc/libfc.h
index e287144..07a1220 100644
--- a/include/scsi/libfc/libfc.h
+++ b/include/scsi/libfc/libfc.h
@@ -92,8 +92,8 @@ enum fc_lport_state {
        LPORT_ST_NONE = 0,
        LPORT_ST_FLOGI,
        LPORT_ST_DNS,
-       LPORT_ST_REG_PN,
-       LPORT_ST_REG_FT,
+       LPORT_ST_RPN_ID,
+       LPORT_ST_RFT_ID,
        LPORT_ST_SCR,
        LPORT_ST_READY,
        LPORT_ST_LOGO,
@@ -451,8 +451,8 @@ struct fc_lport {
        struct fc_ns_fts        fcts;           /* FC-4 type masks */
        struct fc_els_rnid_gen  rnid_gen;       /* RNID information */
 
-       /* Locks */
-       spinlock_t              state_lock;     /* serializes state changes */
+       /* Semaphores */
+       struct mutex lp_mutex;
 
        /* Miscellaneous */
        struct fc_gpn_ft_resp   ns_disc_buf;    /* partial name buffer */
@@ -486,15 +486,6 @@ static inline void fc_set_wwpn(struct fc_lport *lp, u64 
wwnn)
        lp->wwpn = wwnn;
 }
 
-static inline int fc_lport_locked(struct fc_lport *lp)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-       return spin_is_locked(&lp->state_lock);
-#else
-       return 1;
-#endif /* CONFIG_SMP || CONFIG_DEBUG_SPINLOCK */
-}
-
 /**
  * fc_fill_dns_hdr - Fill in a name service request header
  * @lp: Fibre Channel host port instance
@@ -512,23 +503,9 @@ static inline void fc_fill_dns_hdr(struct fc_lport *lp, 
struct fc_ct_hdr *ct,
        ct->ct_cmd = htons((u16) op);
 }
 
-/*
- * Locking code.
- */
-static inline void fc_lport_lock(struct fc_lport *lp)
-{
-       spin_lock_bh(&lp->state_lock);
-}
-
-static inline void fc_lport_unlock(struct fc_lport *lp)
-{
-       spin_unlock_bh(&lp->state_lock);
-}
-
 static inline void fc_lport_state_enter(struct fc_lport *lp,
                                        enum fc_lport_state state)
 {
-       WARN_ON(!fc_lport_locked(lp));
        if (state != lp->state)
                lp->retry_count = 0;
        lp->state = state;
@@ -583,7 +560,7 @@ int fc_lport_config(struct fc_lport *);
 /*
  * Reset the local port.
  */
-int fc_lport_enter_reset(struct fc_lport *);
+int fc_lport_reset(struct fc_lport *);
 
 /*
  * Set the mfs or reset

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to