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