1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _FCTL_PRIVATE_H
#define _FCTL_PRIVATE_H
#include <sys/note.h>
#include <sys/fibre-channel/impl/fc_ulpif.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Stuff strictly internal to fctl that
* isn't exposed to any other modules.
*/
#define PWWN_HASH_TABLE_SIZE (32) /* 2^n */
#define D_ID_HASH_TABLE_SIZE (32) /* 2^n */
#define NWWN_HASH_TABLE_SIZE (32) /* 2^n */
#define HASH_FUNC(key, size) ((key) & (size - 1))
#define WWN_HASH_KEY(x) ((x)[0] + (x)[1] + (x)[2] +\
(x)[3] + (x)[4] + (x)[5] +\
(x)[6] + (x)[7])
#define D_ID_HASH_FUNC(x, size) ((x) & (size - 1))
#define FC4_TYPE_WORD_POS(x) ((uchar_t)(x) >> 5)
#define FC4_TYPE_BIT_POS(x) ((uchar_t)(x) & 0x1F)
#define FC_ACTION_INVALID -1
#define FC_REASON_INVALID -1
#define FC_EXPLN_INVALID -1
/*
* Internally translated and used state change values to ULPs
*/
#define FC_ULP_STATEC_DONT_CARE 0
#define FC_ULP_STATEC_ONLINE 1
#define FC_ULP_STATEC_OFFLINE 2
#define FC_ULP_STATEC_OFFLINE_TIMEOUT 3
#define FC_ULP_ADD_RETRY_COUNT 90
#define FC_MAX_TRACE_BUF_LEN 512
#define FC_NPIV_MAX_PORT 255
/*
* port_dstate values
*/
#define ULP_PORT_ATTACH 0x01
#define ULP_PORT_SUSPEND 0x02
#define ULP_PORT_POWER_DOWN 0x04
#define ULP_PORT_BUSY 0x08
#define FCTL_DISALLOW_CALLBACKS(x) (!((x) & ULP_PORT_ATTACH) ||\
((x) & ULP_PORT_BUSY))
typedef struct ulp_ports {
struct ulp_ports *port_next;
int port_dstate;
uint32_t port_statec;
kmutex_t port_mutex;
struct fc_local_port *port_handle;
} fc_ulp_ports_t;
typedef struct ulp_module {
struct ulp_module *mod_next;
fc_ulp_modinfo_t *mod_info;
fc_ulp_ports_t *mod_ports;
} fc_ulp_module_t;
typedef struct ulp_list {
fc_ulp_modinfo_t *ulp_info;
struct ulp_list *ulp_next;
} fc_ulp_list_t;
typedef struct fca_port {
struct fca_port *port_next;
struct fc_local_port *port_handle;
} fc_fca_port_t;
typedef struct timed_counter {
struct timed_counter *sig;
uint32_t counter;
uint32_t max_value;
boolean_t maxed_out;
kmutex_t mutex;
boolean_t active;
clock_t timer;
timeout_id_t tid;
} timed_counter_t;
/*
* Struct describing a remote node. A remote node is associated with one
* or more remote ports (fc_remote_port_t structs) that are all accessible
* through one local port (fc_local_port_t struct).
*
* Each fc_remote_node_t struct is also referenced by nwwn in the global
* nwwn_hash_table[] list.
*/
typedef struct fc_remote_node {
/*
* Mutex lock to protect access to all members of this struct.
* Current implementation dictates acquisition of fd_mutex before
* pd_mutex can be acquired (when both locks must be acquired).
*/
kmutex_t fd_mutex;
/* Node WWN for the remote node */
la_wwn_t fd_node_name;
/*
* This is the number of (active) fc_remote_port_t structs that
* are associated with this remote node.
*/
int fd_numports;
/*
* Tracks whether this struct is "valid" or "invalid", using the
* FC_REMOTE_NODE_* values given above.
*/
int fd_flags;
/* Linked list of remote ports associated with this remote node. */
struct fc_remote_port *fd_portlistp;
uchar_t fd_ipa[8]; /* Initial proc assoc */
uchar_t fd_vv[16]; /* Vendor Version */
uchar_t fd_snn_len; /* node symbolic name len */
uchar_t fd_snn[255]; /* node symbolic name */
} fc_remote_node_t;
/*
* Stack depth for troubleshooting (only used in debug code)
*/
#define FC_STACK_DEPTH 14
/*
* The fc_remote_port_t struct represents a remote FC port that is
* accessible via the local FC port (fc_local_port_t). Each remote
* FC port is associated with one FC local port (fc_local_port_t,
* above) and one remote FC node (fc_remote_node_t, see below).
* fc_remote_port_t structs are created and destroyed as needed to
* correspond with changing conditions out on the link.
*/
typedef struct fc_remote_port {
/*
* Ah, the infamous 'pd_mutex' that has given developers so much
* joy over the years....
* (Gotta love the original, extremely helpful comment.)
*/
kmutex_t pd_mutex; /* mutex */
fc_portid_t pd_port_id; /* Port Identifier */
la_wwn_t pd_port_name; /* the port WWN */
/*
* Reference count of the # of logins initiated by a ULP
* (i.e., this is the # of ULPs accessing the struct). See
* fp_plogi_group() for more info.
*/
int pd_login_count;
/*
* This appears to track the login state of the remote FC port.
* Used with the PORT_DEVICE_* macros in fc_appif.h.
*/
uint32_t pd_state;
/*
* Link pointers for the port wwn and D_ID hash lists. These point
* to the next remote port in the current hash chain.
*/
struct fc_remote_port *pd_wwn_hnext;
struct fc_remote_port *pd_did_hnext;
/*
* Link pointer for list of *all* fc_remote_port_t structs
* associated with the same fc_local_port_t struct.
*/
struct fc_remote_port *pd_port_next;
/*
* Pointer to the fc_remote_node_t struct for the remote node
* associated with the remote port.
*/
struct fc_remote_node *pd_remote_nodep;
/* port type for the remote port */
fc_porttype_t pd_porttype;
fc_hardaddr_t pd_hard_addr; /* Hard Address */
/*
* Back pointer to the fc_local_port_t struct for the local port
* associated with this remote port.
*/
struct fc_local_port *pd_port;
/*
* (Sigh) this actually doesn't have anything to do with the "type"
* of the remote port per se. It's really more an indicator of the
* most recently known state/status of the remote port. It's intended
* to help figure out if/how the remote port has either gone away or
* changed somehow after an event has occurred on the link.
* There also seems to be some connection to the "changed map".
*
* The legal values for this are the PORT_DEVICE_* definitions
* earlier in this file.
*/
uchar_t pd_type; /* new or old */
/*
* This tracks the current state/status of a login attempt at the
* remote port. Legal values are given above.
* See also the pd_state field.
*/
uchar_t pd_flags; /* login in progress */
uchar_t pd_login_class; /* Logi Class */
/* Legal values are given above (beware of the mipselling) */
uchar_t pd_recepient; /* who did PLOGI? */
uchar_t pd_ip_addr[8]; /* IP address */
uint32_t pd_fc4types[8]; /* FC-4 types */
uint32_t pd_cos; /* class of service */
struct common_service pd_csp; /* common service */
struct service_param pd_clsp1; /* Class 1 */
struct service_param pd_clsp2; /* Class 2 */
struct service_param pd_clsp3; /* Class 3 */
/* This is _SO_ private that even we don't use it */
caddr_t pd_private; /* private data */
/*
* This is a count of the number of references to (or holds on)
* this remote port.
*/
int pd_ref_count; /* number of references */
/*
* Re-login disable for FCP-2 error recovery. This is intended to
* help with tape devices when an RSCN or Link Reset occurs during
* a long write operations (like backup). fp's default action is
* to try to log in again, but that forces a rewind on the LUN
* and corrupts its state.
*
* The legal bit values are given below. Some specific definitions
* are as follows:
*
* PD_IN_DID_QUEUE: The fc_remote_port_t is present in the d_id
* hash list of the associated fc_local_port_t. (This
* is apparently meant to cover some races).
* PD_LOGGED_OUT: This is a directive to ignore the NORELOGIN if
* an actual logout occurred
*/
uchar_t pd_aux_flags; /* relogin disable */
uchar_t pd_spn_len; /* length of sym name */
char pd_spn[255]; /* symbolic port name */
/*
* Count of the # of unsolicited LOGOs received. See the definition
* of FC_LOGO_TOLERANCE_LIMIT in fp.c.
*/
timed_counter_t pd_logo_tc;
#ifdef DEBUG
int pd_w_depth; /* for WWN hash table */
pc_t pd_w_stack[FC_STACK_DEPTH];
int pd_d_depth; /* for D_ID hash table */
pc_t pd_d_stack[FC_STACK_DEPTH];
#endif
} fc_remote_port_t;
/*
* Structs for the global nwwn_hash_table[] entries.
*
* At _init() time, fctl allocates an array of fctl_nwwn_list_t structs that
* has nwwn_table_size entries. The hash_head member anchors a linked
* list of fctl_nwwn_elem_t structs that are linked via the fne_next pointer.
* Each fctl_nwwn_elem_t also contains a pointer to one fc_remote_node_t struct.
*/
typedef struct fctl_nwwn_elem fctl_nwwn_elem_t;
struct fctl_nwwn_elem {
fctl_nwwn_elem_t *fne_nextp;
fc_remote_node_t *fne_nodep;
};
typedef struct fctl_nwwn_list {
fctl_nwwn_elem_t *fnl_headp;
} fctl_nwwn_list_t;
typedef struct fc_errmap {
int fc_errno;
char *fc_errname;
} fc_errmap_t;
typedef struct fc_pkt_reason {
int reason_val;
char *reason_msg;
} fc_pkt_reason_t;
typedef struct fc_pkt_action {
int action_val;
char *action_msg;
} fc_pkt_action_t;
typedef struct fc_pkt_expln {
int expln_val;
char *expln_msg;
} fc_pkt_expln_t;
typedef struct fc_pkt_error {
int pkt_state;
char *pkt_msg;
fc_pkt_reason_t *pkt_reason;
fc_pkt_action_t *pkt_action;
fc_pkt_expln_t *pkt_expln;
} fc_pkt_error_t;
/*
* Values for the fd_flags field in the fc_remote_node_t struct.
* Note, the code seems to rely on the struct initialization using
* kmem_zalloc() to set all the bits to zero, since FC_REMOTE_NODE_INVALID
* is never explicitly set anywhere.
*/
#define FC_REMOTE_NODE_INVALID 0
#define FC_REMOTE_NODE_VALID 1
/*
* Values for the pd_flags field in the fc_remote_port_t struct. These
* are used in a _lot_ of places. NOTE: these are values, not bit flags.
*/
#define PD_IDLE 0x00
#define PD_ELS_IN_PROGRESS 0x01
#define PD_ELS_MARK 0x02
/*
* Bit values for the pd_aux_flags field in the fc_remote_port_t struct.
*/
#define PD_IN_DID_QUEUE 0x01 /* The fc_remote_port_t is present */
/* in the D_ID hash list of the */
/* associated fc_local_port_t. (This */
/* is apparently meant to narrow */
/* some race windows). */
#define PD_DISABLE_RELOGIN 0x02
#define PD_NEEDS_REMOVAL 0x04
#define PD_LOGGED_OUT 0x08 /* This is a directive to ignore */
/* the NORELOGIN if an actual logout */
/* occurred */
#define PD_GIVEN_TO_ULPS 0x10 /* A reference to this pd has been */
/* given to one or more ULPs. */
/*
* Values for the pd_recepient field in the fc_remote_port_t struct.
* Tries to describe where a PLOGI attempt originated.
*/
#define PD_PLOGI_INITIATOR 0
#define PD_PLOGI_RECEPIENT 1
/*
* The fc_local_port_t struct represents a local FC port. It is the softstate
* struct for each fp instance, so it comes into existence at DDI_ATTACH
* and is deleted during DDI_DETACH.
*/
typedef struct fc_local_port {
/*
* Mutex to protect certain data fields in this struct.
*/
kmutex_t fp_mutex;
/*
* fp_state sort of tracks the state of the link at the local port.
* The actual 'state' is kept in the lower byte, and the port speed
* is kept in the next most significant byte. The code makes
* extensive use of the FC_PORT_SPEED_MASK() and FC_PORT_STATE_MASK()
* macros to separate these two items. The current link topology
* is actually kept separately in the fp_topology field.
* The legal values for fp_state are given above.
*/
volatile uint32_t fp_state;
/*
* The S_ID for the local port. See fc_types.h for the fc_portid_t
* definition.
*/
fc_portid_t fp_port_id;
/*
* Opaque reference handle for the local port device. This value
* is supplied by the FCA driver and is passed unaltered to
* various FCA driver entry point functions.
*/
opaque_t fp_fca_handle;
/* Entry point vectors for the FCA driver at this FC port */
struct fca_tran *fp_fca_tran;
/*
* fp's homegrown "job" threading mechanism (not a Solaris DDI taskq).
*
* Head/tail pointers for a linked list of requests to be executed
* in a driver-private thread. One thread per fc_local_port_t struct.
* The thread is created during DDI_ATTACH for the instance.
*/
struct job_request *fp_job_head;
struct job_request *fp_job_tail;
struct fp_cmd *fp_wait_head; /* waitQ head */
struct fp_cmd *fp_wait_tail; /* waitQ tail */
/*
* Current port topology. Uses the FC_TOP_* values defined in
* fc_appif.h. This is used with the FC_IS_TOP_SWITCH() macro and
* is also used with the FC_TOP_EXTERNAL() macro in the ULPs.
*/
uint32_t fp_topology; /* topology */
/*
* The fp_task and fp_last_task fields are used mainly in the
* fp_job_handler() function. These are used to indicate when a job
* is executing. They also allow a second job to be issued while
* the current job is still in progress, but only one level of nesting
* is permitted.
*
* The legal values for these fields are given in fp.h
*
* This should not be confused with the Solaris DDI taskq mechanism,
* altho also fp makes use of that in some places (just to keep life
* interesting).
*/
int fp_task; /* current task */
int fp_last_task; /* last task */
/*
* fp_soft_state actually tracks the progression of the fp driver
* in various code paths, particularly in attach, detach, suspend,
* resume, and state change callbacks.
*
* The values for this are defined in fc_portif.h.
*
* This is sometimes used in conjunction with the fp_statec_busy
* field (see below), but there is no direct, 1-to-1 correlation
* in how these are used together.
*/
volatile uint16_t fp_soft_state;
/*
* Software restoration bit fields for (PM)SUSPEND/(PM)RESUME (??)
* Legal values are FP_RESTORE_* in fp.h
*/
uint16_t fp_restore;
/*
* Open/Close bit flags. Used in fp_open(), fp_close(), fp_ioctl()
* and fp_fciocmd(). See fp.h for legal values.
*/
uchar_t fp_flag; /* open/close flag */
uchar_t fp_verbose;
uchar_t fp_ns_login_class; /* NS Logi Class */
uchar_t fp_sym_port_namelen; /* Symb port name len */
uint32_t fp_cos; /* class of service */
/*
* Base pointer for hash table of fc_remote_port_t structs (remote
* ports) accessible thru the local port. The table is hashed by
* the D_ID of the remote port.
*/
struct d_id_hash *fp_did_table;
/*
* Base pointer for hash table of fc_remote_port_t structs (remote
* ports) accessible thru the local port. The table is hashed by
* the port WWN of the remote port.
*/
struct pwwn_hash *fp_pwwn_table;
struct kmem_cache *fp_pkt_cache;
int fp_out_fpcmds; /* outstanding fp_cmd # */
/*
* fp_statec_busy tracks the progression of state change
* callbacks within the fp driver. It follows unsolicited callbacks
* and things like the port startup which happens during the attach.
* The value increments when a state change is active and decrements
* when it completes.
*
* The benefit of this is that we should be processing only the
* latest state change and drop the existing one. Coalescing of
* multiple outstanding state changes is NOT performed.
*
* This is accessed in many places in the code, and also is buried
* in some macros (see fp_soft_state above).
*
* IMPORTANT: The code currently permits nested state changes,
* and there is no limitation on the allowed level of nesting.
*/
int fp_statec_busy;
int fp_port_num; /* port number */
struct fp_cmd *fp_els_resp_pkt; /* ready response pkt */
int fp_instance; /* instance number */
/*
* Flag to indicate whether or not the ULP attach is in progress. Used
* to synchronize execution of various functions. Seems intended to
* have a value of either zero or one.
*/
int fp_ulp_attach; /* ULP attach done ? */
int fp_dev_count; /* number of devices */
int fp_ptpt_master; /* my WWN is greater */
int fp_ulp_nload; /* count of ULPs */
int fp_total_devices; /* total count */
/*
* Another "busy/not busy" flag. Value is either 0 or 1.
*/
int fp_els_resp_pkt_busy;
/*
* This is the "state" of the link on the local port, as reported
* by the underlying FCA driver at bind time. This uses the same
* values as fp_state above, including FC_STATE_OFFLINE, FC_STATE_LOOP,
* and FC_PORT_STATE_MASK(port->fp_bind_state).
*/
uint32_t fp_bind_state; /* at bind time */
/*
* Bit field of various parameterized behaviors for the local port.
* CAUTION: there is also an fp global variable called "fp_options"
* that is used to initialize this field during DDI_ATTACH.
*/
uint32_t fp_options;
/*
* Apparently intended to facilitate reporting the FC_HBA type
* for the local port. Legal values are in fcgs2.h. The
* fc_porttype_t typedef is in fc_types.h
*/
fc_porttype_t fp_port_type;
uint32_t fp_ub_count; /* Number of UBs */
int fp_active_ubs; /* outstanding UBs */
uint64_t *fp_ub_tokens; /* UB tokens */
/*
* CV to inform fp "job" thread that there is work to do.
* See fp_job_handler() function.
*/
kcondvar_t fp_cv;
/*
* Apparently intended to prevent race conditions by holding off any
* DDI_DETACHes for the local port while a ULP attach is in progress.
*/
kcondvar_t fp_attach_cv; /* ULP attach cv */
/*
* Save up the devinfo pointers from Solaris, for performing
* pm_raise_power(), pm_busy_component(), and other DDI friends.
*/
dev_info_t *fp_port_dip; /* port dip */
dev_info_t *fp_fca_dip; /* FCA dip */
/* This is a real Solaris DDI taskq (not the fp "job" queue) */
taskq_t *fp_taskq; /* callback queue */
timeout_id_t fp_wait_tid; /* retry timer */
timeout_id_t fp_offline_tid; /* Offline timeout ID */
fc_lilpmap_t fp_lilp_map; /* LILP map */
la_els_logi_t fp_service_params; /* service parameters */
fc_fcp_dma_t fp_fcp_dma; /* FCP DVMA space */
fc_reset_action_t fp_reset_action; /* FCA reset behavior */
fc_dma_behavior_t fp_dma_behavior; /* FCA DMA behavior */
uchar_t fp_sym_node_namelen; /* Sym node name len */
uchar_t fp_ipa[8]; /* initial proc assoc */
uchar_t fp_ip_addr[16]; /* IP address */
uint32_t fp_fc4_types[8]; /* fc4 types */
struct fc_orphan *fp_orphan_list; /* orphan list */
int fp_orphan_count; /* number of orphans */
/*
* Current PM power level of the local port device. Values
* are given in fc_portif.h
*/
int fp_pm_level; /* power level */
/* Increment/decrement in fctl_busy_port() and fctl_idle_port() */
int fp_pm_busy; /* port busy */
int fp_pm_busy_nocomp; /* busy (no comp) */
fc_hardaddr_t fp_hard_addr; /* Hard Address */
char fp_sym_port_name[255]; /* Symb port name */
char fp_sym_node_name[255]; /* Symb node name */
/*
* Opaque data for CALLB_CPR_* macros used by the per-local-port
* job thread. Required for safe thread shutdown during PM operations.
*/
callb_cpr_t fp_cpr_info; /* CPR info */
char fp_jindex; /* Not used */
char fp_jbuf[15]; /* Not used */
char fp_ibuf[15]; /* instance buf */
char fp_rnid_init; /* init done */
fc_rnid_t fp_rnid_params; /* node id data */
/* T11 FC-HBA data */
fca_port_attrs_t fp_hba_port_attrs;
fc_hba_state_change_t fp_last_change;
uint8_t fp_port_supported_fc4_types[32];
uint8_t fp_port_active_fc4_types[32];
uint32_t fp_port_speed;
la_wwn_t fp_fabric_name;
uint32_t fp_rscn_count;
int fp_npiv_portnum;
#define FC_NPIV_DISABLE 0
#define FC_NPIV_ENABLE 1
int fp_npiv_flag;
#define FC_NPIV_DELETING 1
int fp_npiv_state;
#define FC_PHY_PORT 0
#define FC_NPIV_PORT 1
int fp_npiv_type;
int fp_npiv_portindex[FC_NPIV_MAX_PORT];
struct fc_local_port *fp_port_next;
struct fc_local_port *fp_port_prev;
} fc_local_port_t;
/*
* Struct for the d_id hash table in the fc_local_port_t struct. The code
* allocates memory for an array of D_ID_HASH_TABLE_SIZE elements at
* attach time. The array pointer is saved at the fp_did_table member
* in the fc_local_port_t struct.
* Each hash chain is a singly-linked list of fc_remote_port_t
* structs, using the pd_did_hnext pointer in the fc_remote_port_t struct.
*/
struct d_id_hash {
struct fc_remote_port *d_id_head; /* Head of linked list */
int d_id_count; /* Count of list entries */
};
/*
* Struct for the pwwn hash table in the fc_local_port_t struct. The code
* allocates memory for an array of PWWN_HASH_TABLE_SIZE elements at
* attach time. The array pointer is saved at the fp_pwwn_table member
* in the fc_local_port_t struct.
* Each hash chain is a singly-linked list of fc_remote_port_t
* structs, using the pd_wwn_hnext pointer in the fc_remote_port_t struct.
*/
struct pwwn_hash {
struct fc_remote_port *pwwn_head; /* Head of linked list */
int pwwn_count; /* Count of list entries */
};
/* Function prototypes */
static dev_info_t *
fctl_findchild(dev_info_t *pdip, char *cname, char *caddr);
int fctl_fca_create_npivport(dev_info_t *parent,
dev_info_t *phydip, char *nwwn, char *pwwn, uint32_t *vindex);
static int fctl_fca_bus_ctl(dev_info_t *fca_dip, dev_info_t *rip,
ddi_ctl_enum_t op, void *arg, void *result);
static int fctl_initchild(dev_info_t *fca_dip, dev_info_t *port_dip);
static int fctl_uninitchild(dev_info_t *fca_dip, dev_info_t *port_dip);
static int fctl_cache_constructor(void *buf, void *cdarg, int size);
static void fctl_cache_destructor(void *buf, void *cdarg);
static int fctl_pre_attach(fc_ulp_ports_t *ulp_port, fc_attach_cmd_t cmd);
static void fctl_post_attach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
fc_attach_cmd_t cmd, int rval);
static int fctl_pre_detach(fc_ulp_ports_t *ulp_port, fc_detach_cmd_t cmd);
static void fctl_post_detach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
fc_detach_cmd_t cmd, int rval);
static fc_ulp_ports_t *fctl_add_ulp_port(fc_ulp_module_t *ulp_module,
fc_local_port_t *port_handle, int sleep);
static fc_ulp_ports_t *fctl_alloc_ulp_port(int sleep);
static int fctl_remove_ulp_port(struct ulp_module *ulp_module,
fc_local_port_t *port_handle);
static void fctl_dealloc_ulp_port(fc_ulp_ports_t *next);
static fc_ulp_ports_t *fctl_get_ulp_port(struct ulp_module *ulp_module,
fc_local_port_t *port_handle);
static int fctl_update_host_ns_values(fc_local_port_t *port,
fc_ns_cmd_t *ns_req);
static int fctl_retrieve_host_ns_values(fc_local_port_t *port,
fc_ns_cmd_t *ns_req);
static void fctl_print_if_not_orphan(fc_local_port_t *port,
fc_remote_port_t *pd);
static void fctl_link_reset_done(opaque_t port_handle, uchar_t result);
static int fctl_error(int fc_errno, char **errmsg);
static int fctl_pkt_error(fc_packet_t *pkt, char **state, char **reason,
char **action, char **expln);
static void fctl_check_alpa_list(fc_local_port_t *port, fc_remote_port_t *pd);
static int fctl_is_alpa_present(fc_local_port_t *port, uchar_t alpa);
static void fc_trace_freemsg(fc_trace_logq_t *logq);
static void fctl_init_dma_attr(fc_local_port_t *port, fc_ulp_module_t *mod,
fc_ulp_port_info_t *info);
fc_local_port_t *fc_get_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn);
fc_local_port_t *fc_delete_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn);
#ifdef __cplusplus
}
#endif
#endif /* _FCTL_PRIVATE_H */
|