Showing error 781

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/scsi/scsi_transport_fc.c
Line in file: 3293
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2011-11-07 22:23:48 UTC


Source:

   1/*
   2 *  FiberChannel transport specific attributes exported to sysfs.
   3 *
   4 *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 *
  20 *  ========
  21 *
  22 *  Copyright (C) 2004-2007   James Smart, Emulex Corporation
  23 *    Rewrite for host, target, device, and remote port attributes,
  24 *    statistics, and service functions...
  25 *    Add vports, etc
  26 *
  27 */
  28#include <linux/module.h>
  29#include <linux/init.h>
  30#include <scsi/scsi_device.h>
  31#include <scsi/scsi_host.h>
  32#include <scsi/scsi_transport.h>
  33#include <scsi/scsi_transport_fc.h>
  34#include <scsi/scsi_cmnd.h>
  35#include <linux/netlink.h>
  36#include <net/netlink.h>
  37#include <scsi/scsi_netlink_fc.h>
  38#include "scsi_priv.h"
  39#include "scsi_transport_fc_internal.h"
  40
  41static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
  42static void fc_vport_sched_delete(struct work_struct *work);
  43static int fc_vport_setup(struct Scsi_Host *shost, int channel,
  44        struct device *pdev, struct fc_vport_identifiers  *ids,
  45        struct fc_vport **vport);
  46
  47/*
  48 * Redefine so that we can have same named attributes in the
  49 * sdev/starget/host objects.
  50 */
  51#define FC_DEVICE_ATTR(_prefix,_name,_mode,_show,_store)                \
  52struct device_attribute device_attr_##_prefix##_##_name =         \
  53        __ATTR(_name,_mode,_show,_store)
  54
  55#define fc_enum_name_search(title, table_type, table)                        \
  56static const char *get_fc_##title##_name(enum table_type table_key)        \
  57{                                                                        \
  58        int i;                                                                \
  59        char *name = NULL;                                                \
  60                                                                        \
  61        for (i = 0; i < ARRAY_SIZE(table); i++) {                        \
  62                if (table[i].value == table_key) {                        \
  63                        name = table[i].name;                                \
  64                        break;                                                \
  65                }                                                        \
  66        }                                                                \
  67        return name;                                                        \
  68}
  69
  70#define fc_enum_name_match(title, table_type, table)                        \
  71static int get_fc_##title##_match(const char *table_key,                \
  72                enum table_type *value)                                        \
  73{                                                                        \
  74        int i;                                                                \
  75                                                                        \
  76        for (i = 0; i < ARRAY_SIZE(table); i++) {                        \
  77                if (strncmp(table_key, table[i].name,                        \
  78                                table[i].matchlen) == 0) {                \
  79                        *value = table[i].value;                        \
  80                        return 0; /* success */                                \
  81                }                                                        \
  82        }                                                                \
  83        return 1; /* failure */                                                \
  84}
  85
  86
  87/* Convert fc_port_type values to ascii string name */
  88static struct {
  89        enum fc_port_type        value;
  90        char                        *name;
  91} fc_port_type_names[] = {
  92        { FC_PORTTYPE_UNKNOWN,                "Unknown" },
  93        { FC_PORTTYPE_OTHER,                "Other" },
  94        { FC_PORTTYPE_NOTPRESENT,        "Not Present" },
  95        { FC_PORTTYPE_NPORT,        "NPort (fabric via point-to-point)" },
  96        { FC_PORTTYPE_NLPORT,        "NLPort (fabric via loop)" },
  97        { FC_PORTTYPE_LPORT,        "LPort (private loop)" },
  98        { FC_PORTTYPE_PTP,        "Point-To-Point (direct nport connection" },
  99        { FC_PORTTYPE_NPIV,                "NPIV VPORT" },
 100};
 101fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
 102#define FC_PORTTYPE_MAX_NAMELEN                50
 103
 104/* Reuse fc_port_type enum function for vport_type */
 105#define get_fc_vport_type_name get_fc_port_type_name
 106
 107
 108/* Convert fc_host_event_code values to ascii string name */
 109static const struct {
 110        enum fc_host_event_code                value;
 111        char                                *name;
 112} fc_host_event_code_names[] = {
 113        { FCH_EVT_LIP,                        "lip" },
 114        { FCH_EVT_LINKUP,                "link_up" },
 115        { FCH_EVT_LINKDOWN,                "link_down" },
 116        { FCH_EVT_LIPRESET,                "lip_reset" },
 117        { FCH_EVT_RSCN,                        "rscn" },
 118        { FCH_EVT_ADAPTER_CHANGE,        "adapter_chg" },
 119        { FCH_EVT_PORT_UNKNOWN,                "port_unknown" },
 120        { FCH_EVT_PORT_ONLINE,                "port_online" },
 121        { FCH_EVT_PORT_OFFLINE,                "port_offline" },
 122        { FCH_EVT_PORT_FABRIC,                "port_fabric" },
 123        { FCH_EVT_LINK_UNKNOWN,                "link_unknown" },
 124        { FCH_EVT_VENDOR_UNIQUE,        "vendor_unique" },
 125};
 126fc_enum_name_search(host_event_code, fc_host_event_code,
 127                fc_host_event_code_names)
 128#define FC_HOST_EVENT_CODE_MAX_NAMELEN        30
 129
 130
 131/* Convert fc_port_state values to ascii string name */
 132static struct {
 133        enum fc_port_state        value;
 134        char                        *name;
 135} fc_port_state_names[] = {
 136        { FC_PORTSTATE_UNKNOWN,                "Unknown" },
 137        { FC_PORTSTATE_NOTPRESENT,        "Not Present" },
 138        { FC_PORTSTATE_ONLINE,                "Online" },
 139        { FC_PORTSTATE_OFFLINE,                "Offline" },
 140        { FC_PORTSTATE_BLOCKED,                "Blocked" },
 141        { FC_PORTSTATE_BYPASSED,        "Bypassed" },
 142        { FC_PORTSTATE_DIAGNOSTICS,        "Diagnostics" },
 143        { FC_PORTSTATE_LINKDOWN,        "Linkdown" },
 144        { FC_PORTSTATE_ERROR,                "Error" },
 145        { FC_PORTSTATE_LOOPBACK,        "Loopback" },
 146        { FC_PORTSTATE_DELETED,                "Deleted" },
 147};
 148fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
 149#define FC_PORTSTATE_MAX_NAMELEN        20
 150
 151
 152/* Convert fc_vport_state values to ascii string name */
 153static struct {
 154        enum fc_vport_state        value;
 155        char                        *name;
 156} fc_vport_state_names[] = {
 157        { FC_VPORT_UNKNOWN,                "Unknown" },
 158        { FC_VPORT_ACTIVE,                "Active" },
 159        { FC_VPORT_DISABLED,                "Disabled" },
 160        { FC_VPORT_LINKDOWN,                "Linkdown" },
 161        { FC_VPORT_INITIALIZING,        "Initializing" },
 162        { FC_VPORT_NO_FABRIC_SUPP,        "No Fabric Support" },
 163        { FC_VPORT_NO_FABRIC_RSCS,        "No Fabric Resources" },
 164        { FC_VPORT_FABRIC_LOGOUT,        "Fabric Logout" },
 165        { FC_VPORT_FABRIC_REJ_WWN,        "Fabric Rejected WWN" },
 166        { FC_VPORT_FAILED,                "VPort Failed" },
 167};
 168fc_enum_name_search(vport_state, fc_vport_state, fc_vport_state_names)
 169#define FC_VPORTSTATE_MAX_NAMELEN        24
 170
 171/* Reuse fc_vport_state enum function for vport_last_state */
 172#define get_fc_vport_last_state_name get_fc_vport_state_name
 173
 174
 175/* Convert fc_tgtid_binding_type values to ascii string name */
 176static const struct {
 177        enum fc_tgtid_binding_type        value;
 178        char                                *name;
 179        int                                matchlen;
 180} fc_tgtid_binding_type_names[] = {
 181        { FC_TGTID_BIND_NONE, "none", 4 },
 182        { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 },
 183        { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 },
 184        { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 },
 185};
 186fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type,
 187                fc_tgtid_binding_type_names)
 188fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type,
 189                fc_tgtid_binding_type_names)
 190#define FC_BINDTYPE_MAX_NAMELEN        30
 191
 192
 193#define fc_bitfield_name_search(title, table)                        \
 194static ssize_t                                                        \
 195get_fc_##title##_names(u32 table_key, char *buf)                \
 196{                                                                \
 197        char *prefix = "";                                        \
 198        ssize_t len = 0;                                        \
 199        int i;                                                        \
 200                                                                \
 201        for (i = 0; i < ARRAY_SIZE(table); i++) {                \
 202                if (table[i].value & table_key) {                \
 203                        len += sprintf(buf + len, "%s%s",        \
 204                                prefix, table[i].name);                \
 205                        prefix = ", ";                                \
 206                }                                                \
 207        }                                                        \
 208        len += sprintf(buf + len, "\n");                        \
 209        return len;                                                \
 210}
 211
 212
 213/* Convert FC_COS bit values to ascii string name */
 214static const struct {
 215        u32                         value;
 216        char                        *name;
 217} fc_cos_names[] = {
 218        { FC_COS_CLASS1,        "Class 1" },
 219        { FC_COS_CLASS2,        "Class 2" },
 220        { FC_COS_CLASS3,        "Class 3" },
 221        { FC_COS_CLASS4,        "Class 4" },
 222        { FC_COS_CLASS6,        "Class 6" },
 223};
 224fc_bitfield_name_search(cos, fc_cos_names)
 225
 226
 227/* Convert FC_PORTSPEED bit values to ascii string name */
 228static const struct {
 229        u32                         value;
 230        char                        *name;
 231} fc_port_speed_names[] = {
 232        { FC_PORTSPEED_1GBIT,                "1 Gbit" },
 233        { FC_PORTSPEED_2GBIT,                "2 Gbit" },
 234        { FC_PORTSPEED_4GBIT,                "4 Gbit" },
 235        { FC_PORTSPEED_10GBIT,                "10 Gbit" },
 236        { FC_PORTSPEED_8GBIT,                "8 Gbit" },
 237        { FC_PORTSPEED_16GBIT,                "16 Gbit" },
 238        { FC_PORTSPEED_NOT_NEGOTIATED,        "Not Negotiated" },
 239};
 240fc_bitfield_name_search(port_speed, fc_port_speed_names)
 241
 242
 243static int
 244show_fc_fc4s (char *buf, u8 *fc4_list)
 245{
 246        int i, len=0;
 247
 248        for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++)
 249                len += sprintf(buf + len , "0x%02x ", *fc4_list);
 250        len += sprintf(buf + len, "\n");
 251        return len;
 252}
 253
 254
 255/* Convert FC_PORT_ROLE bit values to ascii string name */
 256static const struct {
 257        u32                         value;
 258        char                        *name;
 259} fc_port_role_names[] = {
 260        { FC_PORT_ROLE_FCP_TARGET,        "FCP Target" },
 261        { FC_PORT_ROLE_FCP_INITIATOR,        "FCP Initiator" },
 262        { FC_PORT_ROLE_IP_PORT,                "IP Port" },
 263};
 264fc_bitfield_name_search(port_roles, fc_port_role_names)
 265
 266/*
 267 * Define roles that are specific to port_id. Values are relative to ROLE_MASK.
 268 */
 269#define FC_WELLKNOWN_PORTID_MASK        0xfffff0
 270#define FC_WELLKNOWN_ROLE_MASK          0x00000f
 271#define FC_FPORT_PORTID                        0x00000e
 272#define FC_FABCTLR_PORTID                0x00000d
 273#define FC_DIRSRVR_PORTID                0x00000c
 274#define FC_TIMESRVR_PORTID                0x00000b
 275#define FC_MGMTSRVR_PORTID                0x00000a
 276
 277
 278static void fc_timeout_deleted_rport(struct work_struct *work);
 279static void fc_timeout_fail_rport_io(struct work_struct *work);
 280static void fc_scsi_scan_rport(struct work_struct *work);
 281
 282/*
 283 * Attribute counts pre object type...
 284 * Increase these values if you add attributes
 285 */
 286#define FC_STARGET_NUM_ATTRS         3
 287#define FC_RPORT_NUM_ATTRS        10
 288#define FC_VPORT_NUM_ATTRS        9
 289#define FC_HOST_NUM_ATTRS        21
 290
 291struct fc_internal {
 292        struct scsi_transport_template t;
 293        struct fc_function_template *f;
 294
 295        /*
 296         * For attributes : each object has :
 297         *   An array of the actual attributes structures
 298         *   An array of null-terminated pointers to the attribute
 299         *     structures - used for mid-layer interaction.
 300         *
 301         * The attribute containers for the starget and host are are
 302         * part of the midlayer. As the remote port is specific to the
 303         * fc transport, we must provide the attribute container.
 304         */
 305        struct device_attribute private_starget_attrs[
 306                                                        FC_STARGET_NUM_ATTRS];
 307        struct device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1];
 308
 309        struct device_attribute private_host_attrs[FC_HOST_NUM_ATTRS];
 310        struct device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1];
 311
 312        struct transport_container rport_attr_cont;
 313        struct device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS];
 314        struct device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1];
 315
 316        struct transport_container vport_attr_cont;
 317        struct device_attribute private_vport_attrs[FC_VPORT_NUM_ATTRS];
 318        struct device_attribute *vport_attrs[FC_VPORT_NUM_ATTRS + 1];
 319};
 320
 321#define to_fc_internal(tmpl)        container_of(tmpl, struct fc_internal, t)
 322
 323static int fc_target_setup(struct transport_container *tc, struct device *dev,
 324                           struct device *cdev)
 325{
 326        struct scsi_target *starget = to_scsi_target(dev);
 327        struct fc_rport *rport = starget_to_rport(starget);
 328
 329        /*
 330         * if parent is remote port, use values from remote port.
 331         * Otherwise, this host uses the fc_transport, but not the
 332         * remote port interface. As such, initialize to known non-values.
 333         */
 334        if (rport) {
 335                fc_starget_node_name(starget) = rport->node_name;
 336                fc_starget_port_name(starget) = rport->port_name;
 337                fc_starget_port_id(starget) = rport->port_id;
 338        } else {
 339                fc_starget_node_name(starget) = -1;
 340                fc_starget_port_name(starget) = -1;
 341                fc_starget_port_id(starget) = -1;
 342        }
 343
 344        return 0;
 345}
 346
 347static DECLARE_TRANSPORT_CLASS(fc_transport_class,
 348                               "fc_transport",
 349                               fc_target_setup,
 350                               NULL,
 351                               NULL);
 352
 353static int fc_host_setup(struct transport_container *tc, struct device *dev,
 354                         struct device *cdev)
 355{
 356        struct Scsi_Host *shost = dev_to_shost(dev);
 357        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
 358
 359        /*
 360         * Set default values easily detected by the midlayer as
 361         * failure cases.  The scsi lldd is responsible for initializing
 362         * all transport attributes to valid values per host.
 363         */
 364        fc_host->node_name = -1;
 365        fc_host->port_name = -1;
 366        fc_host->permanent_port_name = -1;
 367        fc_host->supported_classes = FC_COS_UNSPECIFIED;
 368        memset(fc_host->supported_fc4s, 0,
 369                sizeof(fc_host->supported_fc4s));
 370        fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN;
 371        fc_host->maxframe_size = -1;
 372        fc_host->max_npiv_vports = 0;
 373        memset(fc_host->serial_number, 0,
 374                sizeof(fc_host->serial_number));
 375
 376        fc_host->port_id = -1;
 377        fc_host->port_type = FC_PORTTYPE_UNKNOWN;
 378        fc_host->port_state = FC_PORTSTATE_UNKNOWN;
 379        memset(fc_host->active_fc4s, 0,
 380                sizeof(fc_host->active_fc4s));
 381        fc_host->speed = FC_PORTSPEED_UNKNOWN;
 382        fc_host->fabric_name = -1;
 383        memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name));
 384        memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname));
 385
 386        fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
 387
 388        INIT_LIST_HEAD(&fc_host->rports);
 389        INIT_LIST_HEAD(&fc_host->rport_bindings);
 390        INIT_LIST_HEAD(&fc_host->vports);
 391        fc_host->next_rport_number = 0;
 392        fc_host->next_target_id = 0;
 393        fc_host->next_vport_number = 0;
 394        fc_host->npiv_vports_inuse = 0;
 395
 396        snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
 397                 "fc_wq_%d", shost->host_no);
 398        fc_host->work_q = create_singlethread_workqueue(
 399                                        fc_host->work_q_name);
 400        if (!fc_host->work_q)
 401                return -ENOMEM;
 402
 403        snprintf(fc_host->devloss_work_q_name,
 404                 sizeof(fc_host->devloss_work_q_name),
 405                 "fc_dl_%d", shost->host_no);
 406        fc_host->devloss_work_q = create_singlethread_workqueue(
 407                                        fc_host->devloss_work_q_name);
 408        if (!fc_host->devloss_work_q) {
 409                destroy_workqueue(fc_host->work_q);
 410                fc_host->work_q = NULL;
 411                return -ENOMEM;
 412        }
 413
 414        return 0;
 415}
 416
 417static DECLARE_TRANSPORT_CLASS(fc_host_class,
 418                               "fc_host",
 419                               fc_host_setup,
 420                               NULL,
 421                               NULL);
 422
 423/*
 424 * Setup and Remove actions for remote ports are handled
 425 * in the service functions below.
 426 */
 427static DECLARE_TRANSPORT_CLASS(fc_rport_class,
 428                               "fc_remote_ports",
 429                               NULL,
 430                               NULL,
 431                               NULL);
 432
 433/*
 434 * Setup and Remove actions for virtual ports are handled
 435 * in the service functions below.
 436 */
 437static DECLARE_TRANSPORT_CLASS(fc_vport_class,
 438                               "fc_vports",
 439                               NULL,
 440                               NULL,
 441                               NULL);
 442
 443/*
 444 * Module Parameters
 445 */
 446
 447/*
 448 * dev_loss_tmo: the default number of seconds that the FC transport
 449 *   should insulate the loss of a remote port.
 450 *   The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
 451 */
 452static unsigned int fc_dev_loss_tmo = 60;                /* seconds */
 453
 454module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
 455MODULE_PARM_DESC(dev_loss_tmo,
 456                 "Maximum number of seconds that the FC transport should"
 457                 " insulate the loss of a remote port. Once this value is"
 458                 " exceeded, the scsi target is removed. Value should be"
 459                 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT.");
 460
 461/*
 462 * Netlink Infrastructure
 463 */
 464
 465static atomic_t fc_event_seq;
 466
 467/**
 468 * fc_get_event_number - Obtain the next sequential FC event number
 469 *
 470 * Notes:
 471 *   We could have inlined this, but it would have required fc_event_seq to
 472 *   be exposed. For now, live with the subroutine call.
 473 *   Atomic used to avoid lock/unlock...
 474 */
 475u32
 476fc_get_event_number(void)
 477{
 478        return atomic_add_return(1, &fc_event_seq);
 479}
 480EXPORT_SYMBOL(fc_get_event_number);
 481
 482
 483/**
 484 * fc_host_post_event - called to post an even on an fc_host.
 485 * @shost:                host the event occurred on
 486 * @event_number:        fc event number obtained from get_fc_event_number()
 487 * @event_code:                fc_host event being posted
 488 * @event_data:                32bits of data for the event being posted
 489 *
 490 * Notes:
 491 *        This routine assumes no locks are held on entry.
 492 */
 493void
 494fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
 495                enum fc_host_event_code event_code, u32 event_data)
 496{
 497        struct sk_buff *skb;
 498        struct nlmsghdr        *nlh;
 499        struct fc_nl_event *event;
 500        const char *name;
 501        u32 len, skblen;
 502        int err;
 503
 504        if (!scsi_nl_sock) {
 505                err = -ENOENT;
 506                goto send_fail;
 507        }
 508
 509        len = FC_NL_MSGALIGN(sizeof(*event));
 510        skblen = NLMSG_SPACE(len);
 511
 512        skb = alloc_skb(skblen, GFP_KERNEL);
 513        if (!skb) {
 514                err = -ENOBUFS;
 515                goto send_fail;
 516        }
 517
 518        nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
 519                                skblen - sizeof(*nlh), 0);
 520        if (!nlh) {
 521                err = -ENOBUFS;
 522                goto send_fail_skb;
 523        }
 524        event = NLMSG_DATA(nlh);
 525
 526        INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
 527                                FC_NL_ASYNC_EVENT, len);
 528        event->seconds = get_seconds();
 529        event->vendor_id = 0;
 530        event->host_no = shost->host_no;
 531        event->event_datalen = sizeof(u32);        /* bytes */
 532        event->event_num = event_number;
 533        event->event_code = event_code;
 534        event->event_data = event_data;
 535
 536        err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
 537                              GFP_KERNEL);
 538        if (err && (err != -ESRCH))        /* filter no recipient errors */
 539                /* nlmsg_multicast already kfree_skb'd */
 540                goto send_fail;
 541
 542        return;
 543
 544send_fail_skb:
 545        kfree_skb(skb);
 546send_fail:
 547        name = get_fc_host_event_code_name(event_code);
 548        printk(KERN_WARNING
 549                "%s: Dropped Event : host %d %s data 0x%08x - err %d\n",
 550                __func__, shost->host_no,
 551                (name) ? name : "<unknown>", event_data, err);
 552        return;
 553}
 554EXPORT_SYMBOL(fc_host_post_event);
 555
 556
 557/**
 558 * fc_host_post_vendor_event - called to post a vendor unique event on an fc_host
 559 * @shost:                host the event occurred on
 560 * @event_number:        fc event number obtained from get_fc_event_number()
 561 * @data_len:                amount, in bytes, of vendor unique data
 562 * @data_buf:                pointer to vendor unique data
 563 * @vendor_id:          Vendor id
 564 *
 565 * Notes:
 566 *        This routine assumes no locks are held on entry.
 567 */
 568void
 569fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
 570                u32 data_len, char * data_buf, u64 vendor_id)
 571{
 572        struct sk_buff *skb;
 573        struct nlmsghdr        *nlh;
 574        struct fc_nl_event *event;
 575        u32 len, skblen;
 576        int err;
 577
 578        if (!scsi_nl_sock) {
 579                err = -ENOENT;
 580                goto send_vendor_fail;
 581        }
 582
 583        len = FC_NL_MSGALIGN(sizeof(*event) + data_len);
 584        skblen = NLMSG_SPACE(len);
 585
 586        skb = alloc_skb(skblen, GFP_KERNEL);
 587        if (!skb) {
 588                err = -ENOBUFS;
 589                goto send_vendor_fail;
 590        }
 591
 592        nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
 593                                skblen - sizeof(*nlh), 0);
 594        if (!nlh) {
 595                err = -ENOBUFS;
 596                goto send_vendor_fail_skb;
 597        }
 598        event = NLMSG_DATA(nlh);
 599
 600        INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
 601                                FC_NL_ASYNC_EVENT, len);
 602        event->seconds = get_seconds();
 603        event->vendor_id = vendor_id;
 604        event->host_no = shost->host_no;
 605        event->event_datalen = data_len;        /* bytes */
 606        event->event_num = event_number;
 607        event->event_code = FCH_EVT_VENDOR_UNIQUE;
 608        memcpy(&event->event_data, data_buf, data_len);
 609
 610        err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
 611                              GFP_KERNEL);
 612        if (err && (err != -ESRCH))        /* filter no recipient errors */
 613                /* nlmsg_multicast already kfree_skb'd */
 614                goto send_vendor_fail;
 615
 616        return;
 617
 618send_vendor_fail_skb:
 619        kfree_skb(skb);
 620send_vendor_fail:
 621        printk(KERN_WARNING
 622                "%s: Dropped Event : host %d vendor_unique - err %d\n",
 623                __func__, shost->host_no, err);
 624        return;
 625}
 626EXPORT_SYMBOL(fc_host_post_vendor_event);
 627
 628
 629
 630static __init int fc_transport_init(void)
 631{
 632        int error;
 633
 634        atomic_set(&fc_event_seq, 0);
 635
 636        error = transport_class_register(&fc_host_class);
 637        if (error)
 638                return error;
 639        error = transport_class_register(&fc_vport_class);
 640        if (error)
 641                return error;
 642        error = transport_class_register(&fc_rport_class);
 643        if (error)
 644                return error;
 645        return transport_class_register(&fc_transport_class);
 646}
 647
 648static void __exit fc_transport_exit(void)
 649{
 650        transport_class_unregister(&fc_transport_class);
 651        transport_class_unregister(&fc_rport_class);
 652        transport_class_unregister(&fc_host_class);
 653        transport_class_unregister(&fc_vport_class);
 654}
 655
 656/*
 657 * FC Remote Port Attribute Management
 658 */
 659
 660#define fc_rport_show_function(field, format_string, sz, cast)                \
 661static ssize_t                                                                \
 662show_fc_rport_##field (struct device *dev,                                 \
 663                       struct device_attribute *attr, char *buf)        \
 664{                                                                        \
 665        struct fc_rport *rport = transport_class_to_rport(dev);                \
 666        struct Scsi_Host *shost = rport_to_shost(rport);                \
 667        struct fc_internal *i = to_fc_internal(shost->transportt);        \
 668        if ((i->f->get_rport_##field) &&                                \
 669            !((rport->port_state == FC_PORTSTATE_BLOCKED) ||                \
 670              (rport->port_state == FC_PORTSTATE_DELETED) ||                \
 671              (rport->port_state == FC_PORTSTATE_NOTPRESENT)))                \
 672                i->f->get_rport_##field(rport);                                \
 673        return snprintf(buf, sz, format_string, cast rport->field);         \
 674}
 675
 676#define fc_rport_store_function(field)                                        \
 677static ssize_t                                                                \
 678store_fc_rport_##field(struct device *dev,                                \
 679                       struct device_attribute *attr,                        \
 680                       const char *buf,        size_t count)                        \
 681{                                                                        \
 682        int val;                                                        \
 683        struct fc_rport *rport = transport_class_to_rport(dev);                \
 684        struct Scsi_Host *shost = rport_to_shost(rport);                \
 685        struct fc_internal *i = to_fc_internal(shost->transportt);        \
 686        char *cp;                                                        \
 687        if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||                \
 688            (rport->port_state == FC_PORTSTATE_DELETED) ||                \
 689            (rport->port_state == FC_PORTSTATE_NOTPRESENT))                \
 690                return -EBUSY;                                                \
 691        val = simple_strtoul(buf, &cp, 0);                                \
 692        if (*cp && (*cp != '\n'))                                        \
 693                return -EINVAL;                                                \
 694        i->f->set_rport_##field(rport, val);                                \
 695        return count;                                                        \
 696}
 697
 698#define fc_rport_rd_attr(field, format_string, sz)                        \
 699        fc_rport_show_function(field, format_string, sz, )                \
 700static FC_DEVICE_ATTR(rport, field, S_IRUGO,                        \
 701                         show_fc_rport_##field, NULL)
 702
 703#define fc_rport_rd_attr_cast(field, format_string, sz, cast)                \
 704        fc_rport_show_function(field, format_string, sz, (cast))        \
 705static FC_DEVICE_ATTR(rport, field, S_IRUGO,                        \
 706                          show_fc_rport_##field, NULL)
 707
 708#define fc_rport_rw_attr(field, format_string, sz)                        \
 709        fc_rport_show_function(field, format_string, sz, )                \
 710        fc_rport_store_function(field)                                        \
 711static FC_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR,                \
 712                        show_fc_rport_##field,                                \
 713                        store_fc_rport_##field)
 714
 715
 716#define fc_private_rport_show_function(field, format_string, sz, cast)        \
 717static ssize_t                                                                \
 718show_fc_rport_##field (struct device *dev,                                 \
 719                       struct device_attribute *attr, char *buf)        \
 720{                                                                        \
 721        struct fc_rport *rport = transport_class_to_rport(dev);                \
 722        return snprintf(buf, sz, format_string, cast rport->field);         \
 723}
 724
 725#define fc_private_rport_rd_attr(field, format_string, sz)                \
 726        fc_private_rport_show_function(field, format_string, sz, )        \
 727static FC_DEVICE_ATTR(rport, field, S_IRUGO,                        \
 728                         show_fc_rport_##field, NULL)
 729
 730#define fc_private_rport_rd_attr_cast(field, format_string, sz, cast)        \
 731        fc_private_rport_show_function(field, format_string, sz, (cast)) \
 732static FC_DEVICE_ATTR(rport, field, S_IRUGO,                        \
 733                          show_fc_rport_##field, NULL)
 734
 735
 736#define fc_private_rport_rd_enum_attr(title, maxlen)                        \
 737static ssize_t                                                                \
 738show_fc_rport_##title (struct device *dev,                                \
 739                       struct device_attribute *attr, char *buf)        \
 740{                                                                        \
 741        struct fc_rport *rport = transport_class_to_rport(dev);                \
 742        const char *name;                                                \
 743        name = get_fc_##title##_name(rport->title);                        \
 744        if (!name)                                                        \
 745                return -EINVAL;                                                \
 746        return snprintf(buf, maxlen, "%s\n", name);                        \
 747}                                                                        \
 748static FC_DEVICE_ATTR(rport, title, S_IRUGO,                        \
 749                        show_fc_rport_##title, NULL)
 750
 751
 752#define SETUP_RPORT_ATTRIBUTE_RD(field)                                        \
 753        i->private_rport_attrs[count] = device_attr_rport_##field; \
 754        i->private_rport_attrs[count].attr.mode = S_IRUGO;                \
 755        i->private_rport_attrs[count].store = NULL;                        \
 756        i->rport_attrs[count] = &i->private_rport_attrs[count];                \
 757        if (i->f->show_rport_##field)                                        \
 758                count++
 759
 760#define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field)                                \
 761        i->private_rport_attrs[count] = device_attr_rport_##field; \
 762        i->private_rport_attrs[count].attr.mode = S_IRUGO;                \
 763        i->private_rport_attrs[count].store = NULL;                        \
 764        i->rport_attrs[count] = &i->private_rport_attrs[count];                \
 765        count++
 766
 767#define SETUP_RPORT_ATTRIBUTE_RW(field)                                        \
 768        i->private_rport_attrs[count] = device_attr_rport_##field; \
 769        if (!i->f->set_rport_##field) {                                        \
 770                i->private_rport_attrs[count].attr.mode = S_IRUGO;        \
 771                i->private_rport_attrs[count].store = NULL;                \
 772        }                                                                \
 773        i->rport_attrs[count] = &i->private_rport_attrs[count];                \
 774        if (i->f->show_rport_##field)                                        \
 775                count++
 776
 777#define SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(field)                                \
 778{                                                                        \
 779        i->private_rport_attrs[count] = device_attr_rport_##field; \
 780        i->rport_attrs[count] = &i->private_rport_attrs[count];                \
 781        count++;                                                        \
 782}
 783
 784
 785/* The FC Transport Remote Port Attributes: */
 786
 787/* Fixed Remote Port Attributes */
 788
 789fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20);
 790
 791static ssize_t
 792show_fc_rport_supported_classes (struct device *dev,
 793                                 struct device_attribute *attr, char *buf)
 794{
 795        struct fc_rport *rport = transport_class_to_rport(dev);
 796        if (rport->supported_classes == FC_COS_UNSPECIFIED)
 797                return snprintf(buf, 20, "unspecified\n");
 798        return get_fc_cos_names(rport->supported_classes, buf);
 799}
 800static FC_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
 801                show_fc_rport_supported_classes, NULL);
 802
 803/* Dynamic Remote Port Attributes */
 804
 805/*
 806 * dev_loss_tmo attribute
 807 */
 808fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
 809static ssize_t
 810store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
 811                            const char *buf, size_t count)
 812{
 813        int val;
 814        struct fc_rport *rport = transport_class_to_rport(dev);
 815        struct Scsi_Host *shost = rport_to_shost(rport);
 816        struct fc_internal *i = to_fc_internal(shost->transportt);
 817        char *cp;
 818        if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
 819            (rport->port_state == FC_PORTSTATE_DELETED) ||
 820            (rport->port_state == FC_PORTSTATE_NOTPRESENT))
 821                return -EBUSY;
 822        val = simple_strtoul(buf, &cp, 0);
 823        if ((*cp && (*cp != '\n')) ||
 824            (val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
 825                return -EINVAL;
 826        i->f->set_rport_dev_loss_tmo(rport, val);
 827        return count;
 828}
 829static FC_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
 830                show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
 831
 832
 833/* Private Remote Port Attributes */
 834
 835fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
 836fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
 837fc_private_rport_rd_attr(port_id, "0x%06x\n", 20);
 838
 839static ssize_t
 840show_fc_rport_roles (struct device *dev, struct device_attribute *attr,
 841                     char *buf)
 842{
 843        struct fc_rport *rport = transport_class_to_rport(dev);
 844
 845        /* identify any roles that are port_id specific */
 846        if ((rport->port_id != -1) &&
 847            (rport->port_id & FC_WELLKNOWN_PORTID_MASK) ==
 848                                        FC_WELLKNOWN_PORTID_MASK) {
 849                switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) {
 850                case FC_FPORT_PORTID:
 851                        return snprintf(buf, 30, "Fabric Port\n");
 852                case FC_FABCTLR_PORTID:
 853                        return snprintf(buf, 30, "Fabric Controller\n");
 854                case FC_DIRSRVR_PORTID:
 855                        return snprintf(buf, 30, "Directory Server\n");
 856                case FC_TIMESRVR_PORTID:
 857                        return snprintf(buf, 30, "Time Server\n");
 858                case FC_MGMTSRVR_PORTID:
 859                        return snprintf(buf, 30, "Management Server\n");
 860                default:
 861                        return snprintf(buf, 30, "Unknown Fabric Entity\n");
 862                }
 863        } else {
 864                if (rport->roles == FC_PORT_ROLE_UNKNOWN)
 865                        return snprintf(buf, 20, "unknown\n");
 866                return get_fc_port_roles_names(rport->roles, buf);
 867        }
 868}
 869static FC_DEVICE_ATTR(rport, roles, S_IRUGO,
 870                show_fc_rport_roles, NULL);
 871
 872fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
 873fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20);
 874
 875/*
 876 * fast_io_fail_tmo attribute
 877 */
 878static ssize_t
 879show_fc_rport_fast_io_fail_tmo (struct device *dev,
 880                                struct device_attribute *attr, char *buf)
 881{
 882        struct fc_rport *rport = transport_class_to_rport(dev);
 883
 884        if (rport->fast_io_fail_tmo == -1)
 885                return snprintf(buf, 5, "off\n");
 886        return snprintf(buf, 20, "%d\n", rport->fast_io_fail_tmo);
 887}
 888
 889static ssize_t
 890store_fc_rport_fast_io_fail_tmo(struct device *dev,
 891                                struct device_attribute *attr, const char *buf,
 892                                size_t count)
 893{
 894        int val;
 895        char *cp;
 896        struct fc_rport *rport = transport_class_to_rport(dev);
 897
 898        if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
 899            (rport->port_state == FC_PORTSTATE_DELETED) ||
 900            (rport->port_state == FC_PORTSTATE_NOTPRESENT))
 901                return -EBUSY;
 902        if (strncmp(buf, "off", 3) == 0)
 903                rport->fast_io_fail_tmo = -1;
 904        else {
 905                val = simple_strtoul(buf, &cp, 0);
 906                if ((*cp && (*cp != '\n')) ||
 907                    (val < 0) || (val >= rport->dev_loss_tmo))
 908                        return -EINVAL;
 909                rport->fast_io_fail_tmo = val;
 910        }
 911        return count;
 912}
 913static FC_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR,
 914        show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo);
 915
 916
 917/*
 918 * FC SCSI Target Attribute Management
 919 */
 920
 921/*
 922 * Note: in the target show function we recognize when the remote
 923 *  port is in the heirarchy and do not allow the driver to get
 924 *  involved in sysfs functions. The driver only gets involved if
 925 *  it's the "old" style that doesn't use rports.
 926 */
 927#define fc_starget_show_function(field, format_string, sz, cast)        \
 928static ssize_t                                                                \
 929show_fc_starget_##field (struct device *dev,                                 \
 930                         struct device_attribute *attr, char *buf)        \
 931{                                                                        \
 932        struct scsi_target *starget = transport_class_to_starget(dev);        \
 933        struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);        \
 934        struct fc_internal *i = to_fc_internal(shost->transportt);        \
 935        struct fc_rport *rport = starget_to_rport(starget);                \
 936        if (rport)                                                        \
 937                fc_starget_##field(starget) = rport->field;                \
 938        else if (i->f->get_starget_##field)                                \
 939                i->f->get_starget_##field(starget);                        \
 940        return snprintf(buf, sz, format_string,                         \
 941                cast fc_starget_##field(starget));                         \
 942}
 943
 944#define fc_starget_rd_attr(field, format_string, sz)                        \
 945        fc_starget_show_function(field, format_string, sz, )                \
 946static FC_DEVICE_ATTR(starget, field, S_IRUGO,                        \
 947                         show_fc_starget_##field, NULL)
 948
 949#define fc_starget_rd_attr_cast(field, format_string, sz, cast)                \
 950        fc_starget_show_function(field, format_string, sz, (cast))        \
 951static FC_DEVICE_ATTR(starget, field, S_IRUGO,                        \
 952                          show_fc_starget_##field, NULL)
 953
 954#define SETUP_STARGET_ATTRIBUTE_RD(field)                                \
 955        i->private_starget_attrs[count] = device_attr_starget_##field; \
 956        i->private_starget_attrs[count].attr.mode = S_IRUGO;                \
 957        i->private_starget_attrs[count].store = NULL;                        \
 958        i->starget_attrs[count] = &i->private_starget_attrs[count];        \
 959        if (i->f->show_starget_##field)                                        \
 960                count++
 961
 962#define SETUP_STARGET_ATTRIBUTE_RW(field)                                \
 963        i->private_starget_attrs[count] = device_attr_starget_##field; \
 964        if (!i->f->set_starget_##field) {                                \
 965                i->private_starget_attrs[count].attr.mode = S_IRUGO;        \
 966                i->private_starget_attrs[count].store = NULL;                \
 967        }                                                                \
 968        i->starget_attrs[count] = &i->private_starget_attrs[count];        \
 969        if (i->f->show_starget_##field)                                        \
 970                count++
 971
 972/* The FC Transport SCSI Target Attributes: */
 973fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
 974fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
 975fc_starget_rd_attr(port_id, "0x%06x\n", 20);
 976
 977
 978/*
 979 * FC Virtual Port Attribute Management
 980 */
 981
 982#define fc_vport_show_function(field, format_string, sz, cast)                \
 983static ssize_t                                                                \
 984show_fc_vport_##field (struct device *dev,                                 \
 985                       struct device_attribute *attr, char *buf)        \
 986{                                                                        \
 987        struct fc_vport *vport = transport_class_to_vport(dev);                \
 988        struct Scsi_Host *shost = vport_to_shost(vport);                \
 989        struct fc_internal *i = to_fc_internal(shost->transportt);        \
 990        if ((i->f->get_vport_##field) &&                                \
 991            !(vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)))        \
 992                i->f->get_vport_##field(vport);                                \
 993        return snprintf(buf, sz, format_string, cast vport->field);         \
 994}
 995
 996#define fc_vport_store_function(field)                                        \
 997static ssize_t                                                                \
 998store_fc_vport_##field(struct device *dev,                                \
 999                       struct device_attribute *attr,                        \
1000                       const char *buf,        size_t count)                        \
1001{                                                                        \
1002        int val;                                                        \
1003        struct fc_vport *vport = transport_class_to_vport(dev);                \
1004        struct Scsi_Host *shost = vport_to_shost(vport);                \
1005        struct fc_internal *i = to_fc_internal(shost->transportt);        \
1006        char *cp;                                                        \
1007        if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))        \
1008                return -EBUSY;                                                \
1009        val = simple_strtoul(buf, &cp, 0);                                \
1010        if (*cp && (*cp != '\n'))                                        \
1011                return -EINVAL;                                                \
1012        i->f->set_vport_##field(vport, val);                                \
1013        return count;                                                        \
1014}
1015
1016#define fc_vport_store_str_function(field, slen)                        \
1017static ssize_t                                                                \
1018store_fc_vport_##field(struct device *dev,                                \
1019                       struct device_attribute *attr,                         \
1020                       const char *buf,        size_t count)                        \
1021{                                                                        \
1022        struct fc_vport *vport = transport_class_to_vport(dev);                \
1023        struct Scsi_Host *shost = vport_to_shost(vport);                \
1024        struct fc_internal *i = to_fc_internal(shost->transportt);        \
1025        unsigned int cnt=count;                                                \
1026                                                                        \
1027        /* count may include a LF at end of string */                        \
1028        if (buf[cnt-1] == '\n')                                                \
1029                cnt--;                                                        \
1030        if (cnt > ((slen) - 1))                                                \
1031                return -EINVAL;                                                \
1032        memcpy(vport->field, buf, cnt);                                        \
1033        i->f->set_vport_##field(vport);                                        \
1034        return count;                                                        \
1035}
1036
1037#define fc_vport_rd_attr(field, format_string, sz)                        \
1038        fc_vport_show_function(field, format_string, sz, )                \
1039static FC_DEVICE_ATTR(vport, field, S_IRUGO,                        \
1040                         show_fc_vport_##field, NULL)
1041
1042#define fc_vport_rd_attr_cast(field, format_string, sz, cast)                \
1043        fc_vport_show_function(field, format_string, sz, (cast))        \
1044static FC_DEVICE_ATTR(vport, field, S_IRUGO,                        \
1045                          show_fc_vport_##field, NULL)
1046
1047#define fc_vport_rw_attr(field, format_string, sz)                        \
1048        fc_vport_show_function(field, format_string, sz, )                \
1049        fc_vport_store_function(field)                                        \
1050static FC_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR,                \
1051                        show_fc_vport_##field,                                \
1052                        store_fc_vport_##field)
1053
1054#define fc_private_vport_show_function(field, format_string, sz, cast)        \
1055static ssize_t                                                                \
1056show_fc_vport_##field (struct device *dev,                                \
1057                       struct device_attribute *attr, char *buf)        \
1058{                                                                        \
1059        struct fc_vport *vport = transport_class_to_vport(dev);                \
1060        return snprintf(buf, sz, format_string, cast vport->field);         \
1061}
1062
1063#define fc_private_vport_store_u32_function(field)                        \
1064static ssize_t                                                                \
1065store_fc_vport_##field(struct device *dev,                                \
1066                       struct device_attribute *attr,                        \
1067                       const char *buf,        size_t count)                        \
1068{                                                                        \
1069        u32 val;                                                        \
1070        struct fc_vport *vport = transport_class_to_vport(dev);                \
1071        char *cp;                                                        \
1072        if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))                \
1073                return -EBUSY;                                                \
1074        val = simple_strtoul(buf, &cp, 0);                                \
1075        if (*cp && (*cp != '\n'))                                        \
1076                return -EINVAL;                                                \
1077        vport->field = val;                                                \
1078        return count;                                                        \
1079}
1080
1081
1082#define fc_private_vport_rd_attr(field, format_string, sz)                \
1083        fc_private_vport_show_function(field, format_string, sz, )        \
1084static FC_DEVICE_ATTR(vport, field, S_IRUGO,                        \
1085                         show_fc_vport_##field, NULL)
1086
1087#define fc_private_vport_rd_attr_cast(field, format_string, sz, cast)        \
1088        fc_private_vport_show_function(field, format_string, sz, (cast)) \
1089static FC_DEVICE_ATTR(vport, field, S_IRUGO,                        \
1090                          show_fc_vport_##field, NULL)
1091
1092#define fc_private_vport_rw_u32_attr(field, format_string, sz)                \
1093        fc_private_vport_show_function(field, format_string, sz, )        \
1094        fc_private_vport_store_u32_function(field)                        \
1095static FC_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR,                \
1096                        show_fc_vport_##field,                                \
1097                        store_fc_vport_##field)
1098
1099
1100#define fc_private_vport_rd_enum_attr(title, maxlen)                        \
1101static ssize_t                                                                \
1102show_fc_vport_##title (struct device *dev,                                \
1103                       struct device_attribute *attr,                        \
1104                       char *buf)                                        \
1105{                                                                        \
1106        struct fc_vport *vport = transport_class_to_vport(dev);                \
1107        const char *name;                                                \
1108        name = get_fc_##title##_name(vport->title);                        \
1109        if (!name)                                                        \
1110                return -EINVAL;                                                \
1111        return snprintf(buf, maxlen, "%s\n", name);                        \
1112}                                                                        \
1113static FC_DEVICE_ATTR(vport, title, S_IRUGO,                        \
1114                        show_fc_vport_##title, NULL)
1115
1116
1117#define SETUP_VPORT_ATTRIBUTE_RD(field)                                        \
1118        i->private_vport_attrs[count] = device_attr_vport_##field; \
1119        i->private_vport_attrs[count].attr.mode = S_IRUGO;                \
1120        i->private_vport_attrs[count].store = NULL;                        \
1121        i->vport_attrs[count] = &i->private_vport_attrs[count];                \
1122        if (i->f->get_##field)                                                \
1123                count++
1124        /* NOTE: Above MACRO differs: checks function not show bit */
1125
1126#define SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(field)                                \
1127        i->private_vport_attrs[count] = device_attr_vport_##field; \
1128        i->private_vport_attrs[count].attr.mode = S_IRUGO;                \
1129        i->private_vport_attrs[count].store = NULL;                        \
1130        i->vport_attrs[count] = &i->private_vport_attrs[count];                \
1131        count++
1132
1133#define SETUP_VPORT_ATTRIBUTE_WR(field)                                        \
1134        i->private_vport_attrs[count] = device_attr_vport_##field; \
1135        i->vport_attrs[count] = &i->private_vport_attrs[count];                \
1136        if (i->f->field)                                                \
1137                count++
1138        /* NOTE: Above MACRO differs: checks function */
1139
1140#define SETUP_VPORT_ATTRIBUTE_RW(field)                                        \
1141        i->private_vport_attrs[count] = device_attr_vport_##field; \
1142        if (!i->f->set_vport_##field) {                                        \
1143                i->private_vport_attrs[count].attr.mode = S_IRUGO;        \
1144                i->private_vport_attrs[count].store = NULL;                \
1145        }                                                                \
1146        i->vport_attrs[count] = &i->private_vport_attrs[count];                \
1147        count++
1148        /* NOTE: Above MACRO differs: does not check show bit */
1149
1150#define SETUP_PRIVATE_VPORT_ATTRIBUTE_RW(field)                                \
1151{                                                                        \
1152        i->private_vport_attrs[count] = device_attr_vport_##field; \
1153        i->vport_attrs[count] = &i->private_vport_attrs[count];                \
1154        count++;                                                        \
1155}
1156
1157
1158/* The FC Transport Virtual Port Attributes: */
1159
1160/* Fixed Virtual Port Attributes */
1161
1162/* Dynamic Virtual Port Attributes */
1163
1164/* Private Virtual Port Attributes */
1165
1166fc_private_vport_rd_enum_attr(vport_state, FC_VPORTSTATE_MAX_NAMELEN);
1167fc_private_vport_rd_enum_attr(vport_last_state, FC_VPORTSTATE_MAX_NAMELEN);
1168fc_private_vport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
1169fc_private_vport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
1170
1171static ssize_t
1172show_fc_vport_roles (struct device *dev, struct device_attribute *attr,
1173                     char *buf)
1174{
1175        struct fc_vport *vport = transport_class_to_vport(dev);
1176
1177        if (vport->roles == FC_PORT_ROLE_UNKNOWN)
1178                return snprintf(buf, 20, "unknown\n");
1179        return get_fc_port_roles_names(vport->roles, buf);
1180}
1181static FC_DEVICE_ATTR(vport, roles, S_IRUGO, show_fc_vport_roles, NULL);
1182
1183fc_private_vport_rd_enum_attr(vport_type, FC_PORTTYPE_MAX_NAMELEN);
1184
1185fc_private_vport_show_function(symbolic_name, "%s\n",
1186                FC_VPORT_SYMBOLIC_NAMELEN + 1, )
1187fc_vport_store_str_function(symbolic_name, FC_VPORT_SYMBOLIC_NAMELEN)
1188static FC_DEVICE_ATTR(vport, symbolic_name, S_IRUGO | S_IWUSR,
1189                show_fc_vport_symbolic_name, store_fc_vport_symbolic_name);
1190
1191static ssize_t
1192store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
1193                      const char *buf, size_t count)
1194{
1195        struct fc_vport *vport = transport_class_to_vport(dev);
1196        struct Scsi_Host *shost = vport_to_shost(vport);
1197
1198        fc_queue_work(shost, &vport->vport_delete_work);
1199        return count;
1200}
1201static FC_DEVICE_ATTR(vport, vport_delete, S_IWUSR,
1202                        NULL, store_fc_vport_delete);
1203
1204
1205/*
1206 * Enable/Disable vport
1207 *  Write "1" to disable, write "0" to enable
1208 */
1209static ssize_t
1210store_fc_vport_disable(struct device *dev, struct device_attribute *attr,
1211                       const char *buf,
1212                           size_t count)
1213{
1214        struct fc_vport *vport = transport_class_to_vport(dev);
1215        struct Scsi_Host *shost = vport_to_shost(vport);
1216        struct fc_internal *i = to_fc_internal(shost->transportt);
1217        int stat;
1218
1219        if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
1220                return -EBUSY;
1221
1222        if (*buf == '0') {
1223                if (vport->vport_state != FC_VPORT_DISABLED)
1224                        return -EALREADY;
1225        } else if (*buf == '1') {
1226                if (vport->vport_state == FC_VPORT_DISABLED)
1227                        return -EALREADY;
1228        } else
1229                return -EINVAL;
1230
1231        stat = i->f->vport_disable(vport, ((*buf == '0') ? false : true));
1232        return stat ? stat : count;
1233}
1234static FC_DEVICE_ATTR(vport, vport_disable, S_IWUSR,
1235                        NULL, store_fc_vport_disable);
1236
1237
1238/*
1239 * Host Attribute Management
1240 */
1241
1242#define fc_host_show_function(field, format_string, sz, cast)                \
1243static ssize_t                                                                \
1244show_fc_host_##field (struct device *dev,                                \
1245                      struct device_attribute *attr, char *buf)                \
1246{                                                                        \
1247        struct Scsi_Host *shost = transport_class_to_shost(dev);        \
1248        struct fc_internal *i = to_fc_internal(shost->transportt);        \
1249        if (i->f->get_host_##field)                                        \
1250                i->f->get_host_##field(shost);                                \
1251        return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
1252}
1253
1254#define fc_host_store_function(field)                                        \
1255static ssize_t                                                                \
1256store_fc_host_##field(struct device *dev,                                 \
1257                      struct device_attribute *attr,                        \
1258                      const char *buf,        size_t count)                        \
1259{                                                                        \
1260        int val;                                                        \
1261        struct Scsi_Host *shost = transport_class_to_shost(dev);        \
1262        struct fc_internal *i = to_fc_internal(shost->transportt);        \
1263        char *cp;                                                        \
1264                                                                        \
1265        val = simple_strtoul(buf, &cp, 0);                                \
1266        if (*cp && (*cp != '\n'))                                        \
1267                return -EINVAL;                                                \
1268        i->f->set_host_##field(shost, val);                                \
1269        return count;                                                        \
1270}
1271
1272#define fc_host_store_str_function(field, slen)                                \
1273static ssize_t                                                                \
1274store_fc_host_##field(struct device *dev,                                \
1275                      struct device_attribute *attr,                        \
1276                      const char *buf, size_t count)                        \
1277{                                                                        \
1278        struct Scsi_Host *shost = transport_class_to_shost(dev);        \
1279        struct fc_internal *i = to_fc_internal(shost->transportt);        \
1280        unsigned int cnt=count;                                                \
1281                                                                        \
1282        /* count may include a LF at end of string */                        \
1283        if (buf[cnt-1] == '\n')                                                \
1284                cnt--;                                                        \
1285        if (cnt > ((slen) - 1))                                                \
1286                return -EINVAL;                                                \
1287        memcpy(fc_host_##field(shost), buf, cnt);                        \
1288        i->f->set_host_##field(shost);                                        \
1289        return count;                                                        \
1290}
1291
1292#define fc_host_rd_attr(field, format_string, sz)                        \
1293        fc_host_show_function(field, format_string, sz, )                \
1294static FC_DEVICE_ATTR(host, field, S_IRUGO,                        \
1295                         show_fc_host_##field, NULL)
1296
1297#define fc_host_rd_attr_cast(field, format_string, sz, cast)                \
1298        fc_host_show_function(field, format_string, sz, (cast))                \
1299static FC_DEVICE_ATTR(host, field, S_IRUGO,                        \
1300                          show_fc_host_##field, NULL)
1301
1302#define fc_host_rw_attr(field, format_string, sz)                        \
1303        fc_host_show_function(field, format_string, sz, )                \
1304        fc_host_store_function(field)                                        \
1305static FC_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR,                \
1306                        show_fc_host_##field,                                \
1307                        store_fc_host_##field)
1308
1309#define fc_host_rd_enum_attr(title, maxlen)                                \
1310static ssize_t                                                                \
1311show_fc_host_##title (struct device *dev,                                \
1312                      struct device_attribute *attr, char *buf)                \
1313{                                                                        \
1314        struct Scsi_Host *shost = transport_class_to_shost(dev);        \
1315        struct fc_internal *i = to_fc_internal(shost->transportt);        \
1316        const char *name;                                                \
1317        if (i->f->get_host_##title)                                        \
1318                i->f->get_host_##title(shost);                                \
1319        name = get_fc_##title##_name(fc_host_##title(shost));                \
1320        if (!name)                                                        \
1321                return -EINVAL;                                                \
1322        return snprintf(buf, maxlen, "%s\n", name);                        \
1323}                                                                        \
1324static FC_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL)
1325
1326#define SETUP_HOST_ATTRIBUTE_RD(field)                                        \
1327        i->private_host_attrs[count] = device_attr_host_##field;        \
1328        i->private_host_attrs[count].attr.mode = S_IRUGO;                \
1329        i->private_host_attrs[count].store = NULL;                        \
1330        i->host_attrs[count] = &i->private_host_attrs[count];                \
1331        if (i->f->show_host_##field)                                        \
1332                count++
1333
1334#define SETUP_HOST_ATTRIBUTE_RD_NS(field)                                \
1335        i->private_host_attrs[count] = device_attr_host_##field;        \
1336        i->private_host_attrs[count].attr.mode = S_IRUGO;                \
1337        i->private_host_attrs[count].store = NULL;                        \
1338        i->host_attrs[count] = &i->private_host_attrs[count];                \
1339        count++
1340
1341#define SETUP_HOST_ATTRIBUTE_RW(field)                                        \
1342        i->private_host_attrs[count] = device_attr_host_##field;        \
1343        if (!i->f->set_host_##field) {                                        \
1344                i->private_host_attrs[count].attr.mode = S_IRUGO;        \
1345                i->private_host_attrs[count].store = NULL;                \
1346        }                                                                \
1347        i->host_attrs[count] = &i->private_host_attrs[count];                \
1348        if (i->f->show_host_##field)                                        \
1349                count++
1350
1351
1352#define fc_private_host_show_function(field, format_string, sz, cast)        \
1353static ssize_t                                                                \
1354show_fc_host_##field (struct device *dev,                                \
1355                      struct device_attribute *attr, char *buf)                \
1356{                                                                        \
1357        struct Scsi_Host *shost = transport_class_to_shost(dev);        \
1358        return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
1359}
1360
1361#define fc_private_host_rd_attr(field, format_string, sz)                \
1362        fc_private_host_show_function(field, format_string, sz, )        \
1363static FC_DEVICE_ATTR(host, field, S_IRUGO,                        \
1364                         show_fc_host_##field, NULL)
1365
1366#define fc_private_host_rd_attr_cast(field, format_string, sz, cast)        \
1367        fc_private_host_show_function(field, format_string, sz, (cast)) \
1368static FC_DEVICE_ATTR(host, field, S_IRUGO,                        \
1369                          show_fc_host_##field, NULL)
1370
1371#define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field)                        \
1372        i->private_host_attrs[count] = device_attr_host_##field;        \
1373        i->private_host_attrs[count].attr.mode = S_IRUGO;                \
1374        i->private_host_attrs[count].store = NULL;                        \
1375        i->host_attrs[count] = &i->private_host_attrs[count];                \
1376        count++
1377
1378#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field)                        \
1379{                                                                        \
1380        i->private_host_attrs[count] = device_attr_host_##field;        \
1381        i->host_attrs[count] = &i->private_host_attrs[count];                \
1382        count++;                                                        \
1383}
1384
1385
1386/* Fixed Host Attributes */
1387
1388static ssize_t
1389show_fc_host_supported_classes (struct device *dev,
1390                                struct device_attribute *attr, char *buf)
1391{
1392        struct Scsi_Host *shost = transport_class_to_shost(dev);
1393
1394        if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED)
1395                return snprintf(buf, 20, "unspecified\n");
1396
1397        return get_fc_cos_names(fc_host_supported_classes(shost), buf);
1398}
1399static FC_DEVICE_ATTR(host, supported_classes, S_IRUGO,
1400                show_fc_host_supported_classes, NULL);
1401
1402static ssize_t
1403show_fc_host_supported_fc4s (struct device *dev,
1404                             struct device_attribute *attr, char *buf)
1405{
1406        struct Scsi_Host *shost = transport_class_to_shost(dev);
1407        return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost));
1408}
1409static FC_DEVICE_ATTR(host, supported_fc4s, S_IRUGO,
1410                show_fc_host_supported_fc4s, NULL);
1411
1412static ssize_t
1413show_fc_host_supported_speeds (struct device *dev,
1414                               struct device_attribute *attr, char *buf)
1415{
1416        struct Scsi_Host *shost = transport_class_to_shost(dev);
1417
1418        if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN)
1419                return snprintf(buf, 20, "unknown\n");
1420
1421        return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf);
1422}
1423static FC_DEVICE_ATTR(host, supported_speeds, S_IRUGO,
1424                show_fc_host_supported_speeds, NULL);
1425
1426
1427fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
1428fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
1429fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
1430                             unsigned long long);
1431fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
1432fc_private_host_rd_attr(max_npiv_vports, "%u\n", 20);
1433fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
1434
1435
1436/* Dynamic Host Attributes */
1437
1438static ssize_t
1439show_fc_host_active_fc4s (struct device *dev,
1440                          struct device_attribute *attr, char *buf)
1441{
1442        struct Scsi_Host *shost = transport_class_to_shost(dev);
1443        struct fc_internal *i = to_fc_internal(shost->transportt);
1444
1445        if (i->f->get_host_active_fc4s)
1446                i->f->get_host_active_fc4s(shost);
1447
1448        return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost));
1449}
1450static FC_DEVICE_ATTR(host, active_fc4s, S_IRUGO,
1451                show_fc_host_active_fc4s, NULL);
1452
1453static ssize_t
1454show_fc_host_speed (struct device *dev,
1455                    struct device_attribute *attr, char *buf)
1456{
1457        struct Scsi_Host *shost = transport_class_to_shost(dev);
1458        struct fc_internal *i = to_fc_internal(shost->transportt);
1459
1460        if (i->f->get_host_speed)
1461                i->f->get_host_speed(shost);
1462
1463        if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN)
1464                return snprintf(buf, 20, "unknown\n");
1465
1466        return get_fc_port_speed_names(fc_host_speed(shost), buf);
1467}
1468static FC_DEVICE_ATTR(host, speed, S_IRUGO,
1469                show_fc_host_speed, NULL);
1470
1471
1472fc_host_rd_attr(port_id, "0x%06x\n", 20);
1473fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN);
1474fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
1475fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
1476fc_host_rd_attr(symbolic_name, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1);
1477
1478fc_private_host_show_function(system_hostname, "%s\n",
1479                FC_SYMBOLIC_NAME_SIZE + 1, )
1480fc_host_store_str_function(system_hostname, FC_SYMBOLIC_NAME_SIZE)
1481static FC_DEVICE_ATTR(host, system_hostname, S_IRUGO | S_IWUSR,
1482                show_fc_host_system_hostname, store_fc_host_system_hostname);
1483
1484
1485/* Private Host Attributes */
1486
1487static ssize_t
1488show_fc_private_host_tgtid_bind_type(struct device *dev,
1489                                     struct device_attribute *attr, char *buf)
1490{
1491        struct Scsi_Host *shost = transport_class_to_shost(dev);
1492        const char *name;
1493
1494        name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost));
1495        if (!name)
1496                return -EINVAL;
1497        return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name);
1498}
1499
1500#define get_list_head_entry(pos, head, member)                 \
1501        pos = list_entry((head)->next, typeof(*pos), member)
1502
1503static ssize_t
1504store_fc_private_host_tgtid_bind_type(struct device *dev,
1505        struct device_attribute *attr, const char *buf, size_t count)
1506{
1507        struct Scsi_Host *shost = transport_class_to_shost(dev);
1508        struct fc_rport *rport;
1509         enum fc_tgtid_binding_type val;
1510        unsigned long flags;
1511
1512        if (get_fc_tgtid_bind_type_match(buf, &val))
1513                return -EINVAL;
1514
1515        /* if changing bind type, purge all unused consistent bindings */
1516        if (val != fc_host_tgtid_bind_type(shost)) {
1517                spin_lock_irqsave(shost->host_lock, flags);
1518                while (!list_empty(&fc_host_rport_bindings(shost))) {
1519                        get_list_head_entry(rport,
1520                                &fc_host_rport_bindings(shost), peers);
1521                        list_del(&rport->peers);
1522                        rport->port_state = FC_PORTSTATE_DELETED;
1523                        fc_queue_work(shost, &rport->rport_delete_work);
1524                }
1525                spin_unlock_irqrestore(shost->host_lock, flags);
1526        }
1527
1528        fc_host_tgtid_bind_type(shost) = val;
1529        return count;
1530}
1531
1532static FC_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
1533                        show_fc_private_host_tgtid_bind_type,
1534                        store_fc_private_host_tgtid_bind_type);
1535
1536static ssize_t
1537store_fc_private_host_issue_lip(struct device *dev,
1538        struct device_attribute *attr, const char *buf, size_t count)
1539{
1540        struct Scsi_Host *shost = transport_class_to_shost(dev);
1541        struct fc_internal *i = to_fc_internal(shost->transportt);
1542        int ret;
1543
1544        /* ignore any data value written to the attribute */
1545        if (i->f->issue_fc_host_lip) {
1546                ret = i->f->issue_fc_host_lip(shost);
1547                return ret ? ret: count;
1548        }
1549
1550        return -ENOENT;
1551}
1552
1553static FC_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
1554                        store_fc_private_host_issue_lip);
1555
1556fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20);
1557
1558
1559/*
1560 * Host Statistics Management
1561 */
1562
1563/* Show a given an attribute in the statistics group */
1564static ssize_t
1565fc_stat_show(const struct device *dev, char *buf, unsigned long offset)
1566{
1567        struct Scsi_Host *shost = transport_class_to_shost(dev);
1568        struct fc_internal *i = to_fc_internal(shost->transportt);
1569        struct fc_host_statistics *stats;
1570        ssize_t ret = -ENOENT;
1571
1572        if (offset > sizeof(struct fc_host_statistics) ||
1573            offset % sizeof(u64) != 0)
1574                WARN_ON(1);
1575
1576        if (i->f->get_fc_host_stats) {
1577                stats = (i->f->get_fc_host_stats)(shost);
1578                if (stats)
1579                        ret = snprintf(buf, 20, "0x%llx\n",
1580                              (unsigned long long)*(u64 *)(((u8 *) stats) + offset));
1581        }
1582        return ret;
1583}
1584
1585
1586/* generate a read-only statistics attribute */
1587#define fc_host_statistic(name)                                                \
1588static ssize_t show_fcstat_##name(struct device *cd,                        \
1589                                  struct device_attribute *attr,        \
1590                                  char *buf)                                \
1591{                                                                        \
1592        return fc_stat_show(cd, buf,                                         \
1593                            offsetof(struct fc_host_statistics, name));        \
1594}                                                                        \
1595static FC_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL)
1596
1597fc_host_statistic(seconds_since_last_reset);
1598fc_host_statistic(tx_frames);
1599fc_host_statistic(tx_words);
1600fc_host_statistic(rx_frames);
1601fc_host_statistic(rx_words);
1602fc_host_statistic(lip_count);
1603fc_host_statistic(nos_count);
1604fc_host_statistic(error_frames);
1605fc_host_statistic(dumped_frames);
1606fc_host_statistic(link_failure_count);
1607fc_host_statistic(loss_of_sync_count);
1608fc_host_statistic(loss_of_signal_count);
1609fc_host_statistic(prim_seq_protocol_err_count);
1610fc_host_statistic(invalid_tx_word_count);
1611fc_host_statistic(invalid_crc_count);
1612fc_host_statistic(fcp_input_requests);
1613fc_host_statistic(fcp_output_requests);
1614fc_host_statistic(fcp_control_requests);
1615fc_host_statistic(fcp_input_megabytes);
1616fc_host_statistic(fcp_output_megabytes);
1617
1618static ssize_t
1619fc_reset_statistics(struct device *dev, struct device_attribute *attr,
1620                    const char *buf, size_t count)
1621{
1622        struct Scsi_Host *shost = transport_class_to_shost(dev);
1623        struct fc_internal *i = to_fc_internal(shost->transportt);
1624
1625        /* ignore any data value written to the attribute */
1626        if (i->f->reset_fc_host_stats) {
1627                i->f->reset_fc_host_stats(shost);
1628                return count;
1629        }
1630
1631        return -ENOENT;
1632}
1633static FC_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL,
1634                                fc_reset_statistics);
1635
1636static struct attribute *fc_statistics_attrs[] = {
1637        &device_attr_host_seconds_since_last_reset.attr,
1638        &device_attr_host_tx_frames.attr,
1639        &device_attr_host_tx_words.attr,
1640        &device_attr_host_rx_frames.attr,
1641        &device_attr_host_rx_words.attr,
1642        &device_attr_host_lip_count.attr,
1643        &device_attr_host_nos_count.attr,
1644        &device_attr_host_error_frames.attr,
1645        &device_attr_host_dumped_frames.attr,
1646        &device_attr_host_link_failure_count.attr,
1647        &device_attr_host_loss_of_sync_count.attr,
1648        &device_attr_host_loss_of_signal_count.attr,
1649        &device_attr_host_prim_seq_protocol_err_count.attr,
1650        &device_attr_host_invalid_tx_word_count.attr,
1651        &device_attr_host_invalid_crc_count.attr,
1652        &device_attr_host_fcp_input_requests.attr,
1653        &device_attr_host_fcp_output_requests.attr,
1654        &device_attr_host_fcp_control_requests.attr,
1655        &device_attr_host_fcp_input_megabytes.attr,
1656        &device_attr_host_fcp_output_megabytes.attr,
1657        &device_attr_host_reset_statistics.attr,
1658        NULL
1659};
1660
1661static struct attribute_group fc_statistics_group = {
1662        .name = "statistics",
1663        .attrs = fc_statistics_attrs,
1664};
1665
1666
1667/* Host Vport Attributes */
1668
1669static int
1670fc_parse_wwn(const char *ns, u64 *nm)
1671{
1672        unsigned int i, j;
1673        u8 wwn[8];
1674
1675        memset(wwn, 0, sizeof(wwn));
1676
1677        /* Validate and store the new name */
1678        for (i=0, j=0; i < 16; i++) {
1679                if ((*ns >= 'a') && (*ns <= 'f'))
1680                        j = ((j << 4) | ((*ns++ -'a') + 10));
1681                else if ((*ns >= 'A') && (*ns <= 'F'))
1682                        j = ((j << 4) | ((*ns++ -'A') + 10));
1683                else if ((*ns >= '0') && (*ns <= '9'))
1684                        j = ((j << 4) | (*ns++ -'0'));
1685                else
1686                        return -EINVAL;
1687                if (i % 2) {
1688                        wwn[i/2] = j & 0xff;
1689                        j = 0;
1690                }
1691        }
1692
1693        *nm = wwn_to_u64(wwn);
1694
1695        return 0;
1696}
1697
1698
1699/*
1700 * "Short-cut" sysfs variable to create a new vport on a FC Host.
1701 * Input is a string of the form "<WWPN>:<WWNN>". Other attributes
1702 * will default to a NPIV-based FCP_Initiator; The WWNs are specified
1703 * as hex characters, and may *not* contain any prefixes (e.g. 0x, x, etc)
1704 */
1705static ssize_t
1706store_fc_host_vport_create(struct device *dev, struct device_attribute *attr,
1707                           const char *buf, size_t count)
1708{
1709        struct Scsi_Host *shost = transport_class_to_shost(dev);
1710        struct fc_vport_identifiers vid;
1711        struct fc_vport *vport;
1712        unsigned int cnt=count;
1713        int stat;
1714
1715        memset(&vid, 0, sizeof(vid));
1716
1717        /* count may include a LF at end of string */
1718        if (buf[cnt-1] == '\n')
1719                cnt--;
1720
1721        /* validate we have enough characters for WWPN */
1722        if ((cnt != (16+1+16)) || (buf[16] != ':'))
1723                return -EINVAL;
1724
1725        stat = fc_parse_wwn(&buf[0], &vid.port_name);
1726        if (stat)
1727                return stat;
1728
1729        stat = fc_parse_wwn(&buf[17], &vid.node_name);
1730        if (stat)
1731                return stat;
1732
1733        vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
1734        vid.vport_type = FC_PORTTYPE_NPIV;
1735        /* vid.symbolic_name is already zero/NULL's */
1736        vid.disable = false;                /* always enabled */
1737
1738        /* we only allow support on Channel 0 !!! */
1739        stat = fc_vport_setup(shost, 0, &shost->shost_gendev, &vid, &vport);
1740        return stat ? stat : count;
1741}
1742static FC_DEVICE_ATTR(host, vport_create, S_IWUSR, NULL,
1743                        store_fc_host_vport_create);
1744
1745
1746/*
1747 * "Short-cut" sysfs variable to delete a vport on a FC Host.
1748 * Vport is identified by a string containing "<WWPN>:<WWNN>".
1749 * The WWNs are specified as hex characters, and may *not* contain
1750 * any prefixes (e.g. 0x, x, etc)
1751 */
1752static ssize_t
1753store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
1754                           const char *buf, size_t count)
1755{
1756        struct Scsi_Host *shost = transport_class_to_shost(dev);
1757        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1758        struct fc_vport *vport;
1759        u64 wwpn, wwnn;
1760        unsigned long flags;
1761        unsigned int cnt=count;
1762        int stat, match;
1763
1764        /* count may include a LF at end of string */
1765        if (buf[cnt-1] == '\n')
1766                cnt--;
1767
1768        /* validate we have enough characters for WWPN */
1769        if ((cnt != (16+1+16)) || (buf[16] != ':'))
1770                return -EINVAL;
1771
1772        stat = fc_parse_wwn(&buf[0], &wwpn);
1773        if (stat)
1774                return stat;
1775
1776        stat = fc_parse_wwn(&buf[17], &wwnn);
1777        if (stat)
1778                return stat;
1779
1780        spin_lock_irqsave(shost->host_lock, flags);
1781        match = 0;
1782        /* we only allow support on Channel 0 !!! */
1783        list_for_each_entry(vport, &fc_host->vports, peers) {
1784                if ((vport->channel == 0) &&
1785                    (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
1786                        match = 1;
1787                        break;
1788                }
1789        }
1790        spin_unlock_irqrestore(shost->host_lock, flags);
1791
1792        if (!match)
1793                return -ENODEV;
1794
1795        stat = fc_vport_terminate(vport);
1796        return stat ? stat : count;
1797}
1798static FC_DEVICE_ATTR(host, vport_delete, S_IWUSR, NULL,
1799                        store_fc_host_vport_delete);
1800
1801
1802static int fc_host_match(struct attribute_container *cont,
1803                          struct device *dev)
1804{
1805        struct Scsi_Host *shost;
1806        struct fc_internal *i;
1807
1808        if (!scsi_is_host_device(dev))
1809                return 0;
1810
1811        shost = dev_to_shost(dev);
1812        if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1813            != &fc_host_class.class)
1814                return 0;
1815
1816        i = to_fc_internal(shost->transportt);
1817
1818        return &i->t.host_attrs.ac == cont;
1819}
1820
1821static int fc_target_match(struct attribute_container *cont,
1822                            struct device *dev)
1823{
1824        struct Scsi_Host *shost;
1825        struct fc_internal *i;
1826
1827        if (!scsi_is_target_device(dev))
1828                return 0;
1829
1830        shost = dev_to_shost(dev->parent);
1831        if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1832            != &fc_host_class.class)
1833                return 0;
1834
1835        i = to_fc_internal(shost->transportt);
1836
1837        return &i->t.target_attrs.ac == cont;
1838}
1839
1840static void fc_rport_dev_release(struct device *dev)
1841{
1842        struct fc_rport *rport = dev_to_rport(dev);
1843        put_device(dev->parent);
1844        kfree(rport);
1845}
1846
1847int scsi_is_fc_rport(const struct device *dev)
1848{
1849        return dev->release == fc_rport_dev_release;
1850}
1851EXPORT_SYMBOL(scsi_is_fc_rport);
1852
1853static int fc_rport_match(struct attribute_container *cont,
1854                            struct device *dev)
1855{
1856        struct Scsi_Host *shost;
1857        struct fc_internal *i;
1858
1859        if (!scsi_is_fc_rport(dev))
1860                return 0;
1861
1862        shost = dev_to_shost(dev->parent);
1863        if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1864            != &fc_host_class.class)
1865                return 0;
1866
1867        i = to_fc_internal(shost->transportt);
1868
1869        return &i->rport_attr_cont.ac == cont;
1870}
1871
1872
1873static void fc_vport_dev_release(struct device *dev)
1874{
1875        struct fc_vport *vport = dev_to_vport(dev);
1876        put_device(dev->parent);                /* release kobj parent */
1877        kfree(vport);
1878}
1879
1880int scsi_is_fc_vport(const struct device *dev)
1881{
1882        return dev->release == fc_vport_dev_release;
1883}
1884EXPORT_SYMBOL(scsi_is_fc_vport);
1885
1886static int fc_vport_match(struct attribute_container *cont,
1887                            struct device *dev)
1888{
1889        struct fc_vport *vport;
1890        struct Scsi_Host *shost;
1891        struct fc_internal *i;
1892
1893        if (!scsi_is_fc_vport(dev))
1894                return 0;
1895        vport = dev_to_vport(dev);
1896
1897        shost = vport_to_shost(vport);
1898        if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1899            != &fc_host_class.class)
1900                return 0;
1901
1902        i = to_fc_internal(shost->transportt);
1903        return &i->vport_attr_cont.ac == cont;
1904}
1905
1906
1907/**
1908 * fc_timed_out - FC Transport I/O timeout intercept handler
1909 * @scmd:        The SCSI command which timed out
1910 *
1911 * This routine protects against error handlers getting invoked while a
1912 * rport is in a blocked state, typically due to a temporarily loss of
1913 * connectivity. If the error handlers are allowed to proceed, requests
1914 * to abort i/o, reset the target, etc will likely fail as there is no way
1915 * to communicate with the device to perform the requested function. These
1916 * failures may result in the midlayer taking the device offline, requiring
1917 * manual intervention to restore operation.
1918 *
1919 * This routine, called whenever an i/o times out, validates the state of
1920 * the underlying rport. If the rport is blocked, it returns
1921 * EH_RESET_TIMER, which will continue to reschedule the timeout.
1922 * Eventually, either the device will return, or devloss_tmo will fire,
1923 * and when the timeout then fires, it will be handled normally.
1924 * If the rport is not blocked, normal error handling continues.
1925 *
1926 * Notes:
1927 *        This routine assumes no locks are held on entry.
1928 */
1929static enum blk_eh_timer_return
1930fc_timed_out(struct scsi_cmnd *scmd)
1931{
1932        struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device));
1933
1934        if (rport->port_state == FC_PORTSTATE_BLOCKED)
1935                return BLK_EH_RESET_TIMER;
1936
1937        return BLK_EH_NOT_HANDLED;
1938}
1939
1940/*
1941 * Called by fc_user_scan to locate an rport on the shost that
1942 * matches the channel and target id, and invoke scsi_scan_target()
1943 * on the rport.
1944 */
1945static void
1946fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, uint lun)
1947{
1948        struct fc_rport *rport;
1949        unsigned long flags;
1950
1951        spin_lock_irqsave(shost->host_lock, flags);
1952
1953        list_for_each_entry(rport, &fc_host_rports(shost), peers) {
1954                if (rport->scsi_target_id == -1)
1955                        continue;
1956
1957                if (rport->port_state != FC_PORTSTATE_ONLINE)
1958                        continue;
1959
1960                if ((channel == rport->channel) &&
1961                    (id == rport->scsi_target_id)) {
1962                        spin_unlock_irqrestore(shost->host_lock, flags);
1963                        scsi_scan_target(&rport->dev, channel, id, lun, 1);
1964                        return;
1965                }
1966        }
1967
1968        spin_unlock_irqrestore(shost->host_lock, flags);
1969}
1970
1971/*
1972 * Called via sysfs scan routines. Necessary, as the FC transport
1973 * wants to place all target objects below the rport object. So this
1974 * routine must invoke the scsi_scan_target() routine with the rport
1975 * object as the parent.
1976 */
1977static int
1978fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, uint lun)
1979{
1980        uint chlo, chhi;
1981        uint tgtlo, tgthi;
1982
1983        if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
1984            ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
1985            ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
1986                return -EINVAL;
1987
1988        if (channel == SCAN_WILD_CARD) {
1989                chlo = 0;
1990                chhi = shost->max_channel + 1;
1991        } else {
1992                chlo = channel;
1993                chhi = channel + 1;
1994        }
1995
1996        if (id == SCAN_WILD_CARD) {
1997                tgtlo = 0;
1998                tgthi = shost->max_id;
1999        } else {
2000                tgtlo = id;
2001                tgthi = id + 1;
2002        }
2003
2004        for ( ; chlo < chhi; chlo++)
2005                for ( ; tgtlo < tgthi; tgtlo++)
2006                        fc_user_scan_tgt(shost, chlo, tgtlo, lun);
2007
2008        return 0;
2009}
2010
2011static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id,
2012                                int result)
2013{
2014        struct fc_internal *i = to_fc_internal(shost->transportt);
2015        return i->f->tsk_mgmt_response(shost, nexus, tm_id, result);
2016}
2017
2018static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
2019{
2020        struct fc_internal *i = to_fc_internal(shost->transportt);
2021        return i->f->it_nexus_response(shost, nexus, result);
2022}
2023
2024struct scsi_transport_template *
2025fc_attach_transport(struct fc_function_template *ft)
2026{
2027        int count;
2028        struct fc_internal *i = kzalloc(sizeof(struct fc_internal),
2029                                        GFP_KERNEL);
2030
2031        if (unlikely(!i))
2032                return NULL;
2033
2034        i->t.target_attrs.ac.attrs = &i->starget_attrs[0];
2035        i->t.target_attrs.ac.class = &fc_transport_class.class;
2036        i->t.target_attrs.ac.match = fc_target_match;
2037        i->t.target_size = sizeof(struct fc_starget_attrs);
2038        transport_container_register(&i->t.target_attrs);
2039
2040        i->t.host_attrs.ac.attrs = &i->host_attrs[0];
2041        i->t.host_attrs.ac.class = &fc_host_class.class;
2042        i->t.host_attrs.ac.match = fc_host_match;
2043        i->t.host_size = sizeof(struct fc_host_attrs);
2044        if (ft->get_fc_host_stats)
2045                i->t.host_attrs.statistics = &fc_statistics_group;
2046        transport_container_register(&i->t.host_attrs);
2047
2048        i->rport_attr_cont.ac.attrs = &i->rport_attrs[0];
2049        i->rport_attr_cont.ac.class = &fc_rport_class.class;
2050        i->rport_attr_cont.ac.match = fc_rport_match;
2051        transport_container_register(&i->rport_attr_cont);
2052
2053        i->vport_attr_cont.ac.attrs = &i->vport_attrs[0];
2054        i->vport_attr_cont.ac.class = &fc_vport_class.class;
2055        i->vport_attr_cont.ac.match = fc_vport_match;
2056        transport_container_register(&i->vport_attr_cont);
2057
2058        i->f = ft;
2059
2060        /* Transport uses the shost workq for scsi scanning */
2061        i->t.create_work_queue = 1;
2062
2063        i->t.eh_timed_out = fc_timed_out;
2064
2065        i->t.user_scan = fc_user_scan;
2066
2067        /* target-mode drivers' functions */
2068        i->t.tsk_mgmt_response = fc_tsk_mgmt_response;
2069        i->t.it_nexus_response = fc_it_nexus_response;
2070
2071        /*
2072         * Setup SCSI Target Attributes.
2073         */
2074        count = 0;
2075        SETUP_STARGET_ATTRIBUTE_RD(node_name);
2076        SETUP_STARGET_ATTRIBUTE_RD(port_name);
2077        SETUP_STARGET_ATTRIBUTE_RD(port_id);
2078
2079        BUG_ON(count > FC_STARGET_NUM_ATTRS);
2080
2081        i->starget_attrs[count] = NULL;
2082
2083
2084        /*
2085         * Setup SCSI Host Attributes.
2086         */
2087        count=0;
2088        SETUP_HOST_ATTRIBUTE_RD(node_name);
2089        SETUP_HOST_ATTRIBUTE_RD(port_name);
2090        SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
2091        SETUP_HOST_ATTRIBUTE_RD(supported_classes);
2092        SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
2093        SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
2094        SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
2095        if (ft->vport_create) {
2096                SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports);
2097                SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
2098        }
2099        SETUP_HOST_ATTRIBUTE_RD(serial_number);
2100
2101        SETUP_HOST_ATTRIBUTE_RD(port_id);
2102        SETUP_HOST_ATTRIBUTE_RD(port_type);
2103        SETUP_HOST_ATTRIBUTE_RD(port_state);
2104        SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
2105        SETUP_HOST_ATTRIBUTE_RD(speed);
2106        SETUP_HOST_ATTRIBUTE_RD(fabric_name);
2107        SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
2108        SETUP_HOST_ATTRIBUTE_RW(system_hostname);
2109
2110        /* Transport-managed attributes */
2111        SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
2112        if (ft->issue_fc_host_lip)
2113                SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
2114        if (ft->vport_create)
2115                SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create);
2116        if (ft->vport_delete)
2117                SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete);
2118
2119        BUG_ON(count > FC_HOST_NUM_ATTRS);
2120
2121        i->host_attrs[count] = NULL;
2122
2123        /*
2124         * Setup Remote Port Attributes.
2125         */
2126        count=0;
2127        SETUP_RPORT_ATTRIBUTE_RD(maxframe_size);
2128        SETUP_RPORT_ATTRIBUTE_RD(supported_classes);
2129        SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo);
2130        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name);
2131        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
2132        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id);
2133        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
2134        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
2135        SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
2136        SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
2137
2138        BUG_ON(count > FC_RPORT_NUM_ATTRS);
2139
2140        i->rport_attrs[count] = NULL;
2141
2142        /*
2143         * Setup Virtual Port Attributes.
2144         */
2145        count=0;
2146        SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state);
2147        SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state);
2148        SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name);
2149        SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name);
2150        SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles);
2151        SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type);
2152        SETUP_VPORT_ATTRIBUTE_RW(symbolic_name);
2153        SETUP_VPORT_ATTRIBUTE_WR(vport_delete);
2154        SETUP_VPORT_ATTRIBUTE_WR(vport_disable);
2155
2156        BUG_ON(count > FC_VPORT_NUM_ATTRS);
2157
2158        i->vport_attrs[count] = NULL;
2159
2160        return &i->t;
2161}
2162EXPORT_SYMBOL(fc_attach_transport);
2163
2164void fc_release_transport(struct scsi_transport_template *t)
2165{
2166        struct fc_internal *i = to_fc_internal(t);
2167
2168        transport_container_unregister(&i->t.target_attrs);
2169        transport_container_unregister(&i->t.host_attrs);
2170        transport_container_unregister(&i->rport_attr_cont);
2171        transport_container_unregister(&i->vport_attr_cont);
2172
2173        kfree(i);
2174}
2175EXPORT_SYMBOL(fc_release_transport);
2176
2177/**
2178 * fc_queue_work - Queue work to the fc_host workqueue.
2179 * @shost:        Pointer to Scsi_Host bound to fc_host.
2180 * @work:        Work to queue for execution.
2181 *
2182 * Return value:
2183 *         1 - work queued for execution
2184 *        0 - work is already queued
2185 *        -EINVAL - work queue doesn't exist
2186 */
2187static int
2188fc_queue_work(struct Scsi_Host *shost, struct work_struct *work)
2189{
2190        if (unlikely(!fc_host_work_q(shost))) {
2191                printk(KERN_ERR
2192                        "ERROR: FC host '%s' attempted to queue work, "
2193                        "when no workqueue created.\n", shost->hostt->name);
2194                dump_stack();
2195
2196                return -EINVAL;
2197        }
2198
2199        return queue_work(fc_host_work_q(shost), work);
2200}
2201
2202/**
2203 * fc_flush_work - Flush a fc_host's workqueue.
2204 * @shost:        Pointer to Scsi_Host bound to fc_host.
2205 */
2206static void
2207fc_flush_work(struct Scsi_Host *shost)
2208{
2209        if (!fc_host_work_q(shost)) {
2210                printk(KERN_ERR
2211                        "ERROR: FC host '%s' attempted to flush work, "
2212                        "when no workqueue created.\n", shost->hostt->name);
2213                dump_stack();
2214                return;
2215        }
2216
2217        flush_workqueue(fc_host_work_q(shost));
2218}
2219
2220/**
2221 * fc_queue_devloss_work - Schedule work for the fc_host devloss workqueue.
2222 * @shost:        Pointer to Scsi_Host bound to fc_host.
2223 * @work:        Work to queue for execution.
2224 * @delay:        jiffies to delay the work queuing
2225 *
2226 * Return value:
2227 *         1 on success / 0 already queued / < 0 for error
2228 */
2229static int
2230fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
2231                                unsigned long delay)
2232{
2233        if (unlikely(!fc_host_devloss_work_q(shost))) {
2234                printk(KERN_ERR
2235                        "ERROR: FC host '%s' attempted to queue work, "
2236                        "when no workqueue created.\n", shost->hostt->name);
2237                dump_stack();
2238
2239                return -EINVAL;
2240        }
2241
2242        return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
2243}
2244
2245/**
2246 * fc_flush_devloss - Flush a fc_host's devloss workqueue.
2247 * @shost:        Pointer to Scsi_Host bound to fc_host.
2248 */
2249static void
2250fc_flush_devloss(struct Scsi_Host *shost)
2251{
2252        if (!fc_host_devloss_work_q(shost)) {
2253                printk(KERN_ERR
2254                        "ERROR: FC host '%s' attempted to flush work, "
2255                        "when no workqueue created.\n", shost->hostt->name);
2256                dump_stack();
2257                return;
2258        }
2259
2260        flush_workqueue(fc_host_devloss_work_q(shost));
2261}
2262
2263
2264/**
2265 * fc_remove_host - called to terminate any fc_transport-related elements for a scsi host.
2266 * @shost:        Which &Scsi_Host
2267 *
2268 * This routine is expected to be called immediately preceeding the
2269 * a driver's call to scsi_remove_host().
2270 *
2271 * WARNING: A driver utilizing the fc_transport, which fails to call
2272 *   this routine prior to scsi_remove_host(), will leave dangling
2273 *   objects in /sys/class/fc_remote_ports. Access to any of these
2274 *   objects can result in a system crash !!!
2275 *
2276 * Notes:
2277 *        This routine assumes no locks are held on entry.
2278 */
2279void
2280fc_remove_host(struct Scsi_Host *shost)
2281{
2282        struct fc_vport *vport = NULL, *next_vport = NULL;
2283        struct fc_rport *rport = NULL, *next_rport = NULL;
2284        struct workqueue_struct *work_q;
2285        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2286        unsigned long flags;
2287
2288        spin_lock_irqsave(shost->host_lock, flags);
2289
2290        /* Remove any vports */
2291        list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers)
2292                fc_queue_work(shost, &vport->vport_delete_work);
2293
2294        /* Remove any remote ports */
2295        list_for_each_entry_safe(rport, next_rport,
2296                        &fc_host->rports, peers) {
2297                list_del(&rport->peers);
2298                rport->port_state = FC_PORTSTATE_DELETED;
2299                fc_queue_work(shost, &rport->rport_delete_work);
2300        }
2301
2302        list_for_each_entry_safe(rport, next_rport,
2303                        &fc_host->rport_bindings, peers) {
2304                list_del(&rport->peers);
2305                rport->port_state = FC_PORTSTATE_DELETED;
2306                fc_queue_work(shost, &rport->rport_delete_work);
2307        }
2308
2309        spin_unlock_irqrestore(shost->host_lock, flags);
2310
2311        /* flush all scan work items */
2312        scsi_flush_work(shost);
2313
2314        /* flush all stgt delete, and rport delete work items, then kill it  */
2315        if (fc_host->work_q) {
2316                work_q = fc_host->work_q;
2317                fc_host->work_q = NULL;
2318                destroy_workqueue(work_q);
2319        }
2320
2321        /* flush all devloss work items, then kill it  */
2322        if (fc_host->devloss_work_q) {
2323                work_q = fc_host->devloss_work_q;
2324                fc_host->devloss_work_q = NULL;
2325                destroy_workqueue(work_q);
2326        }
2327}
2328EXPORT_SYMBOL(fc_remove_host);
2329
2330static void fc_terminate_rport_io(struct fc_rport *rport)
2331{
2332        struct Scsi_Host *shost = rport_to_shost(rport);
2333        struct fc_internal *i = to_fc_internal(shost->transportt);
2334
2335        /* Involve the LLDD if possible to terminate all io on the rport. */
2336        if (i->f->terminate_rport_io)
2337                i->f->terminate_rport_io(rport);
2338
2339        /*
2340         * must unblock to flush queued IO. The caller will have set
2341         * the port_state or flags, so that fc_remote_port_chkready will
2342         * fail IO.
2343         */
2344        scsi_target_unblock(&rport->dev);
2345}
2346
2347/**
2348 * fc_starget_delete - called to delete the scsi decendents of an rport
2349 * @work:        remote port to be operated on.
2350 *
2351 * Deletes target and all sdevs.
2352 */
2353static void
2354fc_starget_delete(struct work_struct *work)
2355{
2356        struct fc_rport *rport =
2357                container_of(work, struct fc_rport, stgt_delete_work);
2358
2359        fc_terminate_rport_io(rport);
2360        scsi_remove_target(&rport->dev);
2361}
2362
2363
2364/**
2365 * fc_rport_final_delete - finish rport termination and delete it.
2366 * @work:        remote port to be deleted.
2367 */
2368static void
2369fc_rport_final_delete(struct work_struct *work)
2370{
2371        struct fc_rport *rport =
2372                container_of(work, struct fc_rport, rport_delete_work);
2373        struct device *dev = &rport->dev;
2374        struct Scsi_Host *shost = rport_to_shost(rport);
2375        struct fc_internal *i = to_fc_internal(shost->transportt);
2376        unsigned long flags;
2377
2378        /*
2379         * if a scan is pending, flush the SCSI Host work_q so that
2380         * that we can reclaim the rport scan work element.
2381         */
2382        if (rport->flags & FC_RPORT_SCAN_PENDING)
2383                scsi_flush_work(shost);
2384
2385        fc_terminate_rport_io(rport);
2386        /*
2387         * Cancel any outstanding timers. These should really exist
2388         * only when rmmod'ing the LLDD and we're asking for
2389         * immediate termination of the rports
2390         */
2391        spin_lock_irqsave(shost->host_lock, flags);
2392        if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
2393                spin_unlock_irqrestore(shost->host_lock, flags);
2394                if (!cancel_delayed_work(&rport->fail_io_work))
2395                        fc_flush_devloss(shost);
2396                if (!cancel_delayed_work(&rport->dev_loss_work))
2397                        fc_flush_devloss(shost);
2398                spin_lock_irqsave(shost->host_lock, flags);
2399                rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
2400        }
2401        spin_unlock_irqrestore(shost->host_lock, flags);
2402
2403        /* Delete SCSI target and sdevs */
2404        if (rport->scsi_target_id != -1)
2405                fc_starget_delete(&rport->stgt_delete_work);
2406
2407        /*
2408         * Notify the driver that the rport is now dead. The LLDD will
2409         * also guarantee that any communication to the rport is terminated
2410         */
2411        if (i->f->dev_loss_tmo_callbk)
2412                i->f->dev_loss_tmo_callbk(rport);
2413
2414        transport_remove_device(dev);
2415        device_del(dev);
2416        transport_destroy_device(dev);
2417        put_device(&shost->shost_gendev);        /* for fc_host->rport list */
2418        put_device(dev);                        /* for self-reference */
2419}
2420
2421
2422/**
2423 * fc_rport_create - allocates and creates a remote FC port.
2424 * @shost:        scsi host the remote port is connected to.
2425 * @channel:        Channel on shost port connected to.
2426 * @ids:        The world wide names, fc address, and FC4 port
2427 *                roles for the remote port.
2428 *
2429 * Allocates and creates the remoter port structure, including the
2430 * class and sysfs creation.
2431 *
2432 * Notes:
2433 *        This routine assumes no locks are held on entry.
2434 */
2435static struct fc_rport *
2436fc_rport_create(struct Scsi_Host *shost, int channel,
2437        struct fc_rport_identifiers  *ids)
2438{
2439        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2440        struct fc_internal *fci = to_fc_internal(shost->transportt);
2441        struct fc_rport *rport;
2442        struct device *dev;
2443        unsigned long flags;
2444        int error;
2445        size_t size;
2446
2447        size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size);
2448        rport = kzalloc(size, GFP_KERNEL);
2449        if (unlikely(!rport)) {
2450                printk(KERN_ERR "%s: allocation failure\n", __func__);
2451                return NULL;
2452        }
2453
2454        rport->maxframe_size = -1;
2455        rport->supported_classes = FC_COS_UNSPECIFIED;
2456        rport->dev_loss_tmo = fc_dev_loss_tmo;
2457        memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
2458        memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
2459        rport->port_id = ids->port_id;
2460        rport->roles = ids->roles;
2461        rport->port_state = FC_PORTSTATE_ONLINE;
2462        if (fci->f->dd_fcrport_size)
2463                rport->dd_data = &rport[1];
2464        rport->channel = channel;
2465        rport->fast_io_fail_tmo = -1;
2466
2467        INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport);
2468        INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io);
2469        INIT_WORK(&rport->scan_work, fc_scsi_scan_rport);
2470        INIT_WORK(&rport->stgt_delete_work, fc_starget_delete);
2471        INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete);
2472
2473        spin_lock_irqsave(shost->host_lock, flags);
2474
2475        rport->number = fc_host->next_rport_number++;
2476        if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
2477                rport->scsi_target_id = fc_host->next_target_id++;
2478        else
2479                rport->scsi_target_id = -1;
2480        list_add_tail(&rport->peers, &fc_host->rports);
2481        get_device(&shost->shost_gendev);        /* for fc_host->rport list */
2482
2483        spin_unlock_irqrestore(shost->host_lock, flags);
2484
2485        dev = &rport->dev;
2486        device_initialize(dev);                        /* takes self reference */
2487        dev->parent = get_device(&shost->shost_gendev); /* parent reference */
2488        dev->release = fc_rport_dev_release;
2489        sprintf(dev->bus_id, "rport-%d:%d-%d",
2490                shost->host_no, channel, rport->number);
2491        transport_setup_device(dev);
2492
2493        error = device_add(dev);
2494        if (error) {
2495                printk(KERN_ERR "FC Remote Port device_add failed\n");
2496                goto delete_rport;
2497        }
2498        transport_add_device(dev);
2499        transport_configure_device(dev);
2500
2501        if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
2502                /* initiate a scan of the target */
2503                rport->flags |= FC_RPORT_SCAN_PENDING;
2504                scsi_queue_work(shost, &rport->scan_work);
2505        }
2506
2507        return rport;
2508
2509delete_rport:
2510        transport_destroy_device(dev);
2511        spin_lock_irqsave(shost->host_lock, flags);
2512        list_del(&rport->peers);
2513        put_device(&shost->shost_gendev);        /* for fc_host->rport list */
2514        spin_unlock_irqrestore(shost->host_lock, flags);
2515        put_device(dev->parent);
2516        kfree(rport);
2517        return NULL;
2518}
2519
2520/**
2521 * fc_remote_port_add - notify fc transport of the existence of a remote FC port.
2522 * @shost:        scsi host the remote port is connected to.
2523 * @channel:        Channel on shost port connected to.
2524 * @ids:        The world wide names, fc address, and FC4 port
2525 *                roles for the remote port.
2526 *
2527 * The LLDD calls this routine to notify the transport of the existence
2528 * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn)
2529 * of the port, it's FC address (port_id), and the FC4 roles that are
2530 * active for the port.
2531 *
2532 * For ports that are FCP targets (aka scsi targets), the FC transport
2533 * maintains consistent target id bindings on behalf of the LLDD.
2534 * A consistent target id binding is an assignment of a target id to
2535 * a remote port identifier, which persists while the scsi host is
2536 * attached. The remote port can disappear, then later reappear, and
2537 * it's target id assignment remains the same. This allows for shifts
2538 * in FC addressing (if binding by wwpn or wwnn) with no apparent
2539 * changes to the scsi subsystem which is based on scsi host number and
2540 * target id values.  Bindings are only valid during the attachment of
2541 * the scsi host. If the host detaches, then later re-attaches, target
2542 * id bindings may change.
2543 *
2544 * This routine is responsible for returning a remote port structure.
2545 * The routine will search the list of remote ports it maintains
2546 * internally on behalf of consistent target id mappings. If found, the
2547 * remote port structure will be reused. Otherwise, a new remote port
2548 * structure will be allocated.
2549 *
2550 * Whenever a remote port is allocated, a new fc_remote_port class
2551 * device is created.
2552 *
2553 * Should not be called from interrupt context.
2554 *
2555 * Notes:
2556 *        This routine assumes no locks are held on entry.
2557 */
2558struct fc_rport *
2559fc_remote_port_add(struct Scsi_Host *shost, int channel,
2560        struct fc_rport_identifiers  *ids)
2561{
2562        struct fc_internal *fci = to_fc_internal(shost->transportt);
2563        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2564        struct fc_rport *rport;
2565        unsigned long flags;
2566        int match = 0;
2567
2568        /* ensure any stgt delete functions are done */
2569        fc_flush_work(shost);
2570
2571        /*
2572         * Search the list of "active" rports, for an rport that has been
2573         * deleted, but we've held off the real delete while the target
2574         * is in a "blocked" state.
2575         */
2576        spin_lock_irqsave(shost->host_lock, flags);
2577
2578        list_for_each_entry(rport, &fc_host->rports, peers) {
2579
2580                if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
2581                        (rport->channel == channel)) {
2582
2583                        switch (fc_host->tgtid_bind_type) {
2584                        case FC_TGTID_BIND_BY_WWPN:
2585                        case FC_TGTID_BIND_NONE:
2586                                if (rport->port_name == ids->port_name)
2587                                        match = 1;
2588                                break;
2589                        case FC_TGTID_BIND_BY_WWNN:
2590                                if (rport->node_name == ids->node_name)
2591                                        match = 1;
2592                                break;
2593                        case FC_TGTID_BIND_BY_ID:
2594                                if (rport->port_id == ids->port_id)
2595                                        match = 1;
2596                                break;
2597                        }
2598
2599                        if (match) {
2600
2601                                memcpy(&rport->node_name, &ids->node_name,
2602                                        sizeof(rport->node_name));
2603                                memcpy(&rport->port_name, &ids->port_name,
2604                                        sizeof(rport->port_name));
2605                                rport->port_id = ids->port_id;
2606
2607                                rport->port_state = FC_PORTSTATE_ONLINE;
2608                                rport->roles = ids->roles;
2609
2610                                spin_unlock_irqrestore(shost->host_lock, flags);
2611
2612                                if (fci->f->dd_fcrport_size)
2613                                        memset(rport->dd_data, 0,
2614                                                fci->f->dd_fcrport_size);
2615
2616                                /*
2617                                 * If we were not a target, cancel the
2618                                 * io terminate and rport timers, and
2619                                 * we're done.
2620                                 *
2621                                 * If we were a target, but our new role
2622                                 * doesn't indicate a target, leave the
2623                                 * timers running expecting the role to
2624                                 * change as the target fully logs in. If
2625                                 * it doesn't, the target will be torn down.
2626                                 *
2627                                 * If we were a target, and our role shows
2628                                 * we're still a target, cancel the timers
2629                                 * and kick off a scan.
2630                                 */
2631
2632                                /* was a target, not in roles */
2633                                if ((rport->scsi_target_id != -1) &&
2634                                    (!(ids->roles & FC_PORT_ROLE_FCP_TARGET)))
2635                                        return rport;
2636
2637                                /*
2638                                 * Stop the fail io and dev_loss timers.
2639                                 * If they flush, the port_state will
2640                                 * be checked and will NOOP the function.
2641                                 */
2642                                if (!cancel_delayed_work(&rport->fail_io_work))
2643                                        fc_flush_devloss(shost);
2644                                if (!cancel_delayed_work(&rport->dev_loss_work))
2645                                        fc_flush_devloss(shost);
2646
2647                                spin_lock_irqsave(shost->host_lock, flags);
2648
2649                                rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
2650                                                  FC_RPORT_DEVLOSS_PENDING);
2651
2652                                /* if target, initiate a scan */
2653                                if (rport->scsi_target_id != -1) {
2654                                        rport->flags |= FC_RPORT_SCAN_PENDING;
2655                                        scsi_queue_work(shost,
2656                                                        &rport->scan_work);
2657                                        spin_unlock_irqrestore(shost->host_lock,
2658                                                        flags);
2659                                        scsi_target_unblock(&rport->dev);
2660                                } else
2661                                        spin_unlock_irqrestore(shost->host_lock,
2662                                                        flags);
2663
2664                                return rport;
2665                        }
2666                }
2667        }
2668
2669        /*
2670         * Search the bindings array
2671         * Note: if never a FCP target, you won't be on this list
2672         */
2673        if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) {
2674
2675                /* search for a matching consistent binding */
2676
2677                list_for_each_entry(rport, &fc_host->rport_bindings,
2678                                        peers) {
2679                        if (rport->channel != channel)
2680                                continue;
2681
2682                        switch (fc_host->tgtid_bind_type) {
2683                        case FC_TGTID_BIND_BY_WWPN:
2684                                if (rport->port_name == ids->port_name)
2685                                        match = 1;
2686                                break;
2687                        case FC_TGTID_BIND_BY_WWNN:
2688                                if (rport->node_name == ids->node_name)
2689                                        match = 1;
2690                                break;
2691                        case FC_TGTID_BIND_BY_ID:
2692                                if (rport->port_id == ids->port_id)
2693                                        match = 1;
2694                                break;
2695                        case FC_TGTID_BIND_NONE: /* to keep compiler happy */
2696                                break;
2697                        }
2698
2699                        if (match) {
2700                                list_move_tail(&rport->peers, &fc_host->rports);
2701                                break;
2702                        }
2703                }
2704
2705                if (match) {
2706                        memcpy(&rport->node_name, &ids->node_name,
2707                                sizeof(rport->node_name));
2708                        memcpy(&rport->port_name, &ids->port_name,
2709                                sizeof(rport->port_name));
2710                        rport->port_id = ids->port_id;
2711                        rport->roles = ids->roles;
2712                        rport->port_state = FC_PORTSTATE_ONLINE;
2713                        rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
2714
2715                        if (fci->f->dd_fcrport_size)
2716                                memset(rport->dd_data, 0,
2717                                                fci->f->dd_fcrport_size);
2718
2719                        if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
2720                                /* initiate a scan of the target */
2721                                rport->flags |= FC_RPORT_SCAN_PENDING;
2722                                scsi_queue_work(shost, &rport->scan_work);
2723                                spin_unlock_irqrestore(shost->host_lock, flags);
2724                                scsi_target_unblock(&rport->dev);
2725                        } else
2726                                spin_unlock_irqrestore(shost->host_lock, flags);
2727
2728                        return rport;
2729                }
2730        }
2731
2732        spin_unlock_irqrestore(shost->host_lock, flags);
2733
2734        /* No consistent binding found - create new remote port entry */
2735        rport = fc_rport_create(shost, channel, ids);
2736
2737        return rport;
2738}
2739EXPORT_SYMBOL(fc_remote_port_add);
2740
2741
2742/**
2743 * fc_remote_port_delete - notifies the fc transport that a remote port is no longer in existence.
2744 * @rport:        The remote port that no longer exists
2745 *
2746 * The LLDD calls this routine to notify the transport that a remote
2747 * port is no longer part of the topology. Note: Although a port
2748 * may no longer be part of the topology, it may persist in the remote
2749 * ports displayed by the fc_host. We do this under 2 conditions:
2750 * 1) If the port was a scsi target, we delay its deletion by "blocking" it.
2751 *   This allows the port to temporarily disappear, then reappear without
2752 *   disrupting the SCSI device tree attached to it. During the "blocked"
2753 *   period the port will still exist.
2754 * 2) If the port was a scsi target and disappears for longer than we
2755 *   expect, we'll delete the port and the tear down the SCSI device tree
2756 *   attached to it. However, we want to semi-persist the target id assigned
2757 *   to that port if it eventually does exist. The port structure will
2758 *   remain (although with minimal information) so that the target id
2759 *   bindings remails.
2760 *
2761 * If the remote port is not an FCP Target, it will be fully torn down
2762 * and deallocated, including the fc_remote_port class device.
2763 *
2764 * If the remote port is an FCP Target, the port will be placed in a
2765 * temporary blocked state. From the LLDD's perspective, the rport no
2766 * longer exists. From the SCSI midlayer's perspective, the SCSI target
2767 * exists, but all sdevs on it are blocked from further I/O. The following
2768 * is then expected.
2769 *
2770 *   If the remote port does not return (signaled by a LLDD call to
2771 *   fc_remote_port_add()) within the dev_loss_tmo timeout, then the
2772 *   scsi target is removed - killing all outstanding i/o and removing the
2773 *   scsi devices attached ot it. The port structure will be marked Not
2774 *   Present and be partially cleared, leaving only enough information to
2775 *   recognize the remote port relative to the scsi target id binding if
2776 *   it later appears.  The port will remain as long as there is a valid
2777 *   binding (e.g. until the user changes the binding type or unloads the
2778 *   scsi host with the binding).
2779 *
2780 *   If the remote port returns within the dev_loss_tmo value (and matches
2781 *   according to the target id binding type), the port structure will be
2782 *   reused. If it is no longer a SCSI target, the target will be torn
2783 *   down. If it continues to be a SCSI target, then the target will be
2784 *   unblocked (allowing i/o to be resumed), and a scan will be activated
2785 *   to ensure that all luns are detected.
2786 *
2787 * Called from normal process context only - cannot be called from interrupt.
2788 *
2789 * Notes:
2790 *        This routine assumes no locks are held on entry.
2791 */
2792void
2793fc_remote_port_delete(struct fc_rport  *rport)
2794{
2795        struct Scsi_Host *shost = rport_to_shost(rport);
2796        int timeout = rport->dev_loss_tmo;
2797        unsigned long flags;
2798
2799        /*
2800         * No need to flush the fc_host work_q's, as all adds are synchronous.
2801         *
2802         * We do need to reclaim the rport scan work element, so eventually
2803         * (in fc_rport_final_delete()) we'll flush the scsi host work_q if
2804         * there's still a scan pending.
2805         */
2806
2807        spin_lock_irqsave(shost->host_lock, flags);
2808
2809        if (rport->port_state != FC_PORTSTATE_ONLINE) {
2810                spin_unlock_irqrestore(shost->host_lock, flags);
2811                return;
2812        }
2813
2814        /*
2815         * In the past, we if this was not an FCP-Target, we would
2816         * unconditionally just jump to deleting the rport.
2817         * However, rports can be used as node containers by the LLDD,
2818         * and its not appropriate to just terminate the rport at the
2819         * first sign of a loss in connectivity. The LLDD may want to
2820         * send ELS traffic to re-validate the login. If the rport is
2821         * immediately deleted, it makes it inappropriate for a node
2822         * container.
2823         * So... we now unconditionally wait dev_loss_tmo before
2824         * destroying an rport.
2825         */
2826
2827        rport->port_state = FC_PORTSTATE_BLOCKED;
2828
2829        rport->flags |= FC_RPORT_DEVLOSS_PENDING;
2830
2831        spin_unlock_irqrestore(shost->host_lock, flags);
2832
2833        if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR &&
2834            shost->active_mode & MODE_TARGET)
2835                fc_tgt_it_nexus_destroy(shost, (unsigned long)rport);
2836
2837        scsi_target_block(&rport->dev);
2838
2839        /* see if we need to kill io faster than waiting for device loss */
2840        if ((rport->fast_io_fail_tmo != -1) &&
2841            (rport->fast_io_fail_tmo < timeout))
2842                fc_queue_devloss_work(shost, &rport->fail_io_work,
2843                                        rport->fast_io_fail_tmo * HZ);
2844
2845        /* cap the length the devices can be blocked until they are deleted */
2846        fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ);
2847}
2848EXPORT_SYMBOL(fc_remote_port_delete);
2849
2850/**
2851 * fc_remote_port_rolechg - notifies the fc transport that the roles on a remote may have changed.
2852 * @rport:        The remote port that changed.
2853 * @roles:      New roles for this port.
2854 *
2855 * Description: The LLDD calls this routine to notify the transport that the
2856 * roles on a remote port may have changed. The largest effect of this is
2857 * if a port now becomes a FCP Target, it must be allocated a
2858 * scsi target id.  If the port is no longer a FCP target, any
2859 * scsi target id value assigned to it will persist in case the
2860 * role changes back to include FCP Target. No changes in the scsi
2861 * midlayer will be invoked if the role changes (in the expectation
2862 * that the role will be resumed. If it doesn't normal error processing
2863 * will take place).
2864 *
2865 * Should not be called from interrupt context.
2866 *
2867 * Notes:
2868 *        This routine assumes no locks are held on entry.
2869 */
2870void
2871fc_remote_port_rolechg(struct fc_rport  *rport, u32 roles)
2872{
2873        struct Scsi_Host *shost = rport_to_shost(rport);
2874        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2875        unsigned long flags;
2876        int create = 0;
2877        int ret;
2878
2879        spin_lock_irqsave(shost->host_lock, flags);
2880        if (roles & FC_PORT_ROLE_FCP_TARGET) {
2881                if (rport->scsi_target_id == -1) {
2882                        rport->scsi_target_id = fc_host->next_target_id++;
2883                        create = 1;
2884                } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
2885                        create = 1;
2886        } else if (shost->active_mode & MODE_TARGET) {
2887                ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport,
2888                                             (char *)&rport->node_name);
2889                if (ret)
2890                        printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n",
2891                               ret);
2892        }
2893
2894        rport->roles = roles;
2895
2896        spin_unlock_irqrestore(shost->host_lock, flags);
2897
2898        if (create) {
2899                /*
2900                 * There may have been a delete timer running on the
2901                 * port. Ensure that it is cancelled as we now know
2902                 * the port is an FCP Target.
2903                 * Note: we know the rport is exists and in an online
2904                 *  state as the LLDD would not have had an rport
2905                 *  reference to pass us.
2906                 *
2907                 * Take no action on the del_timer failure as the state
2908                 * machine state change will validate the
2909                 * transaction.
2910                 */
2911                if (!cancel_delayed_work(&rport->fail_io_work))
2912                        fc_flush_devloss(shost);
2913                if (!cancel_delayed_work(&rport->dev_loss_work))
2914                        fc_flush_devloss(shost);
2915
2916                spin_lock_irqsave(shost->host_lock, flags);
2917                rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
2918                                  FC_RPORT_DEVLOSS_PENDING);
2919                spin_unlock_irqrestore(shost->host_lock, flags);
2920
2921                /* ensure any stgt delete functions are done */
2922                fc_flush_work(shost);
2923
2924                /* initiate a scan of the target */
2925                spin_lock_irqsave(shost->host_lock, flags);
2926                rport->flags |= FC_RPORT_SCAN_PENDING;
2927                scsi_queue_work(shost, &rport->scan_work);
2928                spin_unlock_irqrestore(shost->host_lock, flags);
2929                scsi_target_unblock(&rport->dev);
2930        }
2931}
2932EXPORT_SYMBOL(fc_remote_port_rolechg);
2933
2934/**
2935 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port.
2936 * @work:        rport target that failed to reappear in the allotted time.
2937 *
2938 * Description: An attempt to delete a remote port blocks, and if it fails
2939 *              to return in the allotted time this gets called.
2940 */
2941static void
2942fc_timeout_deleted_rport(struct work_struct *work)
2943{
2944        struct fc_rport *rport =
2945                container_of(work, struct fc_rport, dev_loss_work.work);
2946        struct Scsi_Host *shost = rport_to_shost(rport);
2947        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2948        unsigned long flags;
2949
2950        spin_lock_irqsave(shost->host_lock, flags);
2951
2952        rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
2953
2954        /*
2955         * If the port is ONLINE, then it came back. If it was a SCSI
2956         * target, validate it still is. If not, tear down the
2957         * scsi_target on it.
2958         */
2959        if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
2960            (rport->scsi_target_id != -1) &&
2961            !(rport->roles & FC_PORT_ROLE_FCP_TARGET)) {
2962                dev_printk(KERN_ERR, &rport->dev,
2963                        "blocked FC remote port time out: no longer"
2964                        " a FCP target, removing starget\n");
2965                spin_unlock_irqrestore(shost->host_lock, flags);
2966                scsi_target_unblock(&rport->dev);
2967                fc_queue_work(shost, &rport->stgt_delete_work);
2968                return;
2969        }
2970
2971        /* NOOP state - we're flushing workq's */
2972        if (rport->port_state != FC_PORTSTATE_BLOCKED) {
2973                spin_unlock_irqrestore(shost->host_lock, flags);
2974                dev_printk(KERN_ERR, &rport->dev,
2975                        "blocked FC remote port time out: leaving"
2976                        " rport%s alone\n",
2977                        (rport->scsi_target_id != -1) ?  " and starget" : "");
2978                return;
2979        }
2980
2981        if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) ||
2982            (rport->scsi_target_id == -1)) {
2983                list_del(&rport->peers);
2984                rport->port_state = FC_PORTSTATE_DELETED;
2985                dev_printk(KERN_ERR, &rport->dev,
2986                        "blocked FC remote port time out: removing"
2987                        " rport%s\n",
2988                        (rport->scsi_target_id != -1) ?  " and starget" : "");
2989                fc_queue_work(shost, &rport->rport_delete_work);
2990                spin_unlock_irqrestore(shost->host_lock, flags);
2991                return;
2992        }
2993
2994        dev_printk(KERN_ERR, &rport->dev,
2995                "blocked FC remote port time out: removing target and "
2996                "saving binding\n");
2997
2998        list_move_tail(&rport->peers, &fc_host->rport_bindings);
2999
3000        /*
3001         * Note: We do not remove or clear the hostdata area. This allows
3002         *   host-specific target data to persist along with the
3003         *   scsi_target_id. It's up to the host to manage it's hostdata area.
3004         */
3005
3006        /*
3007         * Reinitialize port attributes that may change if the port comes back.
3008         */
3009        rport->maxframe_size = -1;
3010        rport->supported_classes = FC_COS_UNSPECIFIED;
3011        rport->roles = FC_PORT_ROLE_UNKNOWN;
3012        rport->port_state = FC_PORTSTATE_NOTPRESENT;
3013        rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
3014
3015        /* remove the identifiers that aren't used in the consisting binding */
3016        switch (fc_host->tgtid_bind_type) {
3017        case FC_TGTID_BIND_BY_WWPN:
3018                rport->node_name = -1;
3019                rport->port_id = -1;
3020                break;
3021        case FC_TGTID_BIND_BY_WWNN:
3022                rport->port_name = -1;
3023                rport->port_id = -1;
3024                break;
3025        case FC_TGTID_BIND_BY_ID:
3026                rport->node_name = -1;
3027                rport->port_name = -1;
3028                break;
3029        case FC_TGTID_BIND_NONE:        /* to keep compiler happy */
3030                break;
3031        }
3032
3033        /*
3034         * As this only occurs if the remote port (scsi target)
3035         * went away and didn't come back - we'll remove
3036         * all attached scsi devices.
3037         */
3038        spin_unlock_irqrestore(shost->host_lock, flags);
3039
3040        scsi_target_unblock(&rport->dev);
3041        fc_queue_work(shost, &rport->stgt_delete_work);
3042}
3043
3044/**
3045 * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a disconnected SCSI target.
3046 * @work:        rport to terminate io on.
3047 *
3048 * Notes: Only requests the failure of the io, not that all are flushed
3049 *    prior to returning.
3050 */
3051static void
3052fc_timeout_fail_rport_io(struct work_struct *work)
3053{
3054        struct fc_rport *rport =
3055                container_of(work, struct fc_rport, fail_io_work.work);
3056
3057        if (rport->port_state != FC_PORTSTATE_BLOCKED)
3058                return;
3059
3060        rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT;
3061        fc_terminate_rport_io(rport);
3062}
3063
3064/**
3065 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
3066 * @work:        remote port to be scanned.
3067 */
3068static void
3069fc_scsi_scan_rport(struct work_struct *work)
3070{
3071        struct fc_rport *rport =
3072                container_of(work, struct fc_rport, scan_work);
3073        struct Scsi_Host *shost = rport_to_shost(rport);
3074        struct fc_internal *i = to_fc_internal(shost->transportt);
3075        unsigned long flags;
3076
3077        if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
3078            (rport->roles & FC_PORT_ROLE_FCP_TARGET) &&
3079            !(i->f->disable_target_scan)) {
3080                scsi_scan_target(&rport->dev, rport->channel,
3081                        rport->scsi_target_id, SCAN_WILD_CARD, 1);
3082        }
3083
3084        spin_lock_irqsave(shost->host_lock, flags);
3085        rport->flags &= ~FC_RPORT_SCAN_PENDING;
3086        spin_unlock_irqrestore(shost->host_lock, flags);
3087}
3088
3089
3090/**
3091 * fc_vport_setup - allocates and creates a FC virtual port.
3092 * @shost:        scsi host the virtual port is connected to.
3093 * @channel:        Channel on shost port connected to.
3094 * @pdev:        parent device for vport
3095 * @ids:        The world wide names, FC4 port roles, etc for
3096 *              the virtual port.
3097 * @ret_vport:        The pointer to the created vport.
3098 *
3099 * Allocates and creates the vport structure, calls the parent host
3100 * to instantiate the vport, the completes w/ class and sysfs creation.
3101 *
3102 * Notes:
3103 *        This routine assumes no locks are held on entry.
3104 */
3105static int
3106fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
3107        struct fc_vport_identifiers  *ids, struct fc_vport **ret_vport)
3108{
3109        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3110        struct fc_internal *fci = to_fc_internal(shost->transportt);
3111        struct fc_vport *vport;
3112        struct device *dev;
3113        unsigned long flags;
3114        size_t size;
3115        int error;
3116
3117        *ret_vport = NULL;
3118
3119        if ( ! fci->f->vport_create)
3120                return -ENOENT;
3121
3122        size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size);
3123        vport = kzalloc(size, GFP_KERNEL);
3124        if (unlikely(!vport)) {
3125                printk(KERN_ERR "%s: allocation failure\n", __func__);
3126                return -ENOMEM;
3127        }
3128
3129        vport->vport_state = FC_VPORT_UNKNOWN;
3130        vport->vport_last_state = FC_VPORT_UNKNOWN;
3131        vport->node_name = ids->node_name;
3132        vport->port_name = ids->port_name;
3133        vport->roles = ids->roles;
3134        vport->vport_type = ids->vport_type;
3135        if (fci->f->dd_fcvport_size)
3136                vport->dd_data = &vport[1];
3137        vport->shost = shost;
3138        vport->channel = channel;
3139        vport->flags = FC_VPORT_CREATING;
3140        INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete);
3141
3142        spin_lock_irqsave(shost->host_lock, flags);
3143
3144        if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) {
3145                spin_unlock_irqrestore(shost->host_lock, flags);
3146                kfree(vport);
3147                return -ENOSPC;
3148        }
3149        fc_host->npiv_vports_inuse++;
3150        vport->number = fc_host->next_vport_number++;
3151        list_add_tail(&vport->peers, &fc_host->vports);
3152        get_device(&shost->shost_gendev);        /* for fc_host->vport list */
3153
3154        spin_unlock_irqrestore(shost->host_lock, flags);
3155
3156        dev = &vport->dev;
3157        device_initialize(dev);                        /* takes self reference */
3158        dev->parent = get_device(pdev);                /* takes parent reference */
3159        dev->release = fc_vport_dev_release;
3160        sprintf(dev->bus_id, "vport-%d:%d-%d",
3161                shost->host_no, channel, vport->number);
3162        transport_setup_device(dev);
3163
3164        error = device_add(dev);
3165        if (error) {
3166                printk(KERN_ERR "FC Virtual Port device_add failed\n");
3167                goto delete_vport;
3168        }
3169        transport_add_device(dev);
3170        transport_configure_device(dev);
3171
3172        error = fci->f->vport_create(vport, ids->disable);
3173        if (error) {
3174                printk(KERN_ERR "FC Virtual Port LLDD Create failed\n");
3175                goto delete_vport_all;
3176        }
3177
3178        /*
3179         * if the parent isn't the physical adapter's Scsi_Host, ensure
3180         * the Scsi_Host at least contains ia symlink to the vport.
3181         */
3182        if (pdev != &shost->shost_gendev) {
3183                error = sysfs_create_link(&shost->shost_gendev.kobj,
3184                                 &dev->kobj, dev->bus_id);
3185                if (error)
3186                        printk(KERN_ERR
3187                                "%s: Cannot create vport symlinks for "
3188                                "%s, err=%d\n",
3189                                __func__, dev->bus_id, error);
3190        }
3191        spin_lock_irqsave(shost->host_lock, flags);
3192        vport->flags &= ~FC_VPORT_CREATING;
3193        spin_unlock_irqrestore(shost->host_lock, flags);
3194
3195        dev_printk(KERN_NOTICE, pdev,
3196                        "%s created via shost%d channel %d\n", dev->bus_id,
3197                        shost->host_no, channel);
3198
3199        *ret_vport = vport;
3200
3201        return 0;
3202
3203delete_vport_all:
3204        transport_remove_device(dev);
3205        device_del(dev);
3206delete_vport:
3207        transport_destroy_device(dev);
3208        spin_lock_irqsave(shost->host_lock, flags);
3209        list_del(&vport->peers);
3210        put_device(&shost->shost_gendev);        /* for fc_host->vport list */
3211        fc_host->npiv_vports_inuse--;
3212        spin_unlock_irqrestore(shost->host_lock, flags);
3213        put_device(dev->parent);
3214        kfree(vport);
3215
3216        return error;
3217}
3218
3219/**
3220 * fc_vport_create - Admin App or LLDD requests creation of a vport
3221 * @shost:        scsi host the virtual port is connected to.
3222 * @channel:        channel on shost port connected to.
3223 * @ids:        The world wide names, FC4 port roles, etc for
3224 *              the virtual port.
3225 *
3226 * Notes:
3227 *        This routine assumes no locks are held on entry.
3228 */
3229struct fc_vport *
3230fc_vport_create(struct Scsi_Host *shost, int channel,
3231        struct fc_vport_identifiers *ids)
3232{
3233        int stat;
3234        struct fc_vport *vport;
3235
3236        stat = fc_vport_setup(shost, channel, &shost->shost_gendev,
3237                 ids, &vport);
3238        return stat ? NULL : vport;
3239}
3240EXPORT_SYMBOL(fc_vport_create);
3241
3242/**
3243 * fc_vport_terminate - Admin App or LLDD requests termination of a vport
3244 * @vport:        fc_vport to be terminated
3245 *
3246 * Calls the LLDD vport_delete() function, then deallocates and removes
3247 * the vport from the shost and object tree.
3248 *
3249 * Notes:
3250 *        This routine assumes no locks are held on entry.
3251 */
3252int
3253fc_vport_terminate(struct fc_vport *vport)
3254{
3255        struct Scsi_Host *shost = vport_to_shost(vport);
3256        struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3257        struct fc_internal *i = to_fc_internal(shost->transportt);
3258        struct device *dev = &vport->dev;
3259        unsigned long flags;
3260        int stat;
3261
3262        spin_lock_irqsave(shost->host_lock, flags);
3263        if (vport->flags & FC_VPORT_CREATING) {
3264                spin_unlock_irqrestore(shost->host_lock, flags);
3265                return -EBUSY;
3266        }
3267        if (vport->flags & (FC_VPORT_DEL)) {
3268                spin_unlock_irqrestore(shost->host_lock, flags);
3269                return -EALREADY;
3270        }
3271        vport->flags |= FC_VPORT_DELETING;
3272        spin_unlock_irqrestore(shost->host_lock, flags);
3273
3274        if (i->f->vport_delete)
3275                stat = i->f->vport_delete(vport);
3276        else
3277                stat = -ENOENT;
3278
3279        spin_lock_irqsave(shost->host_lock, flags);
3280        vport->flags &= ~FC_VPORT_DELETING;
3281        if (!stat) {
3282                vport->flags |= FC_VPORT_DELETED;
3283                list_del(&vport->peers);
3284                fc_host->npiv_vports_inuse--;
3285                put_device(&shost->shost_gendev);  /* for fc_host->vport list */
3286        }
3287        spin_unlock_irqrestore(shost->host_lock, flags);
3288
3289        if (stat)
3290                return stat;
3291
3292        if (dev->parent != &shost->shost_gendev)
3293                sysfs_remove_link(&shost->shost_gendev.kobj, dev->bus_id);
3294        transport_remove_device(dev);
3295        device_del(dev);
3296        transport_destroy_device(dev);
3297
3298        /*
3299         * Removing our self-reference should mean our
3300         * release function gets called, which will drop the remaining
3301         * parent reference and free the data structure.
3302         */
3303        put_device(dev);                        /* for self-reference */
3304
3305        return 0; /* SUCCESS */
3306}
3307EXPORT_SYMBOL(fc_vport_terminate);
3308
3309/**
3310 * fc_vport_sched_delete - workq-based delete request for a vport
3311 * @work:        vport to be deleted.
3312 */
3313static void
3314fc_vport_sched_delete(struct work_struct *work)
3315{
3316        struct fc_vport *vport =
3317                container_of(work, struct fc_vport, vport_delete_work);
3318        int stat;
3319
3320        stat = fc_vport_terminate(vport);
3321        if (stat)
3322                dev_printk(KERN_ERR, vport->dev.parent,
3323                        "%s: %s could not be deleted created via "
3324                        "shost%d channel %d - error %d\n", __func__,
3325                        vport->dev.bus_id, vport->shost->host_no,
3326                        vport->channel, stat);
3327}
3328
3329
3330/* Original Author:  Martin Hicks */
3331MODULE_AUTHOR("James Smart");
3332MODULE_DESCRIPTION("FC Transport Attributes");
3333MODULE_LICENSE("GPL");
3334
3335module_init(fc_transport_init);
3336module_exit(fc_transport_exit);