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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 #include <sys/types.h>
40 #include <libdllink.h>
45 #define FCOE_DEV_PATH "/devices/fcoe:admin"
48 #define OPEN_EXCL_FCOE O_EXCL
51 * Open for fcoe module
53 * flag - open flag (OPEN_FCOE, OPEN_EXCL_FCOE)
54 * fd - pointer to integer. On success, contains the fcoe file descriptor
57 openFcoe(int flag
, int *fd
)
59 int ret
= FCOE_STATUS_ERROR
;
61 if ((*fd
= open(FCOE_DEV_PATH
, O_NDELAY
| O_RDONLY
| flag
)) != -1) {
64 if (errno
== EPERM
|| errno
== EACCES
) {
65 ret
= FCOE_STATUS_ERROR_PERM
;
67 ret
= FCOE_STATUS_ERROR_OPEN_DEV
;
69 syslog(LOG_DEBUG
, "openFcoe:open failure:%s:errno(%d)",
70 FCOE_DEV_PATH
, errno
);
77 WWN2str(char *buf
, FCOE_PORT_WWN
*wwn
) {
79 unsigned char *pc
= (unsigned char *)&(wwn
->wwn
[0]);
81 for (j
= 0; j
< 16; j
+= 2) {
82 (void) sprintf(&buf
[j
], "%02X", (int)*pc
++);
87 isWWNZero(FCOE_PORT_WWN portwwn
)
90 int size
= sizeof (FCOE_PORT_WWN
);
92 for (i
= 0; i
< size
; i
++) {
93 if (portwwn
.wwn
[i
] != 0) {
101 * Initialize scf fcoe service access
102 * handle - returned handle
103 * service - returned service handle
106 fcoe_cfg_scf_init(scf_handle_t
**handle
, scf_service_t
**service
, int is_target
)
108 scf_scope_t
*scope
= NULL
;
111 if ((*handle
= scf_handle_create(SCF_VERSION
)) == NULL
) {
112 syslog(LOG_ERR
, "scf_handle_create failed - %s",
113 scf_strerror(scf_error()));
118 if (scf_handle_bind(*handle
) == -1) {
119 syslog(LOG_ERR
, "scf_handle_bind failed - %s",
120 scf_strerror(scf_error()));
125 if ((*service
= scf_service_create(*handle
)) == NULL
) {
126 syslog(LOG_ERR
, "scf_service_create failed - %s",
127 scf_strerror(scf_error()));
132 if ((scope
= scf_scope_create(*handle
)) == NULL
) {
133 syslog(LOG_ERR
, "scf_scope_create failed - %s",
134 scf_strerror(scf_error()));
139 if (scf_handle_get_scope(*handle
, SCF_SCOPE_LOCAL
, scope
) == -1) {
140 syslog(LOG_ERR
, "scf_handle_get_scope failed - %s",
141 scf_strerror(scf_error()));
146 if (scf_scope_get_service(scope
,
147 is_target
? FCOE_TARGET_SERVICE
: FCOE_INITIATOR_SERVICE
,
149 syslog(LOG_ERR
, "scf_scope_get_service failed - %s",
150 scf_strerror(scf_error()));
151 ret
= FCOE_ERROR_SERVICE_NOT_FOUND
;
155 scf_scope_destroy(scope
);
157 return (FCOE_SUCCESS
);
160 if (*handle
!= NULL
) {
161 scf_handle_destroy(*handle
);
163 if (*service
!= NULL
) {
164 scf_service_destroy(*service
);
168 scf_scope_destroy(scope
);
174 fcoe_add_remove_scf_entry(char *mac_name
,
175 char *pwwn
, char *nwwn
,
176 int is_target
, int is_promiscuous
, int addRemoveFlag
)
178 scf_handle_t
*handle
= NULL
;
179 scf_service_t
*svc
= NULL
;
180 scf_propertygroup_t
*pg
= NULL
;
181 scf_transaction_t
*tran
= NULL
;
182 scf_transaction_entry_t
*entry
= NULL
;
183 scf_property_t
*prop
= NULL
;
184 scf_value_t
*valueLookup
= NULL
;
185 scf_iter_t
*valueIter
= NULL
;
186 scf_value_t
**valueSet
= NULL
;
187 int ret
= FCOE_SUCCESS
;
188 boolean_t createProp
= B_FALSE
;
190 char buf
[FCOE_PORT_LIST_LENGTH
] = {0};
191 char memberName
[FCOE_PORT_LIST_LENGTH
] = {0};
192 boolean_t found
= B_FALSE
;
194 int valueArraySize
= 0;
196 int portListAlloc
= 100;
198 (void) snprintf(memberName
, FCOE_PORT_LIST_LENGTH
,
199 "%s:%s:%s:%d:%d", mac_name
, pwwn
, nwwn
,
200 is_target
, is_promiscuous
);
202 ret
= fcoe_cfg_scf_init(&handle
, &svc
, is_target
);
203 if (ret
!= FCOE_SUCCESS
) {
207 if (((pg
= scf_pg_create(handle
)) == NULL
) ||
208 ((tran
= scf_transaction_create(handle
)) == NULL
) ||
209 ((entry
= scf_entry_create(handle
)) == NULL
) ||
210 ((prop
= scf_property_create(handle
)) == NULL
) ||
211 ((valueIter
= scf_iter_create(handle
)) == NULL
)) {
216 /* get property group or create it */
217 if (scf_service_get_pg(svc
, FCOE_PG_NAME
, pg
) == -1) {
218 if ((scf_error() == SCF_ERROR_NOT_FOUND
)) {
219 if (scf_service_add_pg(svc
, FCOE_PG_NAME
,
220 SCF_GROUP_APPLICATION
, 0, pg
) == -1) {
221 syslog(LOG_ERR
, "add pg failed - %s",
222 scf_strerror(scf_error()));
228 syslog(LOG_ERR
, "get pg failed - %s",
229 scf_strerror(scf_error()));
232 if (ret
!= FCOE_SUCCESS
) {
237 /* to make sure property exists */
238 if (createProp
== B_FALSE
) {
239 if (scf_pg_get_property(pg
, FCOE_PORT_LIST
, prop
) == -1) {
240 if ((scf_error() == SCF_ERROR_NOT_FOUND
)) {
243 syslog(LOG_ERR
, "get property failed - %s",
244 scf_strerror(scf_error()));
251 /* Begin the transaction */
252 if (scf_transaction_start(tran
, pg
) == -1) {
253 syslog(LOG_ERR
, "start transaction failed - %s",
254 scf_strerror(scf_error()));
259 valueSet
= (scf_value_t
**)calloc(1, sizeof (*valueSet
)
260 * (lastAlloc
= portListAlloc
));
261 if (valueSet
== NULL
) {
262 ret
= FCOE_ERROR_NOMEM
;
267 if (scf_transaction_property_new(tran
, entry
, FCOE_PORT_LIST
,
268 SCF_TYPE_USTRING
) == -1) {
269 if (scf_error() == SCF_ERROR_EXISTS
) {
270 ret
= FCOE_ERROR_EXISTS
;
273 "transaction property new failed - %s",
274 scf_strerror(scf_error()));
280 if (scf_transaction_property_change(tran
, entry
,
281 FCOE_PORT_LIST
, SCF_TYPE_USTRING
) == -1) {
283 "transaction property change failed - %s",
284 scf_strerror(scf_error()));
289 if (scf_pg_get_property(pg
, FCOE_PORT_LIST
, prop
) == -1) {
290 syslog(LOG_ERR
, "get property failed - %s",
291 scf_strerror(scf_error()));
296 valueLookup
= scf_value_create(handle
);
297 if (valueLookup
== NULL
) {
298 syslog(LOG_ERR
, "scf value alloc failed - %s",
299 scf_strerror(scf_error()));
304 if (scf_iter_property_values(valueIter
, prop
) == -1) {
305 syslog(LOG_ERR
, "iter value failed - %s",
306 scf_strerror(scf_error()));
311 while (scf_iter_next_value(valueIter
, valueLookup
) == 1) {
312 char *macnameIter
= NULL
;
313 char buftmp
[FCOE_PORT_LIST_LENGTH
] = {0};
315 bzero(buf
, sizeof (buf
));
316 if (scf_value_get_ustring(valueLookup
,
317 buf
, MAXNAMELEN
) == -1) {
318 syslog(LOG_ERR
, "iter value failed- %s",
319 scf_strerror(scf_error()));
323 (void) strcpy(buftmp
, buf
);
324 macnameIter
= strtok(buftmp
, ":");
325 if (strcmp(macnameIter
, mac_name
) == 0) {
326 if (addRemoveFlag
== FCOE_SCF_ADD
) {
327 ret
= FCOE_ERROR_EXISTS
;
335 valueSet
[i
] = scf_value_create(handle
);
336 if (valueSet
[i
] == NULL
) {
337 syslog(LOG_ERR
, "scf value alloc failed - %s",
338 scf_strerror(scf_error()));
343 if (scf_value_set_ustring(valueSet
[i
], buf
) == -1) {
344 syslog(LOG_ERR
, "set value failed 1- %s",
345 scf_strerror(scf_error()));
350 if (scf_entry_add_value(entry
, valueSet
[i
]) == -1) {
351 syslog(LOG_ERR
, "add value failed - %s",
352 scf_strerror(scf_error()));
359 if (i
>= lastAlloc
) {
360 lastAlloc
+= portListAlloc
;
361 valueSet
= reallocarray(valueSet
, lastAlloc
,
363 if (valueSet
== NULL
) {
372 if (!found
&& (addRemoveFlag
== FCOE_SCF_REMOVE
)) {
373 ret
= FCOE_ERROR_MEMBER_NOT_FOUND
;
375 if (ret
!= FCOE_SUCCESS
) {
379 if (addRemoveFlag
== FCOE_SCF_ADD
) {
381 * Now create the new entry
383 valueSet
[i
] = scf_value_create(handle
);
384 if (valueSet
[i
] == NULL
) {
385 syslog(LOG_ERR
, "scf value alloc failed - %s",
386 scf_strerror(scf_error()));
394 * Set the new member name
396 if (scf_value_set_ustring(valueSet
[i
], memberName
) == -1) {
397 syslog(LOG_ERR
, "set value failed 2- %s",
398 scf_strerror(scf_error()));
406 if (scf_entry_add_value(entry
, valueSet
[i
]) == -1) {
407 syslog(LOG_ERR
, "add value failed - %s",
408 scf_strerror(scf_error()));
414 if ((commitRet
= scf_transaction_commit(tran
)) != 1) {
415 syslog(LOG_ERR
, "transaction commit failed - %s",
416 scf_strerror(scf_error()));
417 if (commitRet
== 0) {
418 ret
= FCOE_ERROR_BUSY
;
429 if (handle
!= NULL
) {
430 scf_handle_destroy(handle
);
433 scf_service_destroy(svc
);
439 scf_transaction_destroy(tran
);
442 scf_entry_destroy(entry
);
445 scf_property_destroy(prop
);
447 if (valueIter
!= NULL
) {
448 scf_iter_destroy(valueIter
);
450 if (valueLookup
!= NULL
) {
451 scf_value_destroy(valueLookup
);
455 * Free valueSet scf resources
457 if (valueArraySize
> 0) {
458 for (i
= 0; i
< valueArraySize
; i
++) {
459 scf_value_destroy(valueSet
[i
]);
463 * Now free the pointer array to the resources
465 if (valueSet
!= NULL
) {
474 const FCOE_UINT8
*macLinkName
,
478 FCOE_UINT8 promiscuous
)
483 fcoeio_create_port_param_t param
;
484 dladm_handle_t handle
;
485 datalink_id_t linkid
;
486 datalink_class_t
class;
488 bzero(¶m
, sizeof (fcoeio_create_port_param_t
));
490 if (macLinkName
== NULL
) {
491 return (FCOE_STATUS_ERROR_INVAL_ARG
);
494 if (strlen((char *)macLinkName
) > MAXLINKNAMELEN
-1) {
495 return (FCOE_STATUS_ERROR_MAC_LEN
);
498 if (dladm_open(&handle
) != DLADM_STATUS_OK
) {
499 return (FCOE_STATUS_ERROR
);
502 if (dladm_name2info(handle
, (const char *)macLinkName
,
503 &linkid
, NULL
, &class, NULL
) != DLADM_STATUS_OK
) {
505 (void) fcoe_add_remove_scf_entry((char *)macLinkName
,
511 return (FCOE_STATUS_ERROR_GET_LINKINFO
);
515 if (class != DATALINK_CLASS_PHYS
) {
516 return (FCOE_STATUS_ERROR_CLASS_UNSUPPORT
);
519 if (portType
!= FCOE_PORTTYPE_INITIATOR
&&
520 portType
!= FCOE_PORTTYPE_TARGET
) {
521 return (FCOE_STATUS_ERROR_INVAL_ARG
);
524 if (!isWWNZero(pwwn
)) {
525 param
.fcp_pwwn_provided
= 1;
526 bcopy(pwwn
.wwn
, param
.fcp_pwwn
, 8);
529 if (!isWWNZero(nwwn
)) {
530 param
.fcp_nwwn_provided
= 1;
531 bcopy(nwwn
.wwn
, param
.fcp_nwwn
, 8);
534 if (param
.fcp_pwwn_provided
== 1 &&
535 param
.fcp_nwwn_provided
== 1 &&
536 bcmp(&pwwn
, &nwwn
, 8) == 0) {
537 return (FCOE_STATUS_ERROR_WWN_SAME
);
540 param
.fcp_force_promisc
= promiscuous
;
541 param
.fcp_mac_linkid
= linkid
;
542 param
.fcp_port_type
= (fcoe_cli_type_t
)portType
;
544 if ((status
= openFcoe(OPEN_FCOE
, &fcoe_fd
)) != FCOE_STATUS_OK
) {
548 (void) memset(&fcoeio
, 0, sizeof (fcoeio
));
549 fcoeio
.fcoeio_cmd
= FCOEIO_CREATE_FCOE_PORT
;
551 fcoeio
.fcoeio_ilen
= sizeof (param
);
552 fcoeio
.fcoeio_xfer
= FCOEIO_XFER_WRITE
;
553 fcoeio
.fcoeio_ibuf
= (uintptr_t)¶m
;
555 if (ioctl(fcoe_fd
, FCOEIO_CMD
, &fcoeio
) != 0) {
556 switch (fcoeio
.fcoeio_status
) {
557 case FCOEIOE_INVAL_ARG
:
558 status
= FCOE_STATUS_ERROR_INVAL_ARG
;
562 status
= FCOE_STATUS_ERROR_BUSY
;
565 case FCOEIOE_ALREADY
:
566 status
= FCOE_STATUS_ERROR_ALREADY
;
569 case FCOEIOE_PWWN_CONFLICTED
:
570 status
= FCOE_STATUS_ERROR_PWWN_CONFLICTED
;
573 case FCOEIOE_NWWN_CONFLICTED
:
574 status
= FCOE_STATUS_ERROR_NWWN_CONFLICTED
;
577 case FCOEIOE_CREATE_MAC
:
578 status
= FCOE_STATUS_ERROR_CREATE_MAC
;
581 case FCOEIOE_OPEN_MAC
:
582 status
= FCOE_STATUS_ERROR_OPEN_MAC
;
585 case FCOEIOE_CREATE_PORT
:
586 status
= FCOE_STATUS_ERROR_CREATE_PORT
;
589 case FCOEIOE_NEED_JUMBO_FRAME
:
590 status
= FCOE_STATUS_ERROR_NEED_JUMBO_FRAME
;
594 status
= FCOE_STATUS_ERROR
;
597 char cpwwn
[17], cnwwn
[17];
599 WWN2str(cpwwn
, &pwwn
);
600 WWN2str(cnwwn
, &nwwn
);
602 (void) fcoe_add_remove_scf_entry((char *)macLinkName
,
608 status
= FCOE_STATUS_OK
;
610 (void) close(fcoe_fd
);
615 FCOE_DeletePort(const FCOE_UINT8
*macLinkName
)
617 FCOE_STATUS status
= FCOE_STATUS_OK
;
620 dladm_handle_t handle
;
621 datalink_id_t linkid
;
622 fcoeio_delete_port_param_t fc_del_port
;
623 uint64_t is_target
= 0;
626 if (macLinkName
== NULL
) {
627 return (FCOE_STATUS_ERROR_INVAL_ARG
);
630 if (strlen((char *)macLinkName
) > MAXLINKNAMELEN
-1) {
631 return (FCOE_STATUS_ERROR_MAC_LEN
);
633 if (dladm_open(&handle
) != DLADM_STATUS_OK
) {
634 return (FCOE_STATUS_ERROR
);
637 if (dladm_name2info(handle
, (const char *)macLinkName
,
638 &linkid
, NULL
, NULL
, NULL
) != DLADM_STATUS_OK
) {
640 return (FCOE_STATUS_ERROR_GET_LINKINFO
);
644 if ((status
= openFcoe(OPEN_FCOE
, &fcoe_fd
)) != FCOE_STATUS_OK
) {
648 fc_del_port
.fdp_mac_linkid
= linkid
;
650 (void) memset(&fcoeio
, 0, sizeof (fcoeio
));
651 fcoeio
.fcoeio_cmd
= FCOEIO_DELETE_FCOE_PORT
;
653 /* only 4 bytes here, need to change */
654 fcoeio
.fcoeio_ilen
= sizeof (fcoeio_delete_port_param_t
);
655 fcoeio
.fcoeio_olen
= sizeof (uint64_t);
656 fcoeio
.fcoeio_xfer
= FCOEIO_XFER_RW
;
657 fcoeio
.fcoeio_ibuf
= (uintptr_t)&fc_del_port
;
658 fcoeio
.fcoeio_obuf
= (uintptr_t)&is_target
;
660 io_ret
= ioctl(fcoe_fd
, FCOEIO_CMD
, &fcoeio
);
662 switch (fcoeio
.fcoeio_status
) {
663 case FCOEIOE_INVAL_ARG
:
664 status
= FCOE_STATUS_ERROR_INVAL_ARG
;
668 status
= FCOE_STATUS_ERROR_BUSY
;
671 case FCOEIOE_ALREADY
:
672 status
= FCOE_STATUS_ERROR_ALREADY
;
675 case FCOEIOE_MAC_NOT_FOUND
:
676 status
= FCOE_STATUS_ERROR_MAC_NOT_FOUND
;
679 case FCOEIOE_OFFLINE_FAILURE
:
680 status
= FCOE_STATUS_ERROR_OFFLINE_DEV
;
684 status
= FCOE_STATUS_ERROR
;
687 (void) fcoe_add_remove_scf_entry((char *)macLinkName
,
693 status
= FCOE_STATUS_OK
;
696 if (io_ret
== FCOEIOE_MAC_NOT_FOUND
) {
697 (void) fcoe_add_remove_scf_entry((char *)macLinkName
,
703 (void) fcoe_add_remove_scf_entry((char *)macLinkName
,
710 (void) close(fcoe_fd
);
716 FCOE_UINT32
*port_num
,
717 FCOE_PORT_ATTRIBUTE
**portlist
)
719 FCOE_STATUS status
= FCOE_STATUS_OK
;
722 fcoe_port_list_t
*inportlist
= NULL
;
723 FCOE_PORT_ATTRIBUTE
*outportlist
= NULL
;
725 int size
= 64; /* default first attempt */
728 dladm_handle_t handle
;
729 char mac_name
[MAXLINKNAMELEN
];
731 if (port_num
== NULL
|| portlist
== NULL
) {
732 return (FCOE_STATUS_ERROR_INVAL_ARG
);
736 if ((status
= openFcoe(OPEN_FCOE
, &fcoe_fd
)) != FCOE_STATUS_OK
) {
740 /* Get fcoe port list */
741 (void) memset(&fcoeio
, 0, sizeof (fcoeio
));
745 bufsize
= sizeof (fcoe_port_instance_t
) * (size
- 1) +
746 sizeof (fcoe_port_list_t
);
747 inportlist
= (fcoe_port_list_t
*)malloc(bufsize
);
748 fcoeio
.fcoeio_cmd
= FCOEIO_GET_FCOE_PORT_LIST
;
749 fcoeio
.fcoeio_olen
= bufsize
;
750 fcoeio
.fcoeio_xfer
= FCOEIO_XFER_READ
;
751 fcoeio
.fcoeio_obuf
= (uintptr_t)inportlist
;
753 if (ioctl(fcoe_fd
, FCOEIO_CMD
, &fcoeio
) != 0) {
754 if (fcoeio
.fcoeio_status
== FCOEIOE_MORE_DATA
) {
755 size
= inportlist
->numPorts
;
758 switch (fcoeio
.fcoeio_status
) {
759 case FCOEIOE_INVAL_ARG
:
760 status
= FCOE_STATUS_ERROR_INVAL_ARG
;
761 (void) close(fcoe_fd
);
765 status
= FCOE_STATUS_ERROR_BUSY
;
769 case FCOEIOE_MORE_DATA
:
770 status
= FCOE_STATUS_ERROR_MORE_DATA
;
773 status
= FCOE_STATUS_ERROR
;
774 (void) close(fcoe_fd
);
778 status
= FCOE_STATUS_OK
;
781 } while (retry
<= 3 && status
!= FCOE_STATUS_OK
);
783 if (status
== FCOE_STATUS_OK
&& inportlist
->numPorts
> 0) {
784 if (dladm_open(&handle
) != DLADM_STATUS_OK
) {
788 outportlist
= (PFCOE_PORT_ATTRIBUTE
)
789 malloc(sizeof (FCOE_PORT_ATTRIBUTE
) * inportlist
->numPorts
);
791 for (i
= 0; i
< inportlist
->numPorts
; i
++) {
792 fcoe_port_instance_t
*pi
= &inportlist
->ports
[i
];
793 FCOE_PORT_ATTRIBUTE
*po
= &outportlist
[i
];
794 bcopy(pi
->fpi_pwwn
, &po
->port_wwn
, 8);
796 if (handle
== NULL
||
797 dladm_datalink_id2info(handle
, pi
->fpi_mac_linkid
,
798 NULL
, NULL
, NULL
, mac_name
, sizeof (mac_name
))
799 != DLADM_STATUS_OK
) {
800 (void) strcpy((char *)po
->mac_link_name
,
803 (void) strcpy((char *)po
->mac_link_name
,
806 bcopy(pi
->fpi_mac_factory_addr
,
807 po
->mac_factory_addr
, 6);
808 bcopy(pi
->fpi_mac_current_addr
,
809 po
->mac_current_addr
, 6);
810 po
->port_type
= (FCOE_UINT8
)pi
->fpi_port_type
;
811 po
->mtu_size
= pi
->fpi_mtu_size
;
812 po
->mac_promisc
= pi
->fpi_mac_promisc
;
815 if (handle
!= NULL
) {
818 *port_num
= inportlist
->numPorts
;
819 *portlist
= outportlist
;
825 (void) close(fcoe_fd
);
829 FCOE_STATUS
FCOE_LoadConfig(
831 FCOE_SMF_PORT_LIST
**portlist
)
833 scf_handle_t
*handle
= NULL
;
834 scf_service_t
*svc
= NULL
;
835 scf_propertygroup_t
*pg
= NULL
;
836 scf_transaction_t
*tran
= NULL
;
837 scf_transaction_entry_t
*entry
= NULL
;
838 scf_property_t
*prop
= NULL
;
839 scf_value_t
*valueLookup
= NULL
;
840 scf_iter_t
*valueIter
= NULL
;
841 char buf
[FCOE_PORT_LIST_LENGTH
] = {0};
843 FCOE_UINT32 portIndex
;
845 int size
= 10; /* default first attempt */
846 int pg_or_prop_not_found
= 0;
848 commitRet
= fcoe_cfg_scf_init(&handle
, &svc
, portType
);
849 if (commitRet
!= FCOE_SUCCESS
) {
853 if (((pg
= scf_pg_create(handle
)) == NULL
) ||
854 ((tran
= scf_transaction_create(handle
)) == NULL
) ||
855 ((entry
= scf_entry_create(handle
)) == NULL
) ||
856 ((prop
= scf_property_create(handle
)) == NULL
) ||
857 ((valueIter
= scf_iter_create(handle
)) == NULL
)) {
861 if (scf_service_get_pg(svc
, FCOE_PG_NAME
, pg
) == -1) {
862 pg_or_prop_not_found
= 1;
866 if (scf_pg_get_property(pg
, FCOE_PORT_LIST
, prop
) == -1) {
867 pg_or_prop_not_found
= 1;
871 valueLookup
= scf_value_create(handle
);
872 if (valueLookup
== NULL
) {
873 syslog(LOG_ERR
, "scf value alloc failed - %s",
874 scf_strerror(scf_error()));
881 if (scf_iter_property_values(valueIter
, prop
) == -1) {
882 syslog(LOG_ERR
, "iter value failed - %s",
883 scf_strerror(scf_error()));
888 bufsize
= sizeof (FCOE_SMF_PORT_INSTANCE
) * (size
- 1) +
889 sizeof (FCOE_SMF_PORT_LIST
);
890 *portlist
= (PFCOE_SMF_PORT_LIST
)malloc(bufsize
);
892 while (scf_iter_next_value(valueIter
, valueLookup
) == 1) {
893 uint8_t *macLinkName
= NULL
;
894 char *remainder
= NULL
;
895 uint64_t nodeWWN
, portWWN
;
896 int is_target
, is_promiscuous
;
898 bzero(buf
, sizeof (buf
));
899 if (scf_value_get_ustring(valueLookup
, buf
,
901 syslog(LOG_ERR
, "iter value failed - %s",
902 scf_strerror(scf_error()));
905 macLinkName
= (uint8_t *)strtok(buf
, ":");
906 remainder
= strtok(NULL
, "#");
907 (void) sscanf(remainder
,
908 "%016" PRIx64
":%016" PRIx64
":%d:%d",
909 &portWWN
, &nodeWWN
, &is_target
, &is_promiscuous
);
911 if (portIndex
>= size
) {
917 PFCOE_SMF_PORT_INSTANCE pi
=
918 &(*portlist
)->ports
[portIndex
++];
919 (void) strcpy((char *)pi
->mac_link_name
,
920 (char *)macLinkName
);
921 pi
->port_type
= is_target
?
922 FCOE_PORTTYPE_TARGET
:
923 FCOE_PORTTYPE_INITIATOR
;
924 portWWN
= htonll(portWWN
);
925 nodeWWN
= htonll(nodeWWN
);
926 (void) memcpy(&pi
->port_pwwn
, &portWWN
,
927 sizeof (FCOE_PORT_WWN
));
928 (void) memcpy(&pi
->port_nwwn
, &nodeWWN
,
929 sizeof (FCOE_PORT_WWN
));
930 pi
->mac_promisc
= is_promiscuous
;
934 (*portlist
)->port_num
= portIndex
;
935 } while (retry
== 1);
937 return (FCOE_STATUS_OK
);
942 if (handle
!= NULL
) {
943 scf_handle_destroy(handle
);
946 scf_service_destroy(svc
);
952 scf_transaction_destroy(tran
);
955 scf_entry_destroy(entry
);
958 scf_property_destroy(prop
);
960 if (valueIter
!= NULL
) {
961 scf_iter_destroy(valueIter
);
963 if (valueLookup
!= NULL
) {
964 scf_value_destroy(valueLookup
);
967 if (pg_or_prop_not_found
== 1) {
968 return (FCOE_STATUS_OK
);
970 return (FCOE_STATUS_ERROR
);