linux/drivers/scsi/libfc/fc_lport.c
<<
>>
Prefs
   1/*
   2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License along with
  14 * this program; if not, write to the Free Software Foundation, Inc.,
  15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  16 *
  17 * Maintained at www.Open-FCoE.org
  18 */
  19
  20/*
  21 * PORT LOCKING NOTES
  22 *
  23 * These comments only apply to the 'port code' which consists of the lport,
  24 * disc and rport blocks.
  25 *
  26 * MOTIVATION
  27 *
  28 * The lport, disc and rport blocks all have mutexes that are used to protect
  29 * those objects. The main motivation for these locks is to prevent from
  30 * having an lport reset just before we send a frame. In that scenario the
  31 * lport's FID would get set to zero and then we'd send a frame with an
  32 * invalid SID. We also need to ensure that states don't change unexpectedly
  33 * while processing another state.
  34 *
  35 * HIERARCHY
  36 *
  37 * The following hierarchy defines the locking rules. A greater lock
  38 * may be held before acquiring a lesser lock, but a lesser lock should never
  39 * be held while attempting to acquire a greater lock. Here is the hierarchy-
  40 *
  41 * lport > disc, lport > rport, disc > rport
  42 *
  43 * CALLBACKS
  44 *
  45 * The callbacks cause complications with this scheme. There is a callback
  46 * from the rport (to either lport or disc) and a callback from disc
  47 * (to the lport).
  48 *
  49 * As rports exit the rport state machine a callback is made to the owner of
  50 * the rport to notify success or failure. Since the callback is likely to
  51 * cause the lport or disc to grab its lock we cannot hold the rport lock
  52 * while making the callback. To ensure that the rport is not free'd while
  53 * processing the callback the rport callbacks are serialized through a
  54 * single-threaded workqueue. An rport would never be free'd while in a
  55 * callback handler because no other rport work in this queue can be executed
  56 * at the same time.
  57 *
  58 * When discovery succeeds or fails a callback is made to the lport as
  59 * notification. Currently, successful discovery causes the lport to take no
  60 * action. A failure will cause the lport to reset. There is likely a circular
  61 * locking problem with this implementation.
  62 */
  63
  64/*
  65 * LPORT LOCKING
  66 *
  67 * The critical sections protected by the lport's mutex are quite broad and
  68 * may be improved upon in the future. The lport code and its locking doesn't
  69 * influence the I/O path, so excessive locking doesn't penalize I/O
  70 * performance.
  71 *
  72 * The strategy is to lock whenever processing a request or response. Note
  73 * that every _enter_* function corresponds to a state change. They generally
  74 * change the lports state and then send a request out on the wire. We lock
  75 * before calling any of these functions to protect that state change. This
  76 * means that the entry points into the lport block manage the locks while
  77 * the state machine can transition between states (i.e. _enter_* functions)
  78 * while always staying protected.
  79 *
  80 * When handling responses we also hold the lport mutex broadly. When the
  81 * lport receives the response frame it locks the mutex and then calls the
  82 * appropriate handler for the particuar response. Generally a response will
  83 * trigger a state change and so the lock must already be held.
  84 *
  85 * Retries also have to consider the locking. The retries occur from a work
  86 * context and the work function will lock the lport and then retry the state
  87 * (i.e. _enter_* function).
  88 */
  89
  90#include <linux/timer.h>
  91#include <linux/delay.h>
  92#include <linux/module.h>
  93#include <linux/slab.h>
  94#include <asm/unaligned.h>
  95
  96#include <scsi/fc/fc_gs.h>
  97
  98#include <scsi/libfc.h>
  99#include <scsi/fc_encode.h>
 100#include <linux/scatterlist.h>
 101
 102#include "fc_libfc.h"
 103
 104/* Fabric IDs to use for point-to-point mode, chosen on whims. */
 105#define FC_LOCAL_PTP_FID_LO   0x010101
 106#define FC_LOCAL_PTP_FID_HI   0x010102
 107
 108#define DNS_DELAY             3 /* Discovery delay after RSCN (in seconds)*/
 109
 110static void fc_lport_error(struct fc_lport *, struct fc_frame *);
 111
 112static void fc_lport_enter_reset(struct fc_lport *);
 113static void fc_lport_enter_flogi(struct fc_lport *);
 114static void fc_lport_enter_dns(struct fc_lport *);
 115static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
 116static void fc_lport_enter_scr(struct fc_lport *);
 117static void fc_lport_enter_ready(struct fc_lport *);
 118static void fc_lport_enter_logo(struct fc_lport *);
 119static void fc_lport_enter_fdmi(struct fc_lport *lport);
 120static void fc_lport_enter_ms(struct fc_lport *, enum fc_lport_state);
 121
 122static const char *fc_lport_state_names[] = {
 123        [LPORT_ST_DISABLED] = "disabled",
 124        [LPORT_ST_FLOGI] =    "FLOGI",
 125        [LPORT_ST_DNS] =      "dNS",
 126        [LPORT_ST_RNN_ID] =   "RNN_ID",
 127        [LPORT_ST_RSNN_NN] =  "RSNN_NN",
 128        [LPORT_ST_RSPN_ID] =  "RSPN_ID",
 129        [LPORT_ST_RFT_ID] =   "RFT_ID",
 130        [LPORT_ST_RFF_ID] =   "RFF_ID",
 131        [LPORT_ST_FDMI] =     "FDMI",
 132        [LPORT_ST_RHBA] =     "RHBA",
 133        [LPORT_ST_RPA] =      "RPA",
 134        [LPORT_ST_DHBA] =     "DHBA",
 135        [LPORT_ST_DPRT] =     "DPRT",
 136        [LPORT_ST_SCR] =      "SCR",
 137        [LPORT_ST_READY] =    "Ready",
 138        [LPORT_ST_LOGO] =     "LOGO",
 139        [LPORT_ST_RESET] =    "reset",
 140};
 141
 142/**
 143 * struct fc_bsg_info - FC Passthrough managemet structure
 144 * @job:      The passthrough job
 145 * @lport:    The local port to pass through a command
 146 * @rsp_code: The expected response code
 147 * @sg:       job->reply_payload.sg_list
 148 * @nents:    job->reply_payload.sg_cnt
 149 * @offset:   The offset into the response data
 150 */
 151struct fc_bsg_info {
 152        struct bsg_job *job;
 153        struct fc_lport *lport;
 154        u16 rsp_code;
 155        struct scatterlist *sg;
 156        u32 nents;
 157        size_t offset;
 158};
 159
 160/**
 161 * fc_frame_drop() - Dummy frame handler
 162 * @lport: The local port the frame was received on
 163 * @fp:    The received frame
 164 */
 165static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
 166{
 167        fc_frame_free(fp);
 168        return 0;
 169}
 170
 171/**
 172 * fc_lport_rport_callback() - Event handler for rport events
 173 * @lport: The lport which is receiving the event
 174 * @rdata: private remote port data
 175 * @event: The event that occurred
 176 *
 177 * Locking Note: The rport lock should not be held when calling
 178 *               this function.
 179 */
 180static void fc_lport_rport_callback(struct fc_lport *lport,
 181                                    struct fc_rport_priv *rdata,
 182                                    enum fc_rport_event event)
 183{
 184        FC_LPORT_DBG(lport, "Received a %d event for port (%6.6x)\n", event,
 185                     rdata->ids.port_id);
 186
 187        mutex_lock(&lport->lp_mutex);
 188        switch (event) {
 189        case RPORT_EV_READY:
 190                if (lport->state == LPORT_ST_DNS) {
 191                        lport->dns_rdata = rdata;
 192                        fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
 193                } else if (lport->state == LPORT_ST_FDMI) {
 194                        lport->ms_rdata = rdata;
 195                        fc_lport_enter_ms(lport, LPORT_ST_DHBA);
 196                } else {
 197                        FC_LPORT_DBG(lport, "Received an READY event "
 198                                     "on port (%6.6x) for the directory "
 199                                     "server, but the lport is not "
 200                                     "in the DNS or FDMI state, it's in the "
 201                                     "%d state", rdata->ids.port_id,
 202                                     lport->state);
 203                        fc_rport_logoff(rdata);
 204                }
 205                break;
 206        case RPORT_EV_LOGO:
 207        case RPORT_EV_FAILED:
 208        case RPORT_EV_STOP:
 209                if (rdata->ids.port_id == FC_FID_DIR_SERV)
 210                        lport->dns_rdata = NULL;
 211                else if (rdata->ids.port_id == FC_FID_MGMT_SERV)
 212                        lport->ms_rdata = NULL;
 213                break;
 214        case RPORT_EV_NONE:
 215                break;
 216        }
 217        mutex_unlock(&lport->lp_mutex);
 218}
 219
 220/**
 221 * fc_lport_state() - Return a string which represents the lport's state
 222 * @lport: The lport whose state is to converted to a string
 223 */
 224static const char *fc_lport_state(struct fc_lport *lport)
 225{
 226        const char *cp;
 227
 228        cp = fc_lport_state_names[lport->state];
 229        if (!cp)
 230                cp = "unknown";
 231        return cp;
 232}
 233
 234/**
 235 * fc_lport_ptp_setup() - Create an rport for point-to-point mode
 236 * @lport:       The lport to attach the ptp rport to
 237 * @remote_fid:  The FID of the ptp rport
 238 * @remote_wwpn: The WWPN of the ptp rport
 239 * @remote_wwnn: The WWNN of the ptp rport
 240 */
 241static void fc_lport_ptp_setup(struct fc_lport *lport,
 242                               u32 remote_fid, u64 remote_wwpn,
 243                               u64 remote_wwnn)
 244{
 245        lockdep_assert_held(&lport->lp_mutex);
 246
 247        if (lport->ptp_rdata) {
 248                fc_rport_logoff(lport->ptp_rdata);
 249                kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
 250        }
 251        mutex_lock(&lport->disc.disc_mutex);
 252        lport->ptp_rdata = fc_rport_create(lport, remote_fid);
 253        kref_get(&lport->ptp_rdata->kref);
 254        lport->ptp_rdata->ids.port_name = remote_wwpn;
 255        lport->ptp_rdata->ids.node_name = remote_wwnn;
 256        mutex_unlock(&lport->disc.disc_mutex);
 257
 258        fc_rport_login(lport->ptp_rdata);
 259
 260        fc_lport_enter_ready(lport);
 261}
 262
 263/**
 264 * fc_get_host_port_state() - Return the port state of the given Scsi_Host
 265 * @shost:  The SCSI host whose port state is to be determined
 266 */
 267void fc_get_host_port_state(struct Scsi_Host *shost)
 268{
 269        struct fc_lport *lport = shost_priv(shost);
 270
 271        mutex_lock(&lport->lp_mutex);
 272        if (!lport->link_up)
 273                fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
 274        else
 275                switch (lport->state) {
 276                case LPORT_ST_READY:
 277                        fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
 278                        break;
 279                default:
 280                        fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
 281                }
 282        mutex_unlock(&lport->lp_mutex);
 283}
 284EXPORT_SYMBOL(fc_get_host_port_state);
 285
 286/**
 287 * fc_get_host_speed() - Return the speed of the given Scsi_Host
 288 * @shost: The SCSI host whose port speed is to be determined
 289 */
 290void fc_get_host_speed(struct Scsi_Host *shost)
 291{
 292        struct fc_lport *lport = shost_priv(shost);
 293
 294        fc_host_speed(shost) = lport->link_speed;
 295}
 296EXPORT_SYMBOL(fc_get_host_speed);
 297
 298/**
 299 * fc_get_host_stats() - Return the Scsi_Host's statistics
 300 * @shost: The SCSI host whose statistics are to be returned
 301 */
 302struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
 303{
 304        struct fc_host_statistics *fc_stats;
 305        struct fc_lport *lport = shost_priv(shost);
 306        unsigned int cpu;
 307        u64 fcp_in_bytes = 0;
 308        u64 fcp_out_bytes = 0;
 309
 310        fc_stats = &lport->host_stats;
 311        memset(fc_stats, 0, sizeof(struct fc_host_statistics));
 312
 313        fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
 314
 315        for_each_possible_cpu(cpu) {
 316                struct fc_stats *stats;
 317
 318                stats = per_cpu_ptr(lport->stats, cpu);
 319
 320                fc_stats->tx_frames += stats->TxFrames;
 321                fc_stats->tx_words += stats->TxWords;
 322                fc_stats->rx_frames += stats->RxFrames;
 323                fc_stats->rx_words += stats->RxWords;
 324                fc_stats->error_frames += stats->ErrorFrames;
 325                fc_stats->invalid_crc_count += stats->InvalidCRCCount;
 326                fc_stats->fcp_input_requests += stats->InputRequests;
 327                fc_stats->fcp_output_requests += stats->OutputRequests;
 328                fc_stats->fcp_control_requests += stats->ControlRequests;
 329                fcp_in_bytes += stats->InputBytes;
 330                fcp_out_bytes += stats->OutputBytes;
 331                fc_stats->fcp_packet_alloc_failures += stats->FcpPktAllocFails;
 332                fc_stats->fcp_packet_aborts += stats->FcpPktAborts;
 333                fc_stats->fcp_frame_alloc_failures += stats->FcpFrameAllocFails;
 334                fc_stats->link_failure_count += stats->LinkFailureCount;
 335        }
 336        fc_stats->fcp_input_megabytes = div_u64(fcp_in_bytes, 1000000);
 337        fc_stats->fcp_output_megabytes = div_u64(fcp_out_bytes, 1000000);
 338        fc_stats->lip_count = -1;
 339        fc_stats->nos_count = -1;
 340        fc_stats->loss_of_sync_count = -1;
 341        fc_stats->loss_of_signal_count = -1;
 342        fc_stats->prim_seq_protocol_err_count = -1;
 343        fc_stats->dumped_frames = -1;
 344
 345        /* update exches stats */
 346        fc_exch_update_stats(lport);
 347
 348        return fc_stats;
 349}
 350EXPORT_SYMBOL(fc_get_host_stats);
 351
 352/**
 353 * fc_lport_flogi_fill() - Fill in FLOGI command for request
 354 * @lport: The local port the FLOGI is for
 355 * @flogi: The FLOGI command
 356 * @op:    The opcode
 357 */
 358static void fc_lport_flogi_fill(struct fc_lport *lport,
 359                                struct fc_els_flogi *flogi,
 360                                unsigned int op)
 361{
 362        struct fc_els_csp *sp;
 363        struct fc_els_cssp *cp;
 364
 365        memset(flogi, 0, sizeof(*flogi));
 366        flogi->fl_cmd = (u8) op;
 367        put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn);
 368        put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn);
 369        sp = &flogi->fl_csp;
 370        sp->sp_hi_ver = 0x20;
 371        sp->sp_lo_ver = 0x20;
 372        sp->sp_bb_cred = htons(10);     /* this gets set by gateway */
 373        sp->sp_bb_data = htons((u16) lport->mfs);
 374        cp = &flogi->fl_cssp[3 - 1];    /* class 3 parameters */
 375        cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ);
 376        if (op != ELS_FLOGI) {
 377                sp->sp_features = htons(FC_SP_FT_CIRO);
 378                sp->sp_tot_seq = htons(255);    /* seq. we accept */
 379                sp->sp_rel_off = htons(0x1f);
 380                sp->sp_e_d_tov = htonl(lport->e_d_tov);
 381
 382                cp->cp_rdfs = htons((u16) lport->mfs);
 383                cp->cp_con_seq = htons(255);
 384                cp->cp_open_seq = 1;
 385        }
 386}
 387
 388/**
 389 * fc_lport_add_fc4_type() - Add a supported FC-4 type to a local port
 390 * @lport: The local port to add a new FC-4 type to
 391 * @type:  The new FC-4 type
 392 */
 393static void fc_lport_add_fc4_type(struct fc_lport *lport, enum fc_fh_type type)
 394{
 395        __be32 *mp;
 396
 397        mp = &lport->fcts.ff_type_map[type / FC_NS_BPW];
 398        *mp = htonl(ntohl(*mp) | 1UL << (type % FC_NS_BPW));
 399}
 400
 401/**
 402 * fc_lport_recv_rlir_req() - Handle received Registered Link Incident Report.
 403 * @lport: Fibre Channel local port receiving the RLIR
 404 * @fp:    The RLIR request frame
 405 */
 406static void fc_lport_recv_rlir_req(struct fc_lport *lport, struct fc_frame *fp)
 407{
 408        lockdep_assert_held(&lport->lp_mutex);
 409
 410        FC_LPORT_DBG(lport, "Received RLIR request while in state %s\n",
 411                     fc_lport_state(lport));
 412
 413        fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
 414        fc_frame_free(fp);
 415}
 416
 417/**
 418 * fc_lport_recv_echo_req() - Handle received ECHO request
 419 * @lport: The local port receiving the ECHO
 420 * @fp:    ECHO request frame
 421 */
 422static void fc_lport_recv_echo_req(struct fc_lport *lport,
 423                                   struct fc_frame *in_fp)
 424{
 425        struct fc_frame *fp;
 426        unsigned int len;
 427        void *pp;
 428        void *dp;
 429
 430        lockdep_assert_held(&lport->lp_mutex);
 431
 432        FC_LPORT_DBG(lport, "Received ECHO request while in state %s\n",
 433                     fc_lport_state(lport));
 434
 435        len = fr_len(in_fp) - sizeof(struct fc_frame_header);
 436        pp = fc_frame_payload_get(in_fp, len);
 437
 438        if (len < sizeof(__be32))
 439                len = sizeof(__be32);
 440
 441        fp = fc_frame_alloc(lport, len);
 442        if (fp) {
 443                dp = fc_frame_payload_get(fp, len);
 444                memcpy(dp, pp, len);
 445                *((__be32 *)dp) = htonl(ELS_LS_ACC << 24);
 446                fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
 447                lport->tt.frame_send(lport, fp);
 448        }
 449        fc_frame_free(in_fp);
 450}
 451
 452/**
 453 * fc_lport_recv_rnid_req() - Handle received Request Node ID data request
 454 * @lport: The local port receiving the RNID
 455 * @fp:    The RNID request frame
 456 */
 457static void fc_lport_recv_rnid_req(struct fc_lport *lport,
 458                                   struct fc_frame *in_fp)
 459{
 460        struct fc_frame *fp;
 461        struct fc_els_rnid *req;
 462        struct {
 463                struct fc_els_rnid_resp rnid;
 464                struct fc_els_rnid_cid cid;
 465                struct fc_els_rnid_gen gen;
 466        } *rp;
 467        struct fc_seq_els_data rjt_data;
 468        u8 fmt;
 469        size_t len;
 470
 471        lockdep_assert_held(&lport->lp_mutex);
 472
 473        FC_LPORT_DBG(lport, "Received RNID request while in state %s\n",
 474                     fc_lport_state(lport));
 475
 476        req = fc_frame_payload_get(in_fp, sizeof(*req));
 477        if (!req) {
 478                rjt_data.reason = ELS_RJT_LOGIC;
 479                rjt_data.explan = ELS_EXPL_NONE;
 480                fc_seq_els_rsp_send(in_fp, ELS_LS_RJT, &rjt_data);
 481        } else {
 482                fmt = req->rnid_fmt;
 483                len = sizeof(*rp);
 484                if (fmt != ELS_RNIDF_GEN ||
 485                    ntohl(lport->rnid_gen.rnid_atype) == 0) {
 486                        fmt = ELS_RNIDF_NONE;   /* nothing to provide */
 487                        len -= sizeof(rp->gen);
 488                }
 489                fp = fc_frame_alloc(lport, len);
 490                if (fp) {
 491                        rp = fc_frame_payload_get(fp, len);
 492                        memset(rp, 0, len);
 493                        rp->rnid.rnid_cmd = ELS_LS_ACC;
 494                        rp->rnid.rnid_fmt = fmt;
 495                        rp->rnid.rnid_cid_len = sizeof(rp->cid);
 496                        rp->cid.rnid_wwpn = htonll(lport->wwpn);
 497                        rp->cid.rnid_wwnn = htonll(lport->wwnn);
 498                        if (fmt == ELS_RNIDF_GEN) {
 499                                rp->rnid.rnid_sid_len = sizeof(rp->gen);
 500                                memcpy(&rp->gen, &lport->rnid_gen,
 501                                       sizeof(rp->gen));
 502                        }
 503                        fc_fill_reply_hdr(fp, in_fp, FC_RCTL_ELS_REP, 0);
 504                        lport->tt.frame_send(lport, fp);
 505                }
 506        }
 507        fc_frame_free(in_fp);
 508}
 509
 510/**
 511 * fc_lport_recv_logo_req() - Handle received fabric LOGO request
 512 * @lport: The local port receiving the LOGO
 513 * @fp:    The LOGO request frame
 514 */
 515static void fc_lport_recv_logo_req(struct fc_lport *lport, struct fc_frame *fp)
 516{
 517        lockdep_assert_held(&lport->lp_mutex);
 518
 519        fc_seq_els_rsp_send(fp, ELS_LS_ACC, NULL);
 520        fc_lport_enter_reset(lport);
 521        fc_frame_free(fp);
 522}
 523
 524/**
 525 * fc_fabric_login() - Start the lport state machine
 526 * @lport: The local port that should log into the fabric
 527 *
 528 * Locking Note: This function should not be called
 529 *               with the lport lock held.
 530 */
 531int fc_fabric_login(struct fc_lport *lport)
 532{
 533        int rc = -1;
 534
 535        mutex_lock(&lport->lp_mutex);
 536        if (lport->state == LPORT_ST_DISABLED ||
 537            lport->state == LPORT_ST_LOGO) {
 538                fc_lport_state_enter(lport, LPORT_ST_RESET);
 539                fc_lport_enter_reset(lport);
 540                rc = 0;
 541        }
 542        mutex_unlock(&lport->lp_mutex);
 543
 544        return rc;
 545}
 546EXPORT_SYMBOL(fc_fabric_login);
 547
 548/**
 549 * __fc_linkup() - Handler for transport linkup events
 550 * @lport: The lport whose link is up
 551 */
 552void __fc_linkup(struct fc_lport *lport)
 553{
 554        lockdep_assert_held(&lport->lp_mutex);
 555
 556        if (!lport->link_up) {
 557                lport->link_up = 1;
 558
 559                if (lport->state == LPORT_ST_RESET)
 560                        fc_lport_enter_flogi(lport);
 561        }
 562}
 563
 564/**
 565 * fc_linkup() - Handler for transport linkup events
 566 * @lport: The local port whose link is up
 567 */
 568void fc_linkup(struct fc_lport *lport)
 569{
 570        printk(KERN_INFO "host%d: libfc: Link up on port (%6.6x)\n",
 571               lport->host->host_no, lport->port_id);
 572
 573        mutex_lock(&lport->lp_mutex);
 574        __fc_linkup(lport);
 575        mutex_unlock(&lport->lp_mutex);
 576}
 577EXPORT_SYMBOL(fc_linkup);
 578
 579/**
 580 * __fc_linkdown() - Handler for transport linkdown events
 581 * @lport: The lport whose link is down
 582 */
 583void __fc_linkdown(struct fc_lport *lport)
 584{
 585        lockdep_assert_held(&lport->lp_mutex);
 586
 587        if (lport->link_up) {
 588                lport->link_up = 0;
 589                fc_lport_enter_reset(lport);
 590                lport->tt.fcp_cleanup(lport);
 591        }
 592}
 593
 594/**
 595 * fc_linkdown() - Handler for transport linkdown events
 596 * @lport: The local port whose link is down
 597 */
 598void fc_linkdown(struct fc_lport *lport)
 599{
 600        printk(KERN_INFO "host%d: libfc: Link down on port (%6.6x)\n",
 601               lport->host->host_no, lport->port_id);
 602
 603        mutex_lock(&lport->lp_mutex);
 604        __fc_linkdown(lport);
 605        mutex_unlock(&lport->lp_mutex);
 606}
 607EXPORT_SYMBOL(fc_linkdown);
 608
 609/**
 610 * fc_fabric_logoff() - Logout of the fabric
 611 * @lport: The local port to logoff the fabric
 612 *
 613 * Return value:
 614 *      0 for success, -1 for failure
 615 */
 616int fc_fabric_logoff(struct fc_lport *lport)
 617{
 618        lport->tt.disc_stop_final(lport);
 619        mutex_lock(&lport->lp_mutex);
 620        if (lport->dns_rdata)
 621                fc_rport_logoff(lport->dns_rdata);
 622        mutex_unlock(&lport->lp_mutex);
 623        fc_rport_flush_queue();
 624        mutex_lock(&lport->lp_mutex);
 625        fc_lport_enter_logo(lport);
 626        mutex_unlock(&lport->lp_mutex);
 627        cancel_delayed_work_sync(&lport->retry_work);
 628        return 0;
 629}
 630EXPORT_SYMBOL(fc_fabric_logoff);
 631
 632/**
 633 * fc_lport_destroy() - Unregister a fc_lport
 634 * @lport: The local port to unregister
 635 *
 636 * Note:
 637 * exit routine for fc_lport instance
 638 * clean-up all the allocated memory
 639 * and free up other system resources.
 640 *
 641 */
 642int fc_lport_destroy(struct fc_lport *lport)
 643{
 644        mutex_lock(&lport->lp_mutex);
 645        lport->state = LPORT_ST_DISABLED;
 646        lport->link_up = 0;
 647        lport->tt.frame_send = fc_frame_drop;
 648        mutex_unlock(&lport->lp_mutex);
 649
 650        lport->tt.fcp_abort_io(lport);
 651        lport->tt.disc_stop_final(lport);
 652        lport->tt.exch_mgr_reset(lport, 0, 0);
 653        cancel_delayed_work_sync(&lport->retry_work);
 654        fc_fc4_del_lport(lport);
 655        return 0;
 656}
 657EXPORT_SYMBOL(fc_lport_destroy);
 658
 659/**
 660 * fc_set_mfs() - Set the maximum frame size for a local port
 661 * @lport: The local port to set the MFS for
 662 * @mfs:   The new MFS
 663 */
 664int fc_set_mfs(struct fc_lport *lport, u32 mfs)
 665{
 666        unsigned int old_mfs;
 667        int rc = -EINVAL;
 668
 669        mutex_lock(&lport->lp_mutex);
 670
 671        old_mfs = lport->mfs;
 672
 673        if (mfs >= FC_MIN_MAX_FRAME) {
 674                mfs &= ~3;
 675                if (mfs > FC_MAX_FRAME)
 676                        mfs = FC_MAX_FRAME;
 677                mfs -= sizeof(struct fc_frame_header);
 678                lport->mfs = mfs;
 679                rc = 0;
 680        }
 681
 682        if (!rc && mfs < old_mfs)
 683                fc_lport_enter_reset(lport);
 684
 685        mutex_unlock(&lport->lp_mutex);
 686
 687        return rc;
 688}
 689EXPORT_SYMBOL(fc_set_mfs);
 690
 691/**
 692 * fc_lport_disc_callback() - Callback for discovery events
 693 * @lport: The local port receiving the event
 694 * @event: The discovery event
 695 */
 696static void fc_lport_disc_callback(struct fc_lport *lport,
 697                                   enum fc_disc_event event)
 698{
 699        switch (event) {
 700        case DISC_EV_SUCCESS:
 701                FC_LPORT_DBG(lport, "Discovery succeeded\n");
 702                break;
 703        case DISC_EV_FAILED:
 704                printk(KERN_ERR "host%d: libfc: "
 705                       "Discovery failed for port (%6.6x)\n",
 706                       lport->host->host_no, lport->port_id);
 707                mutex_lock(&lport->lp_mutex);
 708                fc_lport_enter_reset(lport);
 709                mutex_unlock(&lport->lp_mutex);
 710                break;
 711        case DISC_EV_NONE:
 712                WARN_ON(1);
 713                break;
 714        }
 715}
 716
 717/**
 718 * fc_rport_enter_ready() - Enter the ready state and start discovery
 719 * @lport: The local port that is ready
 720 */
 721static void fc_lport_enter_ready(struct fc_lport *lport)
 722{
 723        lockdep_assert_held(&lport->lp_mutex);
 724
 725        FC_LPORT_DBG(lport, "Entered READY from state %s\n",
 726                     fc_lport_state(lport));
 727
 728        fc_lport_state_enter(lport, LPORT_ST_READY);
 729        if (lport->vport)
 730                fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE);
 731        fc_vports_linkchange(lport);
 732
 733        if (!lport->ptp_rdata)
 734                lport->tt.disc_start(fc_lport_disc_callback, lport);
 735}
 736
 737/**
 738 * fc_lport_set_port_id() - set the local port Port ID
 739 * @lport: The local port which will have its Port ID set.
 740 * @port_id: The new port ID.
 741 * @fp: The frame containing the incoming request, or NULL.
 742 */
 743static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id,
 744                                 struct fc_frame *fp)
 745{
 746        lockdep_assert_held(&lport->lp_mutex);
 747
 748        if (port_id)
 749                printk(KERN_INFO "host%d: Assigned Port ID %6.6x\n",
 750                       lport->host->host_no, port_id);
 751
 752        lport->port_id = port_id;
 753
 754        /* Update the fc_host */
 755        fc_host_port_id(lport->host) = port_id;
 756
 757        if (lport->tt.lport_set_port_id)
 758                lport->tt.lport_set_port_id(lport, port_id, fp);
 759}
 760
 761/**
 762 * fc_lport_set_port_id() - set the local port Port ID for point-to-multipoint
 763 * @lport: The local port which will have its Port ID set.
 764 * @port_id: The new port ID.
 765 *
 766 * Called by the lower-level driver when transport sets the local port_id.
 767 * This is used in VN_port to VN_port mode for FCoE, and causes FLOGI and
 768 * discovery to be skipped.
 769 */
 770void fc_lport_set_local_id(struct fc_lport *lport, u32 port_id)
 771{
 772        mutex_lock(&lport->lp_mutex);
 773
 774        fc_lport_set_port_id(lport, port_id, NULL);
 775
 776        switch (lport->state) {
 777        case LPORT_ST_RESET:
 778        case LPORT_ST_FLOGI:
 779                if (port_id)
 780                        fc_lport_enter_ready(lport);
 781                break;
 782        default:
 783                break;
 784        }
 785        mutex_unlock(&lport->lp_mutex);
 786}
 787EXPORT_SYMBOL(fc_lport_set_local_id);
 788
 789/**
 790 * fc_lport_recv_flogi_req() - Receive a FLOGI request
 791 * @lport: The local port that received the request
 792 * @rx_fp: The FLOGI frame
 793 *
 794 * A received FLOGI request indicates a point-to-point connection.
 795 * Accept it with the common service parameters indicating our N port.
 796 * Set up to do a PLOGI if we have the higher-number WWPN.
 797 */
 798static void fc_lport_recv_flogi_req(struct fc_lport *lport,
 799                                    struct fc_frame *rx_fp)
 800{
 801        struct fc_frame *fp;
 802        struct fc_frame_header *fh;
 803        struct fc_els_flogi *flp;
 804        struct fc_els_flogi *new_flp;
 805        u64 remote_wwpn;
 806        u32 remote_fid;
 807        u32 local_fid;
 808
 809        lockdep_assert_held(&lport->lp_mutex);
 810
 811        FC_LPORT_DBG(lport, "Received FLOGI request while in state %s\n",
 812                     fc_lport_state(lport));
 813
 814        remote_fid = fc_frame_sid(rx_fp);
 815        flp = fc_frame_payload_get(rx_fp, sizeof(*flp));
 816        if (!flp)
 817                goto out;
 818        remote_wwpn = get_unaligned_be64(&flp->fl_wwpn);
 819        if (remote_wwpn == lport->wwpn) {
 820                printk(KERN_WARNING "host%d: libfc: Received FLOGI from port "
 821                       "with same WWPN %16.16llx\n",
 822                       lport->host->host_no, remote_wwpn);
 823                goto out;
 824        }
 825        FC_LPORT_DBG(lport, "FLOGI from port WWPN %16.16llx\n", remote_wwpn);
 826
 827        /*
 828         * XXX what is the right thing to do for FIDs?
 829         * The originator might expect our S_ID to be 0xfffffe.
 830         * But if so, both of us could end up with the same FID.
 831         */
 832        local_fid = FC_LOCAL_PTP_FID_LO;
 833        if (remote_wwpn < lport->wwpn) {
 834                local_fid = FC_LOCAL_PTP_FID_HI;
 835                if (!remote_fid || remote_fid == local_fid)
 836                        remote_fid = FC_LOCAL_PTP_FID_LO;
 837        } else if (!remote_fid) {
 838                remote_fid = FC_LOCAL_PTP_FID_HI;
 839        }
 840
 841        fc_lport_set_port_id(lport, local_fid, rx_fp);
 842
 843        fp = fc_frame_alloc(lport, sizeof(*flp));
 844        if (fp) {
 845                new_flp = fc_frame_payload_get(fp, sizeof(*flp));
 846                fc_lport_flogi_fill(lport, new_flp, ELS_FLOGI);
 847                new_flp->fl_cmd = (u8) ELS_LS_ACC;
 848
 849                /*
 850                 * Send the response.  If this fails, the originator should
 851                 * repeat the sequence.
 852                 */
 853                fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
 854                fh = fc_frame_header_get(fp);
 855                hton24(fh->fh_s_id, local_fid);
 856                hton24(fh->fh_d_id, remote_fid);
 857                lport->tt.frame_send(lport, fp);
 858
 859        } else {
 860                fc_lport_error(lport, fp);
 861        }
 862        fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
 863                           get_unaligned_be64(&flp->fl_wwnn));
 864out:
 865        fc_frame_free(rx_fp);
 866}
 867
 868/**
 869 * fc_lport_recv_els_req() - The generic lport ELS request handler
 870 * @lport: The local port that received the request
 871 * @fp:    The request frame
 872 *
 873 * This function will see if the lport handles the request or
 874 * if an rport should handle the request.
 875 *
 876 * Locking Note: This function should not be called with the lport
 877 *               lock held because it will grab the lock.
 878 */
 879static void fc_lport_recv_els_req(struct fc_lport *lport,
 880                                  struct fc_frame *fp)
 881{
 882        mutex_lock(&lport->lp_mutex);
 883
 884        /*
 885         * Handle special ELS cases like FLOGI, LOGO, and
 886         * RSCN here.  These don't require a session.
 887         * Even if we had a session, it might not be ready.
 888         */
 889        if (!lport->link_up)
 890                fc_frame_free(fp);
 891        else {
 892                /*
 893                 * Check opcode.
 894                 */
 895                switch (fc_frame_payload_op(fp)) {
 896                case ELS_FLOGI:
 897                        if (!lport->point_to_multipoint)
 898                                fc_lport_recv_flogi_req(lport, fp);
 899                        else
 900                                fc_rport_recv_req(lport, fp);
 901                        break;
 902                case ELS_LOGO:
 903                        if (fc_frame_sid(fp) == FC_FID_FLOGI)
 904                                fc_lport_recv_logo_req(lport, fp);
 905                        else
 906                                fc_rport_recv_req(lport, fp);
 907                        break;
 908                case ELS_RSCN:
 909                        lport->tt.disc_recv_req(lport, fp);
 910                        break;
 911                case ELS_ECHO:
 912                        fc_lport_recv_echo_req(lport, fp);
 913                        break;
 914                case ELS_RLIR:
 915                        fc_lport_recv_rlir_req(lport, fp);
 916                        break;
 917                case ELS_RNID:
 918                        fc_lport_recv_rnid_req(lport, fp);
 919                        break;
 920                default:
 921                        fc_rport_recv_req(lport, fp);
 922                        break;
 923                }
 924        }
 925        mutex_unlock(&lport->lp_mutex);
 926}
 927
 928static int fc_lport_els_prli(struct fc_rport_priv *rdata, u32 spp_len,
 929                             const struct fc_els_spp *spp_in,
 930                             struct fc_els_spp *spp_out)
 931{
 932        return FC_SPP_RESP_INVL;
 933}
 934
 935struct fc4_prov fc_lport_els_prov = {
 936        .prli = fc_lport_els_prli,
 937        .recv = fc_lport_recv_els_req,
 938};
 939
 940/**
 941 * fc_lport_recv() - The generic lport request handler
 942 * @lport: The lport that received the request
 943 * @fp: The frame the request is in
 944 *
 945 * Locking Note: This function should not be called with the lport
 946 *               lock held because it may grab the lock.
 947 */
 948void fc_lport_recv(struct fc_lport *lport, struct fc_frame *fp)
 949{
 950        struct fc_frame_header *fh = fc_frame_header_get(fp);
 951        struct fc_seq *sp = fr_seq(fp);
 952        struct fc4_prov *prov;
 953
 954        /*
 955         * Use RCU read lock and module_lock to be sure module doesn't
 956         * deregister and get unloaded while we're calling it.
 957         * try_module_get() is inlined and accepts a NULL parameter.
 958         * Only ELSes and FCP target ops should come through here.
 959         * The locking is unfortunate, and a better scheme is being sought.
 960         */
 961
 962        rcu_read_lock();
 963        if (fh->fh_type >= FC_FC4_PROV_SIZE)
 964                goto drop;
 965        prov = rcu_dereference(fc_passive_prov[fh->fh_type]);
 966        if (!prov || !try_module_get(prov->module))
 967                goto drop;
 968        rcu_read_unlock();
 969        prov->recv(lport, fp);
 970        module_put(prov->module);
 971        return;
 972drop:
 973        rcu_read_unlock();
 974        FC_LPORT_DBG(lport, "dropping unexpected frame type %x\n", fh->fh_type);
 975        fc_frame_free(fp);
 976        if (sp)
 977                fc_exch_done(sp);
 978}
 979EXPORT_SYMBOL(fc_lport_recv);
 980
 981/**
 982 * fc_lport_reset() - Reset a local port
 983 * @lport: The local port which should be reset
 984 *
 985 * Locking Note: This functions should not be called with the
 986 *               lport lock held.
 987 */
 988int fc_lport_reset(struct fc_lport *lport)
 989{
 990        cancel_delayed_work_sync(&lport->retry_work);
 991        mutex_lock(&lport->lp_mutex);
 992        fc_lport_enter_reset(lport);
 993        mutex_unlock(&lport->lp_mutex);
 994        return 0;
 995}
 996EXPORT_SYMBOL(fc_lport_reset);
 997
 998/**
 999 * fc_lport_reset_locked() - Reset the local port w/ the lport lock held
1000 * @lport: The local port to be reset
1001 */
1002static void fc_lport_reset_locked(struct fc_lport *lport)
1003{
1004        lockdep_assert_held(&lport->lp_mutex);
1005
1006        if (lport->dns_rdata) {
1007                fc_rport_logoff(lport->dns_rdata);
1008                lport->dns_rdata = NULL;
1009        }
1010
1011        if (lport->ptp_rdata) {
1012                fc_rport_logoff(lport->ptp_rdata);
1013                kref_put(&lport->ptp_rdata->kref, fc_rport_destroy);
1014                lport->ptp_rdata = NULL;
1015        }
1016
1017        lport->tt.disc_stop(lport);
1018
1019        lport->tt.exch_mgr_reset(lport, 0, 0);
1020        fc_host_fabric_name(lport->host) = 0;
1021
1022        if (lport->port_id && (!lport->point_to_multipoint || !lport->link_up))
1023                fc_lport_set_port_id(lport, 0, NULL);
1024}
1025
1026/**
1027 * fc_lport_enter_reset() - Reset the local port
1028 * @lport: The local port to be reset
1029 */
1030static void fc_lport_enter_reset(struct fc_lport *lport)
1031{
1032        lockdep_assert_held(&lport->lp_mutex);
1033
1034        FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
1035                     fc_lport_state(lport));
1036
1037        if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
1038                return;
1039
1040        if (lport->vport) {
1041                if (lport->link_up)
1042                        fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
1043                else
1044                        fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN);
1045        }
1046        fc_lport_state_enter(lport, LPORT_ST_RESET);
1047        fc_host_post_event(lport->host, fc_get_event_number(),
1048                           FCH_EVT_LIPRESET, 0);
1049        fc_vports_linkchange(lport);
1050        fc_lport_reset_locked(lport);
1051        if (lport->link_up)
1052                fc_lport_enter_flogi(lport);
1053}
1054
1055/**
1056 * fc_lport_enter_disabled() - Disable the local port
1057 * @lport: The local port to be reset
1058 */
1059static void fc_lport_enter_disabled(struct fc_lport *lport)
1060{
1061        lockdep_assert_held(&lport->lp_mutex);
1062
1063        FC_LPORT_DBG(lport, "Entered disabled state from %s state\n",
1064                     fc_lport_state(lport));
1065
1066        fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1067        fc_vports_linkchange(lport);
1068        fc_lport_reset_locked(lport);
1069}
1070
1071/**
1072 * fc_lport_error() - Handler for any errors
1073 * @lport: The local port that the error was on
1074 * @fp:    The error code encoded in a frame pointer
1075 *
1076 * If the error was caused by a resource allocation failure
1077 * then wait for half a second and retry, otherwise retry
1078 * after the e_d_tov time.
1079 */
1080static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
1081{
1082        unsigned long delay = 0;
1083        FC_LPORT_DBG(lport, "Error %ld in state %s, retries %d\n",
1084                     IS_ERR(fp) ? -PTR_ERR(fp) : 0, fc_lport_state(lport),
1085                     lport->retry_count);
1086
1087        if (PTR_ERR(fp) == -FC_EX_CLOSED)
1088                return;
1089
1090        /*
1091         * Memory allocation failure, or the exchange timed out
1092         * or we received LS_RJT.
1093         * Retry after delay
1094         */
1095        if (lport->retry_count < lport->max_retry_count) {
1096                lport->retry_count++;
1097                if (!fp)
1098                        delay = msecs_to_jiffies(500);
1099                else
1100                        delay = msecs_to_jiffies(lport->e_d_tov);
1101
1102                schedule_delayed_work(&lport->retry_work, delay);
1103        } else
1104                fc_lport_enter_reset(lport);
1105}
1106
1107/**
1108 * fc_lport_ns_resp() - Handle response to a name server
1109 *                      registration exchange
1110 * @sp:     current sequence in exchange
1111 * @fp:     response frame
1112 * @lp_arg: Fibre Channel host port instance
1113 *
1114 * Locking Note: This function will be called without the lport lock
1115 * held, but it will lock, call an _enter_* function or fc_lport_error()
1116 * and then unlock the lport.
1117 */
1118static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
1119                             void *lp_arg)
1120{
1121        struct fc_lport *lport = lp_arg;
1122        struct fc_frame_header *fh;
1123        struct fc_ct_hdr *ct;
1124
1125        FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp));
1126
1127        if (fp == ERR_PTR(-FC_EX_CLOSED))
1128                return;
1129
1130        mutex_lock(&lport->lp_mutex);
1131
1132        if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
1133                FC_LPORT_DBG(lport, "Received a name server response, "
1134                             "but in state %s\n", fc_lport_state(lport));
1135                if (IS_ERR(fp))
1136                        goto err;
1137                goto out;
1138        }
1139
1140        if (IS_ERR(fp)) {
1141                fc_lport_error(lport, fp);
1142                goto err;
1143        }
1144
1145        fh = fc_frame_header_get(fp);
1146        ct = fc_frame_payload_get(fp, sizeof(*ct));
1147
1148        if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1149            ct->ct_fs_type == FC_FST_DIR &&
1150            ct->ct_fs_subtype == FC_NS_SUBTYPE &&
1151            ntohs(ct->ct_cmd) == FC_FS_ACC)
1152                switch (lport->state) {
1153                case LPORT_ST_RNN_ID:
1154                        fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN);
1155                        break;
1156                case LPORT_ST_RSNN_NN:
1157                        fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID);
1158                        break;
1159                case LPORT_ST_RSPN_ID:
1160                        fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1161                        break;
1162                case LPORT_ST_RFT_ID:
1163                        fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
1164                        break;
1165                case LPORT_ST_RFF_ID:
1166                        if (lport->fdmi_enabled)
1167                                fc_lport_enter_fdmi(lport);
1168                        else
1169                                fc_lport_enter_scr(lport);
1170                        break;
1171                default:
1172                        /* should have already been caught by state checks */
1173                        break;
1174                }
1175        else
1176                fc_lport_error(lport, fp);
1177out:
1178        fc_frame_free(fp);
1179err:
1180        mutex_unlock(&lport->lp_mutex);
1181}
1182
1183/**
1184 * fc_lport_ms_resp() - Handle response to a management server
1185 *                      exchange
1186 * @sp:     current sequence in exchange
1187 * @fp:     response frame
1188 * @lp_arg: Fibre Channel host port instance
1189 *
1190 * Locking Note: This function will be called without the lport lock
1191 * held, but it will lock, call an _enter_* function or fc_lport_error()
1192 * and then unlock the lport.
1193 */
1194static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp,
1195                             void *lp_arg)
1196{
1197        struct fc_lport *lport = lp_arg;
1198        struct fc_frame_header *fh;
1199        struct fc_ct_hdr *ct;
1200
1201        FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp));
1202
1203        if (fp == ERR_PTR(-FC_EX_CLOSED))
1204                return;
1205
1206        mutex_lock(&lport->lp_mutex);
1207
1208        if (lport->state < LPORT_ST_RHBA || lport->state > LPORT_ST_DPRT) {
1209                FC_LPORT_DBG(lport, "Received a management server response, "
1210                             "but in state %s\n", fc_lport_state(lport));
1211                if (IS_ERR(fp))
1212                        goto err;
1213                goto out;
1214        }
1215
1216        if (IS_ERR(fp)) {
1217                fc_lport_error(lport, fp);
1218                goto err;
1219        }
1220
1221        fh = fc_frame_header_get(fp);
1222        ct = fc_frame_payload_get(fp, sizeof(*ct));
1223
1224        if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1225            ct->ct_fs_type == FC_FST_MGMT &&
1226            ct->ct_fs_subtype == FC_FDMI_SUBTYPE) {
1227                FC_LPORT_DBG(lport, "Received a management server response, "
1228                                    "reason=%d explain=%d\n",
1229                                    ct->ct_reason,
1230                                    ct->ct_explan);
1231
1232                switch (lport->state) {
1233                case LPORT_ST_RHBA:
1234                        if (ntohs(ct->ct_cmd) == FC_FS_ACC)
1235                                fc_lport_enter_ms(lport, LPORT_ST_RPA);
1236                        else /* Error Skip RPA */
1237                                fc_lport_enter_scr(lport);
1238                        break;
1239                case LPORT_ST_RPA:
1240                        fc_lport_enter_scr(lport);
1241                        break;
1242                case LPORT_ST_DPRT:
1243                        fc_lport_enter_ms(lport, LPORT_ST_RHBA);
1244                        break;
1245                case LPORT_ST_DHBA:
1246                        fc_lport_enter_ms(lport, LPORT_ST_DPRT);
1247                        break;
1248                default:
1249                        /* should have already been caught by state checks */
1250                        break;
1251                }
1252        } else {
1253                /* Invalid Frame? */
1254                fc_lport_error(lport, fp);
1255        }
1256out:
1257        fc_frame_free(fp);
1258err:
1259        mutex_unlock(&lport->lp_mutex);
1260}
1261
1262/**
1263 * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
1264 * @sp:     current sequence in SCR exchange
1265 * @fp:     response frame
1266 * @lp_arg: Fibre Channel lport port instance that sent the registration request
1267 *
1268 * Locking Note: This function will be called without the lport lock
1269 * held, but it will lock, call an _enter_* function or fc_lport_error
1270 * and then unlock the lport.
1271 */
1272static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
1273                              void *lp_arg)
1274{
1275        struct fc_lport *lport = lp_arg;
1276        u8 op;
1277
1278        FC_LPORT_DBG(lport, "Received a SCR %s\n", fc_els_resp_type(fp));
1279
1280        if (fp == ERR_PTR(-FC_EX_CLOSED))
1281                return;
1282
1283        mutex_lock(&lport->lp_mutex);
1284
1285        if (lport->state != LPORT_ST_SCR) {
1286                FC_LPORT_DBG(lport, "Received a SCR response, but in state "
1287                             "%s\n", fc_lport_state(lport));
1288                if (IS_ERR(fp))
1289                        goto err;
1290                goto out;
1291        }
1292
1293        if (IS_ERR(fp)) {
1294                fc_lport_error(lport, fp);
1295                goto err;
1296        }
1297
1298        op = fc_frame_payload_op(fp);
1299        if (op == ELS_LS_ACC)
1300                fc_lport_enter_ready(lport);
1301        else
1302                fc_lport_error(lport, fp);
1303
1304out:
1305        fc_frame_free(fp);
1306err:
1307        mutex_unlock(&lport->lp_mutex);
1308}
1309
1310/**
1311 * fc_lport_enter_scr() - Send a SCR (State Change Register) request
1312 * @lport: The local port to register for state changes
1313 */
1314static void fc_lport_enter_scr(struct fc_lport *lport)
1315{
1316        struct fc_frame *fp;
1317
1318        lockdep_assert_held(&lport->lp_mutex);
1319
1320        FC_LPORT_DBG(lport, "Entered SCR state from %s state\n",
1321                     fc_lport_state(lport));
1322
1323        fc_lport_state_enter(lport, LPORT_ST_SCR);
1324
1325        fp = fc_frame_alloc(lport, sizeof(struct fc_els_scr));
1326        if (!fp) {
1327                fc_lport_error(lport, fp);
1328                return;
1329        }
1330
1331        if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
1332                                  fc_lport_scr_resp, lport,
1333                                  2 * lport->r_a_tov))
1334                fc_lport_error(lport, NULL);
1335}
1336
1337/**
1338 * fc_lport_enter_ns() - register some object with the name server
1339 * @lport: Fibre Channel local port to register
1340 */
1341static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
1342{
1343        struct fc_frame *fp;
1344        enum fc_ns_req cmd;
1345        int size = sizeof(struct fc_ct_hdr);
1346        size_t len;
1347
1348        lockdep_assert_held(&lport->lp_mutex);
1349
1350        FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1351                     fc_lport_state_names[state],
1352                     fc_lport_state(lport));
1353
1354        fc_lport_state_enter(lport, state);
1355
1356        switch (state) {
1357        case LPORT_ST_RNN_ID:
1358                cmd = FC_NS_RNN_ID;
1359                size += sizeof(struct fc_ns_rn_id);
1360                break;
1361        case LPORT_ST_RSNN_NN:
1362                len = strnlen(fc_host_symbolic_name(lport->host), 255);
1363                /* if there is no symbolic name, skip to RFT_ID */
1364                if (!len)
1365                        return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1366                cmd = FC_NS_RSNN_NN;
1367                size += sizeof(struct fc_ns_rsnn) + len;
1368                break;
1369        case LPORT_ST_RSPN_ID:
1370                len = strnlen(fc_host_symbolic_name(lport->host), 255);
1371                /* if there is no symbolic name, skip to RFT_ID */
1372                if (!len)
1373                        return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1374                cmd = FC_NS_RSPN_ID;
1375                size += sizeof(struct fc_ns_rspn) + len;
1376                break;
1377        case LPORT_ST_RFT_ID:
1378                cmd = FC_NS_RFT_ID;
1379                size += sizeof(struct fc_ns_rft);
1380                break;
1381        case LPORT_ST_RFF_ID:
1382                cmd = FC_NS_RFF_ID;
1383                size += sizeof(struct fc_ns_rff_id);
1384                break;
1385        default:
1386                fc_lport_error(lport, NULL);
1387                return;
1388        }
1389
1390        fp = fc_frame_alloc(lport, size);
1391        if (!fp) {
1392                fc_lport_error(lport, fp);
1393                return;
1394        }
1395
1396        if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd,
1397                                  fc_lport_ns_resp,
1398                                  lport, 3 * lport->r_a_tov))
1399                fc_lport_error(lport, fp);
1400}
1401
1402static struct fc_rport_operations fc_lport_rport_ops = {
1403        .event_callback = fc_lport_rport_callback,
1404};
1405
1406/**
1407 * fc_rport_enter_dns() - Create a fc_rport for the name server
1408 * @lport: The local port requesting a remote port for the name server
1409 */
1410static void fc_lport_enter_dns(struct fc_lport *lport)
1411{
1412        struct fc_rport_priv *rdata;
1413
1414        lockdep_assert_held(&lport->lp_mutex);
1415
1416        FC_LPORT_DBG(lport, "Entered DNS state from %s state\n",
1417                     fc_lport_state(lport));
1418
1419        fc_lport_state_enter(lport, LPORT_ST_DNS);
1420
1421        mutex_lock(&lport->disc.disc_mutex);
1422        rdata = fc_rport_create(lport, FC_FID_DIR_SERV);
1423        mutex_unlock(&lport->disc.disc_mutex);
1424        if (!rdata)
1425                goto err;
1426
1427        rdata->ops = &fc_lport_rport_ops;
1428        fc_rport_login(rdata);
1429        return;
1430
1431err:
1432        fc_lport_error(lport, NULL);
1433}
1434
1435/**
1436 * fc_lport_enter_ms() - management server commands
1437 * @lport: Fibre Channel local port to register
1438 */
1439static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state)
1440{
1441        struct fc_frame *fp;
1442        enum fc_fdmi_req cmd;
1443        int size = sizeof(struct fc_ct_hdr);
1444        size_t len;
1445        int numattrs;
1446
1447        lockdep_assert_held(&lport->lp_mutex);
1448
1449        FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
1450                     fc_lport_state_names[state],
1451                     fc_lport_state(lport));
1452
1453        fc_lport_state_enter(lport, state);
1454
1455        switch (state) {
1456        case LPORT_ST_RHBA:
1457                cmd = FC_FDMI_RHBA;
1458                /* Number of HBA Attributes */
1459                numattrs = 10;
1460                len = sizeof(struct fc_fdmi_rhba);
1461                len -= sizeof(struct fc_fdmi_attr_entry);
1462                len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
1463                len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
1464                len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
1465                len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
1466                len += FC_FDMI_HBA_ATTR_MODEL_LEN;
1467                len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
1468                len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
1469                len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
1470                len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
1471                len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
1472                len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
1473
1474                size += len;
1475                break;
1476        case LPORT_ST_RPA:
1477                cmd = FC_FDMI_RPA;
1478                /* Number of Port Attributes */
1479                numattrs = 6;
1480                len = sizeof(struct fc_fdmi_rpa);
1481                len -= sizeof(struct fc_fdmi_attr_entry);
1482                len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
1483                len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
1484                len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
1485                len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
1486                len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
1487                len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
1488                len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
1489
1490                size += len;
1491                break;
1492        case LPORT_ST_DPRT:
1493                cmd = FC_FDMI_DPRT;
1494                len = sizeof(struct fc_fdmi_dprt);
1495                size += len;
1496                break;
1497        case LPORT_ST_DHBA:
1498                cmd = FC_FDMI_DHBA;
1499                len = sizeof(struct fc_fdmi_dhba);
1500                size += len;
1501                break;
1502        default:
1503                fc_lport_error(lport, NULL);
1504                return;
1505        }
1506
1507        FC_LPORT_DBG(lport, "Cmd=0x%x Len %d size %d\n",
1508                             cmd, (int)len, size);
1509        fp = fc_frame_alloc(lport, size);
1510        if (!fp) {
1511                fc_lport_error(lport, fp);
1512                return;
1513        }
1514
1515        if (!lport->tt.elsct_send(lport, FC_FID_MGMT_SERV, fp, cmd,
1516                                  fc_lport_ms_resp,
1517                                  lport, 3 * lport->r_a_tov))
1518                fc_lport_error(lport, fp);
1519}
1520
1521/**
1522 * fc_rport_enter_fdmi() - Create a fc_rport for the management server
1523 * @lport: The local port requesting a remote port for the management server
1524 */
1525static void fc_lport_enter_fdmi(struct fc_lport *lport)
1526{
1527        struct fc_rport_priv *rdata;
1528
1529        lockdep_assert_held(&lport->lp_mutex);
1530
1531        FC_LPORT_DBG(lport, "Entered FDMI state from %s state\n",
1532                     fc_lport_state(lport));
1533
1534        fc_lport_state_enter(lport, LPORT_ST_FDMI);
1535
1536        mutex_lock(&lport->disc.disc_mutex);
1537        rdata = fc_rport_create(lport, FC_FID_MGMT_SERV);
1538        mutex_unlock(&lport->disc.disc_mutex);
1539        if (!rdata)
1540                goto err;
1541
1542        rdata->ops = &fc_lport_rport_ops;
1543        fc_rport_login(rdata);
1544        return;
1545
1546err:
1547        fc_lport_error(lport, NULL);
1548}
1549
1550/**
1551 * fc_lport_timeout() - Handler for the retry_work timer
1552 * @work: The work struct of the local port
1553 */
1554static void fc_lport_timeout(struct work_struct *work)
1555{
1556        struct fc_lport *lport =
1557                container_of(work, struct fc_lport,
1558                             retry_work.work);
1559
1560        mutex_lock(&lport->lp_mutex);
1561
1562        switch (lport->state) {
1563        case LPORT_ST_DISABLED:
1564                break;
1565        case LPORT_ST_READY:
1566                break;
1567        case LPORT_ST_RESET:
1568                break;
1569        case LPORT_ST_FLOGI:
1570                fc_lport_enter_flogi(lport);
1571                break;
1572        case LPORT_ST_DNS:
1573                fc_lport_enter_dns(lport);
1574                break;
1575        case LPORT_ST_RNN_ID:
1576        case LPORT_ST_RSNN_NN:
1577        case LPORT_ST_RSPN_ID:
1578        case LPORT_ST_RFT_ID:
1579        case LPORT_ST_RFF_ID:
1580                fc_lport_enter_ns(lport, lport->state);
1581                break;
1582        case LPORT_ST_FDMI:
1583                fc_lport_enter_fdmi(lport);
1584                break;
1585        case LPORT_ST_RHBA:
1586        case LPORT_ST_RPA:
1587        case LPORT_ST_DHBA:
1588        case LPORT_ST_DPRT:
1589                FC_LPORT_DBG(lport, "Skipping lport state %s to SCR\n",
1590                             fc_lport_state(lport));
1591                /* fall thru */
1592        case LPORT_ST_SCR:
1593                fc_lport_enter_scr(lport);
1594                break;
1595        case LPORT_ST_LOGO:
1596                fc_lport_enter_logo(lport);
1597                break;
1598        }
1599
1600        mutex_unlock(&lport->lp_mutex);
1601}
1602
1603/**
1604 * fc_lport_logo_resp() - Handle response to LOGO request
1605 * @sp:     The sequence that the LOGO was on
1606 * @fp:     The LOGO frame
1607 * @lp_arg: The lport port that received the LOGO request
1608 *
1609 * Locking Note: This function will be called without the lport lock
1610 * held, but it will lock, call an _enter_* function or fc_lport_error()
1611 * and then unlock the lport.
1612 */
1613void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1614                        void *lp_arg)
1615{
1616        struct fc_lport *lport = lp_arg;
1617        u8 op;
1618
1619        FC_LPORT_DBG(lport, "Received a LOGO %s\n", fc_els_resp_type(fp));
1620
1621        if (fp == ERR_PTR(-FC_EX_CLOSED))
1622                return;
1623
1624        mutex_lock(&lport->lp_mutex);
1625
1626        if (lport->state != LPORT_ST_LOGO) {
1627                FC_LPORT_DBG(lport, "Received a LOGO response, but in state "
1628                             "%s\n", fc_lport_state(lport));
1629                if (IS_ERR(fp))
1630                        goto err;
1631                goto out;
1632        }
1633
1634        if (IS_ERR(fp)) {
1635                fc_lport_error(lport, fp);
1636                goto err;
1637        }
1638
1639        op = fc_frame_payload_op(fp);
1640        if (op == ELS_LS_ACC)
1641                fc_lport_enter_disabled(lport);
1642        else
1643                fc_lport_error(lport, fp);
1644
1645out:
1646        fc_frame_free(fp);
1647err:
1648        mutex_unlock(&lport->lp_mutex);
1649}
1650EXPORT_SYMBOL(fc_lport_logo_resp);
1651
1652/**
1653 * fc_rport_enter_logo() - Logout of the fabric
1654 * @lport: The local port to be logged out
1655 */
1656static void fc_lport_enter_logo(struct fc_lport *lport)
1657{
1658        struct fc_frame *fp;
1659        struct fc_els_logo *logo;
1660
1661        lockdep_assert_held(&lport->lp_mutex);
1662
1663        FC_LPORT_DBG(lport, "Entered LOGO state from %s state\n",
1664                     fc_lport_state(lport));
1665
1666        fc_lport_state_enter(lport, LPORT_ST_LOGO);
1667        fc_vports_linkchange(lport);
1668
1669        fp = fc_frame_alloc(lport, sizeof(*logo));
1670        if (!fp) {
1671                fc_lport_error(lport, fp);
1672                return;
1673        }
1674
1675        if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
1676                                  fc_lport_logo_resp, lport,
1677                                  2 * lport->r_a_tov))
1678                fc_lport_error(lport, NULL);
1679}
1680
1681/**
1682 * fc_lport_flogi_resp() - Handle response to FLOGI request
1683 * @sp:     The sequence that the FLOGI was on
1684 * @fp:     The FLOGI response frame
1685 * @lp_arg: The lport port that received the FLOGI response
1686 *
1687 * Locking Note: This function will be called without the lport lock
1688 * held, but it will lock, call an _enter_* function or fc_lport_error()
1689 * and then unlock the lport.
1690 */
1691void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1692                         void *lp_arg)
1693{
1694        struct fc_lport *lport = lp_arg;
1695        struct fc_frame_header *fh;
1696        struct fc_els_flogi *flp;
1697        u32 did;
1698        u16 csp_flags;
1699        unsigned int r_a_tov;
1700        unsigned int e_d_tov;
1701        u16 mfs;
1702
1703        FC_LPORT_DBG(lport, "Received a FLOGI %s\n", fc_els_resp_type(fp));
1704
1705        if (fp == ERR_PTR(-FC_EX_CLOSED))
1706                return;
1707
1708        mutex_lock(&lport->lp_mutex);
1709
1710        if (lport->state != LPORT_ST_FLOGI) {
1711                FC_LPORT_DBG(lport, "Received a FLOGI response, but in state "
1712                             "%s\n", fc_lport_state(lport));
1713                if (IS_ERR(fp))
1714                        goto err;
1715                goto out;
1716        }
1717
1718        if (IS_ERR(fp)) {
1719                fc_lport_error(lport, fp);
1720                goto err;
1721        }
1722
1723        fh = fc_frame_header_get(fp);
1724        did = fc_frame_did(fp);
1725        if (fh->fh_r_ctl != FC_RCTL_ELS_REP || did == 0 ||
1726            fc_frame_payload_op(fp) != ELS_LS_ACC) {
1727                FC_LPORT_DBG(lport, "FLOGI not accepted or bad response\n");
1728                fc_lport_error(lport, fp);
1729                goto out;
1730        }
1731
1732        flp = fc_frame_payload_get(fp, sizeof(*flp));
1733        if (!flp) {
1734                FC_LPORT_DBG(lport, "FLOGI bad response\n");
1735                fc_lport_error(lport, fp);
1736                goto out;
1737        }
1738
1739        mfs = ntohs(flp->fl_csp.sp_bb_data) &
1740                FC_SP_BB_DATA_MASK;
1741
1742        if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
1743                FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
1744                             "lport->mfs:%hu\n", mfs, lport->mfs);
1745                fc_lport_error(lport, fp);
1746                goto out;
1747        }
1748
1749        if (mfs <= lport->mfs) {
1750                lport->mfs = mfs;
1751                fc_host_maxframe_size(lport->host) = mfs;
1752        }
1753
1754        csp_flags = ntohs(flp->fl_csp.sp_features);
1755        r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
1756        e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
1757        if (csp_flags & FC_SP_FT_EDTR)
1758                e_d_tov /= 1000000;
1759
1760        lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC);
1761
1762        if ((csp_flags & FC_SP_FT_FPORT) == 0) {
1763                if (e_d_tov > lport->e_d_tov)
1764                        lport->e_d_tov = e_d_tov;
1765                lport->r_a_tov = 2 * lport->e_d_tov;
1766                fc_lport_set_port_id(lport, did, fp);
1767                printk(KERN_INFO "host%d: libfc: "
1768                       "Port (%6.6x) entered "
1769                       "point-to-point mode\n",
1770                       lport->host->host_no, did);
1771                fc_lport_ptp_setup(lport, fc_frame_sid(fp),
1772                                   get_unaligned_be64(
1773                                           &flp->fl_wwpn),
1774                                   get_unaligned_be64(
1775                                           &flp->fl_wwnn));
1776        } else {
1777                if (e_d_tov > lport->e_d_tov)
1778                        lport->e_d_tov = e_d_tov;
1779                if (r_a_tov > lport->r_a_tov)
1780                        lport->r_a_tov = r_a_tov;
1781                fc_host_fabric_name(lport->host) =
1782                        get_unaligned_be64(&flp->fl_wwnn);
1783                fc_lport_set_port_id(lport, did, fp);
1784                fc_lport_enter_dns(lport);
1785        }
1786
1787out:
1788        fc_frame_free(fp);
1789err:
1790        mutex_unlock(&lport->lp_mutex);
1791}
1792EXPORT_SYMBOL(fc_lport_flogi_resp);
1793
1794/**
1795 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
1796 * @lport: Fibre Channel local port to be logged in to the fabric
1797 */
1798static void fc_lport_enter_flogi(struct fc_lport *lport)
1799{
1800        struct fc_frame *fp;
1801
1802        lockdep_assert_held(&lport->lp_mutex);
1803
1804        FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n",
1805                     fc_lport_state(lport));
1806
1807        fc_lport_state_enter(lport, LPORT_ST_FLOGI);
1808
1809        if (lport->point_to_multipoint) {
1810                if (lport->port_id)
1811                        fc_lport_enter_ready(lport);
1812                return;
1813        }
1814
1815        fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
1816        if (!fp)
1817                return fc_lport_error(lport, fp);
1818
1819        if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp,
1820                                  lport->vport ? ELS_FDISC : ELS_FLOGI,
1821                                  fc_lport_flogi_resp, lport,
1822                                  lport->vport ? 2 * lport->r_a_tov :
1823                                  lport->e_d_tov))
1824                fc_lport_error(lport, NULL);
1825}
1826
1827/**
1828 * fc_lport_config() - Configure a fc_lport
1829 * @lport: The local port to be configured
1830 */
1831int fc_lport_config(struct fc_lport *lport)
1832{
1833        INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
1834        mutex_init(&lport->lp_mutex);
1835
1836        fc_lport_state_enter(lport, LPORT_ST_DISABLED);
1837
1838        fc_lport_add_fc4_type(lport, FC_TYPE_FCP);
1839        fc_lport_add_fc4_type(lport, FC_TYPE_CT);
1840        fc_fc4_conf_lport_params(lport, FC_TYPE_FCP);
1841
1842        return 0;
1843}
1844EXPORT_SYMBOL(fc_lport_config);
1845
1846/**
1847 * fc_lport_init() - Initialize the lport layer for a local port
1848 * @lport: The local port to initialize the exchange layer for
1849 */
1850int fc_lport_init(struct fc_lport *lport)
1851{
1852        fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
1853        fc_host_node_name(lport->host) = lport->wwnn;
1854        fc_host_port_name(lport->host) = lport->wwpn;
1855        fc_host_supported_classes(lport->host) = FC_COS_CLASS3;
1856        memset(fc_host_supported_fc4s(lport->host), 0,
1857               sizeof(fc_host_supported_fc4s(lport->host)));
1858        fc_host_supported_fc4s(lport->host)[2] = 1;
1859        fc_host_supported_fc4s(lport->host)[7] = 1;
1860
1861        /* This value is also unchanging */
1862        memset(fc_host_active_fc4s(lport->host), 0,
1863               sizeof(fc_host_active_fc4s(lport->host)));
1864        fc_host_active_fc4s(lport->host)[2] = 1;
1865        fc_host_active_fc4s(lport->host)[7] = 1;
1866        fc_host_maxframe_size(lport->host) = lport->mfs;
1867        fc_host_supported_speeds(lport->host) = 0;
1868        if (lport->link_supported_speeds & FC_PORTSPEED_1GBIT)
1869                fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_1GBIT;
1870        if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
1871                fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
1872        fc_fc4_add_lport(lport);
1873
1874        return 0;
1875}
1876EXPORT_SYMBOL(fc_lport_init);
1877
1878/**
1879 * fc_lport_bsg_resp() - The common response handler for FC Passthrough requests
1880 * @sp:       The sequence for the FC Passthrough response
1881 * @fp:       The response frame
1882 * @info_arg: The BSG info that the response is for
1883 */
1884static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
1885                              void *info_arg)
1886{
1887        struct fc_bsg_info *info = info_arg;
1888        struct bsg_job *job = info->job;
1889        struct fc_bsg_reply *bsg_reply = job->reply;
1890        struct fc_lport *lport = info->lport;
1891        struct fc_frame_header *fh;
1892        size_t len;
1893        void *buf;
1894
1895        if (IS_ERR(fp)) {
1896                bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
1897                        -ECONNABORTED : -ETIMEDOUT;
1898                job->reply_len = sizeof(uint32_t);
1899                bsg_job_done(job, bsg_reply->result,
1900                               bsg_reply->reply_payload_rcv_len);
1901                kfree(info);
1902                return;
1903        }
1904
1905        mutex_lock(&lport->lp_mutex);
1906        fh = fc_frame_header_get(fp);
1907        len = fr_len(fp) - sizeof(*fh);
1908        buf = fc_frame_payload_get(fp, 0);
1909
1910        if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) {
1911                /* Get the response code from the first frame payload */
1912                unsigned short cmd = (info->rsp_code == FC_FS_ACC) ?
1913                        ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) :
1914                        (unsigned short)fc_frame_payload_op(fp);
1915
1916                /* Save the reply status of the job */
1917                bsg_reply->reply_data.ctels_reply.status =
1918                        (cmd == info->rsp_code) ?
1919                        FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
1920        }
1921
1922        bsg_reply->reply_payload_rcv_len +=
1923                fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
1924                                         &info->offset, NULL);
1925
1926        if (fr_eof(fp) == FC_EOF_T &&
1927            (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
1928            (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
1929                if (bsg_reply->reply_payload_rcv_len >
1930                    job->reply_payload.payload_len)
1931                        bsg_reply->reply_payload_rcv_len =
1932                                job->reply_payload.payload_len;
1933                bsg_reply->result = 0;
1934                bsg_job_done(job, bsg_reply->result,
1935                               bsg_reply->reply_payload_rcv_len);
1936                kfree(info);
1937        }
1938        fc_frame_free(fp);
1939        mutex_unlock(&lport->lp_mutex);
1940}
1941
1942/**
1943 * fc_lport_els_request() - Send ELS passthrough request
1944 * @job:   The BSG Passthrough job
1945 * @lport: The local port sending the request
1946 * @did:   The destination port id
1947 */
1948static int fc_lport_els_request(struct bsg_job *job,
1949                                struct fc_lport *lport,
1950                                u32 did, u32 tov)
1951{
1952        struct fc_bsg_info *info;
1953        struct fc_frame *fp;
1954        struct fc_frame_header *fh;
1955        char *pp;
1956        int len;
1957
1958        lockdep_assert_held(&lport->lp_mutex);
1959
1960        fp = fc_frame_alloc(lport, job->request_payload.payload_len);
1961        if (!fp)
1962                return -ENOMEM;
1963
1964        len = job->request_payload.payload_len;
1965        pp = fc_frame_payload_get(fp, len);
1966
1967        sg_copy_to_buffer(job->request_payload.sg_list,
1968                          job->request_payload.sg_cnt,
1969                          pp, len);
1970
1971        fh = fc_frame_header_get(fp);
1972        fh->fh_r_ctl = FC_RCTL_ELS_REQ;
1973        hton24(fh->fh_d_id, did);
1974        hton24(fh->fh_s_id, lport->port_id);
1975        fh->fh_type = FC_TYPE_ELS;
1976        hton24(fh->fh_f_ctl, FC_FCTL_REQ);
1977        fh->fh_cs_ctl = 0;
1978        fh->fh_df_ctl = 0;
1979        fh->fh_parm_offset = 0;
1980
1981        info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
1982        if (!info) {
1983                fc_frame_free(fp);
1984                return -ENOMEM;
1985        }
1986
1987        info->job = job;
1988        info->lport = lport;
1989        info->rsp_code = ELS_LS_ACC;
1990        info->nents = job->reply_payload.sg_cnt;
1991        info->sg = job->reply_payload.sg_list;
1992
1993        if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
1994                              NULL, info, tov)) {
1995                kfree(info);
1996                return -ECOMM;
1997        }
1998        return 0;
1999}
2000
2001/**
2002 * fc_lport_ct_request() - Send CT Passthrough request
2003 * @job:   The BSG Passthrough job
2004 * @lport: The local port sending the request
2005 * @did:   The destination FC-ID
2006 * @tov:   The timeout period to wait for the response
2007 */
2008static int fc_lport_ct_request(struct bsg_job *job,
2009                               struct fc_lport *lport, u32 did, u32 tov)
2010{
2011        struct fc_bsg_info *info;
2012        struct fc_frame *fp;
2013        struct fc_frame_header *fh;
2014        struct fc_ct_req *ct;
2015        size_t len;
2016
2017        lockdep_assert_held(&lport->lp_mutex);
2018
2019        fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
2020                            job->request_payload.payload_len);
2021        if (!fp)
2022                return -ENOMEM;
2023
2024        len = job->request_payload.payload_len;
2025        ct = fc_frame_payload_get(fp, len);
2026
2027        sg_copy_to_buffer(job->request_payload.sg_list,
2028                          job->request_payload.sg_cnt,
2029                          ct, len);
2030
2031        fh = fc_frame_header_get(fp);
2032        fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
2033        hton24(fh->fh_d_id, did);
2034        hton24(fh->fh_s_id, lport->port_id);
2035        fh->fh_type = FC_TYPE_CT;
2036        hton24(fh->fh_f_ctl, FC_FCTL_REQ);
2037        fh->fh_cs_ctl = 0;
2038        fh->fh_df_ctl = 0;
2039        fh->fh_parm_offset = 0;
2040
2041        info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL);
2042        if (!info) {
2043                fc_frame_free(fp);
2044                return -ENOMEM;
2045        }
2046
2047        info->job = job;
2048        info->lport = lport;
2049        info->rsp_code = FC_FS_ACC;
2050        info->nents = job->reply_payload.sg_cnt;
2051        info->sg = job->reply_payload.sg_list;
2052
2053        if (!fc_exch_seq_send(lport, fp, fc_lport_bsg_resp,
2054                              NULL, info, tov)) {
2055                kfree(info);
2056                return -ECOMM;
2057        }
2058        return 0;
2059}
2060
2061/**
2062 * fc_lport_bsg_request() - The common entry point for sending
2063 *                          FC Passthrough requests
2064 * @job: The BSG passthrough job
2065 */
2066int fc_lport_bsg_request(struct bsg_job *job)
2067{
2068        struct fc_bsg_request *bsg_request = job->request;
2069        struct fc_bsg_reply *bsg_reply = job->reply;
2070        struct Scsi_Host *shost = fc_bsg_to_shost(job);
2071        struct fc_lport *lport = shost_priv(shost);
2072        struct fc_rport *rport;
2073        struct fc_rport_priv *rdata;
2074        int rc = -EINVAL;
2075        u32 did, tov;
2076
2077        bsg_reply->reply_payload_rcv_len = 0;
2078
2079        mutex_lock(&lport->lp_mutex);
2080
2081        switch (bsg_request->msgcode) {
2082        case FC_BSG_RPT_ELS:
2083                rport = fc_bsg_to_rport(job);
2084                if (!rport)
2085                        break;
2086
2087                rdata = rport->dd_data;
2088                rc = fc_lport_els_request(job, lport, rport->port_id,
2089                                          rdata->e_d_tov);
2090                break;
2091
2092        case FC_BSG_RPT_CT:
2093                rport = fc_bsg_to_rport(job);
2094                if (!rport)
2095                        break;
2096
2097                rdata = rport->dd_data;
2098                rc = fc_lport_ct_request(job, lport, rport->port_id,
2099                                         rdata->e_d_tov);
2100                break;
2101
2102        case FC_BSG_HST_CT:
2103                did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
2104                if (did == FC_FID_DIR_SERV) {
2105                        rdata = lport->dns_rdata;
2106                        if (!rdata)
2107                                break;
2108                        tov = rdata->e_d_tov;
2109                } else {
2110                        rdata = fc_rport_lookup(lport, did);
2111                        if (!rdata)
2112                                break;
2113                        tov = rdata->e_d_tov;
2114                        kref_put(&rdata->kref, fc_rport_destroy);
2115                }
2116
2117                rc = fc_lport_ct_request(job, lport, did, tov);
2118                break;
2119
2120        case FC_BSG_HST_ELS_NOLOGIN:
2121                did = ntoh24(bsg_request->rqst_data.h_els.port_id);
2122                rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
2123                break;
2124        }
2125
2126        mutex_unlock(&lport->lp_mutex);
2127        return rc;
2128}
2129EXPORT_SYMBOL(fc_lport_bsg_request);
2130