~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/scsi/scsi_transport_fc.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

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