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