4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
35 #include <sys/types.h>
36 #include <sys/mkdev.h>
51 #include <sys/ioctl.h>
52 #include <sys/dditypes.h>
53 #include <sys/modctl.h>
54 #include <libdevinfo.h>
55 #include <libdevice.h>
61 #include <sys/ioctl.h>
62 #include <sys/byteorder.h>
63 #include <sys/scsi/scsi.h>
65 #include <sys/vfstab.h>
70 #include <sys/fibre-channel/fcio.h>
71 #include <sys/fibre-channel/ulp/fcp_util.h>
74 #include <sys/param.h>
82 #define CFGA_PLUGIN_LIB
83 #include <config_admin.h>
93 /* Return/error codes */
102 FPCFGA_APID_NOCONFIGURE
,
103 FPCFGA_APID_NOACCESS
,
111 FPCFGA_CONF_OK_UPD_REP_FAILED
,
112 FPCFGA_UNCONF_OK_UPD_REP_FAILED
,
114 FPCFGA_VHCI_GET_PATHLIST_FAILED
,
115 FPCFGA_XPORT_NOT_IN_PHCI_LIST
,
117 FPCFGA_FCP_TGT_SEND_SCSI_FAILED
,
118 FPCFGA_FCP_SEND_SCSI_DEV_NOT_TGT
121 /* Commands used internally */
123 FPCFGA_INVAL_CMD
= -1,
127 FPCFGA_STAT_FCA_PORT
,
136 FPCFGA_BUS_UNQUIESCE
,
139 FPCFGA_BUS_CONFIGURE
,
140 FPCFGA_BUS_UNCONFIGURE
,
141 FPCFGA_DEV_CONFIGURE
,
142 FPCFGA_DEV_UNCONFIGURE
,
152 FPCFGA_TERMINATE
= 0,
157 /* Structures for tree walking code */
161 int (*fcn
)(di_node_t node
, void *argp
);
165 const char *nodetype
;
166 int (*fcn
)(di_node_t node
, di_minor_t minor
, void *argp
);
170 walk_node_t node_args
;
171 walk_minor_t minor_args
;
187 typedef struct ldata_list
{
188 cfga_list_data_t ldata
;
189 struct ldata_list
*next
;
193 struct cfga_confirm
*confp
;
194 struct cfga_msg
*msgp
;
197 typedef struct luninfo_list
{
202 struct luninfo_list
*next
;
209 luninfo_list_t
*lunlist
; /* Singly linked list */
212 /* Report luns names */
213 #define FP_SCMD_REPORT_LUN 0xA0
214 #define DEFAULT_NUM_LUN 1024
215 #define REPORT_LUN_HDR_SIZE 8
216 #define SAM_LUN_SIZE 8
219 #define htonll(x) (x)
220 #define ntohll(x) (x)
222 #define htonll(x) ((((unsigned long long)htonl(x)) << 32) + htonl(x >> 32))
223 #define ntohll(x) ((((unsigned long long)ntohl(x)) << 32) + ntohl(x >> 32))
226 typedef struct report_lun_resp
{
229 longlong_t lun_string
[DEFAULT_NUM_LUN
];
233 * Hardware options acceptable for fp plugin.
234 * list related options are handled by getsupopts() and set to
237 #define OPT_DEVINFO_FORCE 0
238 #define OPT_SHOW_SCSI_LUN 1
239 #define OPT_FCP_DEV 2
240 #define OPT_DISABLE_RCM 0
241 #define OPT_FORCE_UPDATE_REP 1
242 #define OPT_NO_UPDATE_REP 2
243 #define OPT_REMOVE_UNUSABLE_SCSI_LUN 3
244 #define OPT_REMOVE_UNUSABLE_FCP_DEV 4
247 #define FLAG_PATH_INFO_WALK 0x00000001
250 #define FLAG_DISABLE_RCM 0x00000001
251 #define FLAG_FORCE_UPDATE_REP 0x00000010
252 #define FLAG_NO_UPDATE_REP 0x00000100
253 #define FLAG_DYN_AP_CONFIGURED 0x00001000
254 #define FLAG_DEVINFO_FORCE 0x00010000
255 #define FLAG_FCP_DEV 0x00100000
256 #define FLAG_REMOVE_UNUSABLE_FCP_DEV 0x01000000
258 /* apid_t lun flags */
259 #define FLAG_SKIP_RCMOFFLINE 0x00000001
260 #define FLAG_SKIP_RCMREMOVE 0x00000010
261 #define FLAG_SKIP_ONLINEOTHERS 0x00000100
263 /* define for peripheral qualifier mask */
264 #define FP_PERI_QUAL_MASK 0xE0
280 ERR_BUS_NOTCONNECTED
,
297 ERR_FC_GET_FIRST_DEV
,
299 ERRARG_FC_DEV_MAP_INIT
,
300 ERRARG_FC_PROP_LOOKUP_BYTES
,
304 ERRARG_PATH_TOO_LONG
,
307 ERRARG_VHCI_GET_PATHLIST
,
308 ERRARG_XPORT_NOT_IN_PHCI_LIST
,
311 ERR_BUS_DEV_MISMATCH
,
317 ERR_UNCONF_OK_UPD_REP
,
319 ERR_HBA_LOAD_LIBRARY
,
320 ERR_MATCHING_HBA_PORT
,
321 ERR_NO_ADAPTER_FOUND
,
323 /* Errors with arguments */
327 ERRARG_NOT_IN_DEVLIST
,
328 ERRARG_NOT_IN_DEVINFO
,
330 ERRARG_DC_DDEF_ALLOC
,
331 ERRARG_DC_BYTE_ARRAY
,
332 ERRARG_DC_BUS_ACQUIRE
,
333 ERRARG_BUS_DEV_CREATE
,
334 ERRARG_BUS_DEV_CREATE_UNKNOWN
,
359 /* Hotplug messages */
364 /* Hotplugging confirmation prompts */
376 fpcfga_ret_t (*fcn
)(fpcfga_cmd_t
, apid_t
*, prompt_t
*, char **);
381 int nargs
; /* Number of arguments following msgid */
382 int intl
; /* Flag: if 1, internationalize */
388 #define CFGA_DEV_DIR "/dev/cfg"
389 #define DEV_DIR "/dev"
390 #define DEVICES_DIR "/devices"
391 #define DEV_DSK "/dev/dsk"
392 #define DEV_RDSK "/dev/rdsk"
393 #define DEV_RMT "/dev/rmt"
394 #define DSK_DIR "dsk"
395 #define RDSK_DIR "rdsk"
396 #define RMT_DIR "rmt"
400 #define LUN_COMP_SEP ","
401 #define MINOR_SEP ":"
403 #define S_FREE(x) (free(x), (x) = NULL)
404 #define S_STR(x) (((x) == NULL) ? "" : (x))
407 #define IS_STUB_NODE(s) (di_instance(s) == -1 && \
408 di_nodeid(s) == (DI_PROM_NODEID))
410 #define GET_MSG_STR(i) (str_tbl[msg_idx(i)].msgstr)
412 #define GET_DYN(a) (((a) != NULL) ? strstr((a), DYN_SEP) : NULL)
413 #define GET_LUN_DYN(a) (((a) != NULL) ? strstr((a), LUN_COMP_SEP) : NULL)
416 * The following macro removes the separator from the dynamic component.
418 #define DYN_TO_DYNCOMP(a) ((a) + strlen(DYN_SEP))
419 #define LUN_DYN_TO_LUNCOMP(a) ((a) + strlen(LUN_COMP_SEP))
424 #define PORT_WWN_PROP "port-wwn"
425 #define LUN_GUID_PROP "client-guid"
426 #define LUN_PROP "lun"
428 #define WWN_S_LEN 17 /* NULL terminated string */
430 /* Constants used for repository updates */
432 #define REMOVE_ENTRY 1
434 #define FAB_REPOSITORY_DIR "/etc/cfg/fp"
435 #define FAB_REPOSITORY "/etc/cfg/fp/fabric_WWN_map"
436 #define TMP_FAB_REPOSITORY "/etc/cfg/fp/fabric_WWN_map.tmp"
437 #define OLD_FAB_REPOSITORY "/etc/cfg/fp/fabric_WWN_map.old"
439 /* MPXIO VHCI root dir */
440 #define SCSI_VHCI_ROOT "/devices/scsi_vhci/"
441 #define SCSI_VHCI_DRVR "scsi_vhci"
442 #define HBA_MAX_RETRIES 10
444 /* Function prototypes */
446 fpcfga_ret_t
get_report_lun_data(const char *xport_phys
,
447 const char *dyncomp
, int *num_luns
, report_lun_resp_t
**resp_buf
,
448 struct scsi_extended_sense
*sense
, int *l_errnop
);
449 /* Functions in cfga_cs.c */
451 dev_change_state(cfga_cmd_t
, apid_t
*, la_wwn_t
*, cfga_flags_t
, char **,
452 HBA_HANDLE handle
, HBA_PORTATTRIBUTES portAttrs
);
454 fca_change_state(cfga_cmd_t
, apid_t
*, cfga_flags_t
, char **);
456 /* Functions in cfga_rep.c */
457 int update_fabric_wwn_list(int, const char *, char **);
459 fpcfga_ret_t
dev_insert(fpcfga_cmd_t cmd
, apid_t
*apidp
, prompt_t
*argsp
,
461 fpcfga_ret_t
dev_replace(fpcfga_cmd_t cmd
, apid_t
*apidp
, prompt_t
*argsp
,
463 fpcfga_ret_t
dev_remove(fpcfga_cmd_t cmd
, apid_t
*apidp
, prompt_t
*argsp
,
465 fpcfga_ret_t
reset_common(fpcfga_cmd_t cmd
, apid_t
*apidp
, prompt_t
*argsp
,
469 /* List related routines */
470 fpcfga_ret_t
do_list(apid_t
*apidp
, fpcfga_cmd_t cmd
,
471 ldata_list_t
**ldatalistp
, int *nelem
, char **errstring
);
472 fpcfga_ret_t
do_list_FCP_dev(const char *ap_id
, uint_t flags
, fpcfga_cmd_t cmd
,
473 ldata_list_t
**llpp
, int *nelemp
, char **errstring
);
474 fpcfga_ret_t
list_ext_postprocess(ldata_list_t
**ldatalistp
, int nelem
,
475 cfga_list_data_t
**ap_id_list
, int *nlistp
, char **errstring
);
476 int stat_path_info_node(di_node_t root
, void *arg
, int *l_errnop
);
478 /* Conversion routines */
479 fpcfga_ret_t
make_xport_logid(const char *xport_phys
, char **xport_logpp
,
481 fpcfga_ret_t
dyn_apid_to_path(const char *xport_phys
, const char *dyncomp
,
482 struct luninfo_list
**lunlistpp
, int *l_errnop
);
483 void cvt_lawwn_to_dyncomp(const la_wwn_t
*pwwn
, char **dyncomp
, int *l_errnop
);
484 int cvt_dyncomp_to_lawwn(const char *dyncomp
, la_wwn_t
*port_wwn
);
485 fpcfga_ret_t
make_dyncomp_from_dinode(const di_node_t node
, char **dyncompp
,
487 fpcfga_ret_t
make_portwwn_luncomp_from_dinode(const di_node_t node
,
488 char **dyncompp
, int **luncompp
, int *l_errnop
);
489 fpcfga_ret_t
make_portwwn_luncomp_from_pinode(const di_path_t pinode
,
490 char **dyncompp
, int **luncompp
, int *l_errnop
);
491 fpcfga_ret_t
construct_nodepath_from_dinode(const di_node_t node
,
492 char **node_pathp
, int *l_errnop
);
493 u_longlong_t
wwnConversion(uchar_t
*wwn
);
496 /* Functions in cfga_rcm.c */
497 fpcfga_ret_t
fp_rcm_offline(char *, char **, cfga_flags_t
);
498 fpcfga_ret_t
fp_rcm_online(char *, char **, cfga_flags_t
);
499 fpcfga_ret_t
fp_rcm_remove(char *, char **, cfga_flags_t
);
500 fpcfga_ret_t
fp_rcm_suspend(char *, char *, char **, cfga_flags_t
);
501 fpcfga_ret_t
fp_rcm_resume(char *, char *, char **, cfga_flags_t
);
502 fpcfga_ret_t
fp_rcm_info(char *, char **, char **);
504 /* Utility routines */
505 fpcfga_ret_t
physpath_to_devlink(const char *basedir
, char *xport_phys
,
506 char **xport_logpp
, int *l_errnop
, int match_minor
);
507 fpcfga_ret_t
recurse_dev(const char *basedir
, void *arg
,
508 fpcfga_recur_t (*fcn
)(const char *lpath
, void *arg
));
509 fpcfga_ret_t
apidt_create(const char *ap_id
, apid_t
*apidp
,
511 void apidt_free(apid_t
*apidp
);
512 cfga_err_t
err_cvt(fpcfga_ret_t err
);
513 void list_free(ldata_list_t
**llpp
);
514 int known_state(di_node_t node
);
516 fpcfga_ret_t
devctl_cmd(const char *ap_id
, fpcfga_cmd_t cmd
,
517 uint_t
*statep
, int *l_errnop
);
518 fpcfga_ret_t
invoke_cmd(const char *func
, apid_t
*apidt
, prompt_t
*prp
,
521 void cfga_err(char **errstring
, int use_errno
, ...);
522 void cfga_msg(struct cfga_msg
*msgp
, ...);
523 char *cfga_str(int append_newline
, ...);
524 int msg_idx(msgid_t msgid
);
525 fpcfga_ret_t
walk_tree(const char *physpath
, void *arg
, uint_t init_flags
,
526 walkarg_t
*up
, fpcfga_cmd_t cmd
, int *l_errnop
);
527 int hba_dev_cmp(const char *hba
, const char *dev
);
528 int dev_cmp(const char *dev1
, const char *dev2
, int match_minor
);
529 char *pathdup(const char *path
, int *l_errnop
);
530 int getPortAttrsByWWN(HBA_HANDLE handle
, HBA_WWN wwn
,
531 HBA_PORTATTRIBUTES
*attrs
);
532 int getDiscPortAttrs(HBA_HANDLE handle
, int portIndex
,
533 int discIndex
, HBA_PORTATTRIBUTES
*attrs
);
534 int getAdapterPortAttrs(HBA_HANDLE handle
, int portIndex
,
535 HBA_PORTATTRIBUTES
*attrs
);
536 int getAdapterAttrs(HBA_HANDLE handle
, HBA_ADAPTERATTRIBUTES
*attrs
);
537 fpcfga_ret_t
findMatchingAdapterPort(char *portPath
,
538 HBA_HANDLE
*matchingHandle
, int *matchingPortIndex
,
539 HBA_PORTATTRIBUTES
*matchingPortAttrs
, char **errstring
);
541 extern msgcvt_t str_tbl
[];
547 #endif /* _CFGA_FP_H */