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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/sunddi.h>
33 /* Remove these 5 when this source can compile with sunddi.h */
35 #define EC_DDI "EC_ddi"
38 #ifndef ESC_DDI_INITIATOR_REGISTER
39 #define ESC_DDI_INITIATOR_REGISTER "ESC_ddi_initiator_register"
42 #ifndef ESC_DDI_INITIATOR_UNREGISTER
43 #define ESC_DDI_INITIATOR_UNREGISTER "ESC_ddi_initiator_unregister"
46 #ifndef DDI_DRIVER_MAJOR
47 #define DDI_DRIVER_MAJOR "ddi.major"
51 #define DDI_INSTANCE "ddi.instance"
61 getStatus4ErrorCode(int driverError
)
63 MP_STATUS mpStatus
= MP_STATUS_FAILED
;
65 log(LOG_INFO
, "getStatus4ErrorCode()", "- enter");
67 switch (driverError
) {
69 case MP_DRVR_INVALID_ID
:
70 log(LOG_INFO
, "getStatus4ErrorCode()",
71 " received mp_errno=MP_DRVR_INVALID_ID"
72 " from driver call.");
73 log(LOG_INFO
, "getStatus4ErrorCode()",
74 " returning MP_STATUS_OBJECT_NOT_FOUND"
76 mpStatus
= MP_STATUS_OBJECT_NOT_FOUND
;
80 case MP_DRVR_ID_OBSOLETE
:
81 log(LOG_INFO
, "getStatus4ErrorCode()",
82 " received mp_errno=MP_DRVR_ID_OBSOLETE"
83 " from driver call.");
84 log(LOG_INFO
, "getStatus4ErrorCode()",
85 " returning MP_STATUS_OBJECT_NOT_FOUND"
87 mpStatus
= MP_STATUS_OBJECT_NOT_FOUND
;
91 case MP_DRVR_ACCESS_SYMMETRIC
:
92 log(LOG_INFO
, "getStatus4ErrorCode()",
93 " received mp_errno=MP_DRVR_ACCESS_SYMMETRIC"
94 " from driver call.");
95 log(LOG_INFO
, "getStatus4ErrorCode()",
96 " returning MP_STATUS_INVALID_PARAMETER"
98 mpStatus
= MP_STATUS_INVALID_PARAMETER
;
102 case MP_DRVR_PATH_UNAVAILABLE
:
103 log(LOG_INFO
, "getStatus4ErrorCode()",
104 " received mp_errno=MP_DRVR_PATH_UNAVAILABLE"
105 " from driver call.");
106 log(LOG_INFO
, "getStatus4ErrorCode()",
107 " returning MP_STATUS_PATH_NONOPERATIONAL"
109 mpStatus
= MP_STATUS_PATH_NONOPERATIONAL
;
113 case MP_DRVR_IDS_NOT_ASSOCIATED
:
114 log(LOG_INFO
, "getStatus4ErrorCode()",
115 " received mp_errno=MP_DRVR_IDS_NOT_ASSOCIATED"
116 " from driver call.");
117 log(LOG_INFO
, "getStatus4ErrorCode()",
118 " returning MP_STATUS_INVALID_PARAMETER"
120 mpStatus
= MP_STATUS_INVALID_PARAMETER
;
124 case MP_DRVR_ILLEGAL_ACCESS_STATE_REQUEST
:
125 log(LOG_INFO
, "getStatus4ErrorCode()",
126 " received mp_errno="
127 "MP_DRVR_ILLEGAL_ACCESS_STATE_REQUEST"
128 " from driver call.");
129 log(LOG_INFO
, "getStatus4ErrorCode()",
130 " returning MP_STATUS_INVALID_PARAMETER"
132 mpStatus
= MP_STATUS_ACCESS_STATE_INVALID
;
137 log(LOG_INFO
, "getStatus4ErrorCode()",
138 " - received (unsupported) mp_errno=%d from"
139 " driver call.", driverError
);
140 log(LOG_INFO
, "getStatus4ErrorCode()",
141 " - returning MP_STATUS_FAILED to caller.");
142 mpStatus
= MP_STATUS_FAILED
;
145 log(LOG_INFO
, "getStatus4ErrorCode()", "- exit");
153 *createOidList(int size
) {
155 MP_OID_LIST
*pOidList
= NULL
;
158 log(LOG_INFO
, "createOidList()", "- enter");
163 log(LOG_INFO
, "createOidList()",
164 "requested size is less than 1");
165 log(LOG_INFO
, "createOidList()",
171 pOidList
= (MP_OID_LIST
*)calloc(1,
172 sizeof (MP_OID_LIST
) +
176 if (NULL
== pOidList
) {
177 log(LOG_INFO
, "createOidList()",
178 "no memory for pOidList");
179 log(LOG_INFO
, "createOidList()",
193 /* Calls the client callback function, if one is registered */
195 notifyClient(sysevent_t
*ev
)
197 nvlist_t
*attr_list
= NULL
;
199 uint64_t *val
= NULL
;
200 int32_t *instance
= NULL
;
201 int32_t *major
= NULL
;
203 int valAllocated
= 0;
211 void *pCallerData
= NULL
;
213 char subClassName
[256];
215 MP_BOOL becomingVisible
= MP_FALSE
;
217 MP_OID_LIST
*oidList
= NULL
;
220 log(LOG_INFO
, "notifyClient()", "- enter");
223 (void) strncpy(subClassName
, sysevent_get_subclass_name(ev
), 256);
225 if (strstr(subClassName
, "change")) {
227 eventType
= PROP_CHANGE
;
229 log(LOG_INFO
, "notifyClient()", "- got a change event");
230 log(LOG_INFO
, "notifyClient()", ": [%s]",
233 if (strncmp(subClassName
, ESC_SUN_MP_PLUGIN_CHANGE
, 255)
236 index
= MP_OBJECT_TYPE_PLUGIN
;
238 } else if (strncmp(subClassName
, ESC_SUN_MP_LU_CHANGE
, 255)
241 index
= MP_OBJECT_TYPE_MULTIPATH_LU
;
243 } else if (strncmp(subClassName
, ESC_SUN_MP_PATH_CHANGE
, 255)
246 index
= MP_OBJECT_TYPE_PATH_LU
;
248 } else if (strncmp(subClassName
, ESC_SUN_MP_INIT_PORT_CHANGE
,
251 index
= MP_OBJECT_TYPE_INITIATOR_PORT
;
253 } else if (strncmp(subClassName
, ESC_SUN_MP_TPG_CHANGE
, 255)
256 index
= MP_OBJECT_TYPE_TARGET_PORT_GROUP
;
258 } else if (strncmp(subClassName
, ESC_SUN_MP_TARGET_PORT_CHANGE
,
261 index
= MP_OBJECT_TYPE_TARGET_PORT
;
263 } else if (strncmp(subClassName
, ESC_SUN_MP_DEV_PROD_CHANGE
,
266 index
= MP_OBJECT_TYPE_DEVICE_PRODUCT
;
269 } else if ((strstr(subClassName
, "add")) ||
270 (strstr(subClassName
, "initiator_register"))) {
272 eventType
= VISA_CHANGE
;
273 becomingVisible
= MP_TRUE
;
275 log(LOG_INFO
, "notifyClient()", "- got a visibility"
277 log(LOG_INFO
, "notifyClient()", ": [%s]",
280 if (strncmp(subClassName
, ESC_SUN_MP_LU_ADD
, 255) == 0) {
282 index
= MP_OBJECT_TYPE_MULTIPATH_LU
;
284 } else if (strncmp(subClassName
, ESC_SUN_MP_PATH_ADD
, 255)
287 index
= MP_OBJECT_TYPE_PATH_LU
;
289 } else if (strncmp(subClassName
, ESC_DDI_INITIATOR_REGISTER
,
292 index
= MP_OBJECT_TYPE_INITIATOR_PORT
;
294 } else if (strncmp(subClassName
, ESC_SUN_MP_TPG_ADD
,
297 index
= MP_OBJECT_TYPE_TARGET_PORT_GROUP
;
299 } else if (strncmp(subClassName
, ESC_SUN_MP_TARGET_PORT_ADD
,
302 index
= MP_OBJECT_TYPE_TARGET_PORT
;
304 } else if (strncmp(subClassName
, ESC_SUN_MP_DEV_PROD_ADD
, 255)
307 index
= MP_OBJECT_TYPE_DEVICE_PRODUCT
;
311 } else if ((strstr(subClassName
, "remove")) ||
312 (strstr(subClassName
, "initiator_unregister"))) {
314 eventType
= VISA_CHANGE
;
315 becomingVisible
= MP_FALSE
;
317 log(LOG_INFO
, "notifyClient()", "- got a visibility"
319 log(LOG_INFO
, "notifyClient()", ": [%s]",
322 if (strncmp(subClassName
, ESC_SUN_MP_LU_REMOVE
, 255) == 0) {
324 index
= MP_OBJECT_TYPE_MULTIPATH_LU
;
326 } else if (strncmp(subClassName
, ESC_SUN_MP_PATH_REMOVE
, 255)
329 index
= MP_OBJECT_TYPE_PATH_LU
;
331 } else if (strncmp(subClassName
, ESC_DDI_INITIATOR_UNREGISTER
,
334 index
= MP_OBJECT_TYPE_INITIATOR_PORT
;
336 } else if (strncmp(subClassName
, ESC_SUN_MP_TPG_REMOVE
, 255)
339 index
= MP_OBJECT_TYPE_TARGET_PORT_GROUP
;
341 } else if (strncmp(subClassName
, ESC_SUN_MP_TARGET_PORT_REMOVE
,
344 index
= MP_OBJECT_TYPE_TARGET_PORT
;
346 } else if (strncmp(subClassName
, ESC_SUN_MP_DEV_PROD_REMOVE
,
349 index
= MP_OBJECT_TYPE_DEVICE_PRODUCT
;
354 log(LOG_INFO
, "notifyClient()", "- got an unsupported event");
360 log(LOG_INFO
, "notifyClient()", "- index is less than zero");
364 if (eventType
== VISA_CHANGE
) {
366 (void) pthread_mutex_lock(&g_visa_mutex
);
368 if (NULL
== g_Visibility_Callback_List
[index
].pClientFn
) {
370 log(LOG_INFO
, "notifyClient()",
371 "- no visibility change callback to notify");
373 (void) pthread_mutex_unlock(&g_visa_mutex
);
378 (void) pthread_mutex_unlock(&g_visa_mutex
);
381 if (eventType
== PROP_CHANGE
) {
383 (void) pthread_mutex_lock(&g_prop_mutex
);
385 if (NULL
== g_Property_Callback_List
[index
].pClientFn
) {
387 log(LOG_INFO
, "notifyClient()",
388 "- no property change callback to notify");
390 (void) pthread_mutex_unlock(&g_prop_mutex
);
395 (void) pthread_mutex_unlock(&g_prop_mutex
);
398 (void) sysevent_get_attr_list(ev
, &attr_list
);
399 if (NULL
!= attr_list
) {
401 if ((VISA_CHANGE
== eventType
) &&
402 (MP_OBJECT_TYPE_PLUGIN
== index
)) {
404 val
= (uint64_t *)malloc(sizeof (uint64_t));
408 * We have no well-defined way to determine our OSN.
409 * Currently the common library uses 0 as OSN for every
410 * plugin, so just use 0. If the OSN assigned by the
411 * common library changed, this code would have to be
417 } else if ((VISA_CHANGE
== eventType
) &&
418 (MP_OBJECT_TYPE_INITIATOR_PORT
== index
)) {
420 (void) nvlist_lookup_int32_array(attr_list
,
421 DDI_INSTANCE
, &instance
, &nelem
);
423 log(LOG_INFO
, "notifyClient()",
424 "- event (PHCI_INSTANCE) has [%d] elements",
427 (void) nvlist_lookup_int32_array(attr_list
,
428 DDI_DRIVER_MAJOR
, &major
, &nelem
);
430 log(LOG_INFO
, "notifyClient()",
431 "- event (PHCI_DRIVER_MAJOR) has [%d] elements",
434 if ((NULL
!= instance
) & (NULL
!= major
)) {
436 val
= (uint64_t *)malloc(sizeof (uint64_t));
441 *val
= MP_STORE_INST_TO_ID(*instance
, *val
);
442 *val
= MP_STORE_MAJOR_TO_ID(*major
, *val
);
453 (void) nvlist_lookup_uint64_array(attr_list
, OIDLIST
,
456 log(LOG_INFO
, "notifyClient()",
457 "- event has [%d] elements",
463 for (i
= 0; i
< nelem
; i
++) {
465 log(LOG_INFO
, "notifyClient()",
466 "- event [%d] = %llx",
470 oidList
= createOidList(nelem
);
471 if (NULL
== oidList
) {
473 log(LOG_INFO
, "notifyClient()",
474 "- unable to create MP_OID_LIST");
476 log(LOG_INFO
, "notifyClient()",
479 nvlist_free(attr_list
);
484 oidList
->oidCount
= nelem
;
486 for (i
= 0; i
< nelem
; i
++) {
488 oidList
->oids
[i
].objectType
= index
;
489 oidList
->oids
[i
].ownerId
= g_pluginOwnerID
;
490 oidList
->oids
[i
].objectSequenceNumber
= val
[i
];
498 for (i
= 0; i
< oidList
->oidCount
; i
++) {
500 log(LOG_INFO
, "notifyClient()",
501 "oidList->oids[%d].objectType"
503 i
, oidList
->oids
[i
].objectType
);
504 log(LOG_INFO
, "notifyClient()",
505 "oidList->oids[%d].ownerId"
507 i
, oidList
->oids
[i
].ownerId
);
508 log(LOG_INFO
, "notifyClient()",
509 "oidList->oids[%d].objectSequenceNumber"
511 i
, oidList
->oids
[i
].objectSequenceNumber
);
514 if (eventType
== PROP_CHANGE
) {
516 (void) pthread_mutex_lock(&g_prop_mutex
);
518 pCallerData
= g_Property_Callback_List
[index
].
521 (g_Property_Callback_List
[index
].pClientFn
)
522 (oidList
, pCallerData
);
524 (void) pthread_mutex_unlock(&g_prop_mutex
);
526 } else if (eventType
== VISA_CHANGE
) {
528 (void) pthread_mutex_lock(&g_visa_mutex
);
530 pCallerData
= g_Visibility_Callback_List
[index
].
533 (g_Visibility_Callback_List
[index
].pClientFn
)
534 (becomingVisible
, oidList
, pCallerData
);
536 (void) pthread_mutex_unlock(&g_visa_mutex
);
541 nvlist_free(attr_list
);
545 log(LOG_INFO
, "notifyClient()", "- exit");
548 /* Event handler called by system */
550 sysevent_handler(sysevent_t
*ev
)
552 log(LOG_INFO
, "sysevent_handler()", "- enter");
554 /* Is the event one of ours? */
555 if ((strncmp(EC_SUN_MP
, sysevent_get_class_name(ev
), 9) != 0) &&
556 (strncmp(EC_DDI
, sysevent_get_class_name(ev
), 6) != 0)) {
561 /* Notify client if it cares */
565 log(LOG_INFO
, "sysevent_handler()", "- exit");
568 /* Registers the plugin to the sysevent framework */
570 init_sysevents(void) {
572 const char *subclass_list
[] = {
574 ESC_SUN_MP_PLUGIN_CHANGE
,
576 ESC_SUN_MP_LU_CHANGE
,
578 ESC_SUN_MP_LU_REMOVE
,
580 ESC_SUN_MP_PATH_CHANGE
,
582 ESC_SUN_MP_PATH_REMOVE
,
584 ESC_SUN_MP_INIT_PORT_CHANGE
,
586 ESC_SUN_MP_TPG_CHANGE
,
588 ESC_SUN_MP_TPG_REMOVE
,
590 ESC_SUN_MP_TARGET_PORT_CHANGE
,
591 ESC_SUN_MP_TARGET_PORT_ADD
,
592 ESC_SUN_MP_TARGET_PORT_REMOVE
,
594 ESC_SUN_MP_DEV_PROD_CHANGE
,
595 ESC_SUN_MP_DEV_PROD_ADD
,
596 ESC_SUN_MP_DEV_PROD_REMOVE
600 const char *init_port_subclass_list
[] = {
602 ESC_DDI_INITIATOR_REGISTER
,
603 ESC_DDI_INITIATOR_UNREGISTER
608 log(LOG_INFO
, "init_sysevents()", "- enter");
611 g_SysEventHandle
= sysevent_bind_handle(sysevent_handler
);
612 if (g_SysEventHandle
== NULL
) {
614 log(LOG_INFO
, "init_sysevents()",
615 "- sysevent_bind_handle() failed");
617 log(LOG_INFO
, "init_sysevents()", "- error exit");
619 return (MP_STATUS_FAILED
);
622 if (sysevent_subscribe_event(g_SysEventHandle
, EC_SUN_MP
,
623 subclass_list
, sizeof (subclass_list
) / sizeof (subclass_list
[0]))
627 log(LOG_INFO
, "init_sysevents()",
628 "- sysevent_subscribe_event() failed for subclass_list");
630 log(LOG_INFO
, "init_sysevents()", "- error exit");
632 sysevent_unbind_handle(g_SysEventHandle
);
634 return (MP_STATUS_FAILED
);
637 if (sysevent_subscribe_event(g_SysEventHandle
, EC_DDI
,
638 init_port_subclass_list
, sizeof (init_port_subclass_list
) /
639 sizeof (init_port_subclass_list
[0])) != 0) {
642 log(LOG_INFO
, "init_sysevents()",
643 "- sysevent_subscribe_event() failed "
644 "for init_port_subclass_list");
646 log(LOG_INFO
, "init_sysevents()", "- error exit");
648 sysevent_unbind_handle(g_SysEventHandle
);
650 return (MP_STATUS_FAILED
);
654 log(LOG_INFO
, "init_sysevents()", "- exit");
656 return (MP_STATUS_SUCCESS
);