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.
27 #include <libsysevent.h>
28 #include <sys/types.h>
29 #include <netinet/in.h>
34 /* Remove these 5 when the header containing the event names aver available. */
39 #define EC_HBA "EC_hba"
42 #define ESC_SAS_HBA_PORT_BROADCAST "ESC_sas_hba_port_broadcast"
43 #define ESC_SAS_PHY_EVENT "ESC_sas_phy_event"
44 #define ESC_DR_TARGET_STATE_CHANGE "ESC_dr_target_state_change"
46 /* Broadcast Event Types */
47 #define SAS_PORT_BROADCAST_CHANGE "port_broadcast_change"
48 #define SAS_PORT_BROADCAST_SES "port_broadcast_ses"
49 #define SAS_PORT_BROADCAST_D24_0 "port_broadcast_d24_0"
50 #define SAS_PORT_BROADCAST_D27_4 "port_broadcast_d27_4"
51 #define SAS_PORT_BROADCAST_D01_4 "port_broadcast_d01_4"
52 #define SAS_PORT_BROADCAST_D04_7 "port_broadcast_d04_7"
53 #define SAS_PORT_BROADCAST_D16_7 "port_broadcast_d16_7"
54 #define SAS_PORT_BROADCAST_D29_7 "port_broadcast_d29_7"
57 #define SAS_PHY_ONLINE "port_online"
58 #define SAS_PHY_OFFLINE "port_offline"
59 #define SAS_PHY_REMOVE "port_remove"
62 #define SAS_DRV_INST "driver_instance"
63 #define SAS_PORT_ADDR "port_address"
64 #define SAS_DEVFS_PATH "devfs_path"
65 #define SAS_EVENT_TYPE "event_type"
67 #define HBA_PORT_MATCH 1
68 #define TARGET_PORT_MATCH 2
75 sysevent_handle_t
*gSysEventHandle
= NULL
;
77 /* Calls the client callback function, if one is registered */
79 updateMatchingPhy(HBA_WWN portAddr
, uint8_t phyId
, int update
, uint8_t linkRate
)
81 const char ROUTINE
[] = "updateMatchingPhy";
82 struct sun_sas_hba
*hba_ptr
;
83 struct sun_sas_port
*hba_port_ptr
;
84 struct phy_info
*phy_ptr
;
86 log(LOG_DEBUG
, ROUTINE
, "- phy matching");
89 /* loop through HBAs */
90 for (hba_ptr
= global_hba_head
; hba_ptr
!= NULL
;
91 hba_ptr
= hba_ptr
->next
) {
92 /* loop through HBA ports */
93 for (hba_port_ptr
= hba_ptr
->first_port
;
95 hba_port_ptr
= hba_port_ptr
->next
) {
96 if (wwnConversion(hba_port_ptr
->
97 port_attributes
.PortSpecificAttribute
.
98 SASPort
->LocalSASAddress
.wwn
) ==
99 wwnConversion(portAddr
.wwn
)) {
100 /* loop through phys */
101 for (phy_ptr
= hba_port_ptr
->first_phy
;
102 phy_ptr
!= NULL
; phy_ptr
=
104 if (phy_ptr
->phy
.PhyIdentifier
==
106 if (update
== REMOVED
) {
109 } else if (update
== OFFLINE
) {
113 } else { /* online */
118 unlock(&all_hbas_lock
);
119 return (HBA_STATUS_OK
);
122 } /* wwn mismatch. continue */
123 } /* for HBA ports */
126 unlock(&all_hbas_lock
);
127 return (HBA_STATUS_ERROR
);
130 /* Event handler called by system */
132 syseventHandler(sysevent_t
*ev
)
135 const char ROUTINE
[] = "syseventHandler";
136 nvlist_t
*attrList
= NULL
;
137 char *eventStr
, *portAddrStr
, *charptr
;
140 uint8_t phyId
, linkRate
;
143 /* Is the event one of ours? */
144 if (strncmp(EC_HBA
, sysevent_get_class_name(ev
), strlen(EC_HBA
)) == 0) {
145 /* handle phy events */
146 if (strncmp(ESC_SAS_PHY_EVENT
, sysevent_get_subclass_name(ev
),
147 strlen(ESC_SAS_PHY_EVENT
)) == 0) {
148 if (sysevent_get_attr_list(ev
, &attrList
) != 0) {
149 log(LOG_DEBUG
, ROUTINE
,
150 "Failed to get event attributes on %s/%s",
151 EC_HBA
, ESC_SAS_PHY_EVENT
);
154 if (nvlist_lookup_string(attrList
,
155 "event_type", &eventStr
) != 0) {
156 log(LOG_DEBUG
, ROUTINE
,
157 "Event type not found");
160 if (strncmp(eventStr
, "phy_online",
161 sizeof (eventStr
)) == 0) {
163 if (nvlist_lookup_uint8(
164 attrList
, "link_rate",
166 log(LOG_DEBUG
, ROUTINE
,
171 } else if (strncmp(eventStr
,
173 sizeof (eventStr
)) == 0) {
175 } else if (strncmp(eventStr
,
177 sizeof (eventStr
)) == 0) {
180 log(LOG_DEBUG
, ROUTINE
,
181 "Invalid event type");
185 if (nvlist_lookup_string(attrList
,
186 "port_address", &portAddrStr
) != 0) {
187 log(LOG_DEBUG
, ROUTINE
,
188 "Port SAS address not found");
191 for (charptr
= portAddrStr
;
192 charptr
!= NULL
; charptr
++) {
193 if (isxdigit(*charptr
)) {
197 addr
= htonll(strtoll(charptr
,
199 (void) memcpy(portAddr
.wwn
, &addr
, 8);
201 if (nvlist_lookup_uint8(attrList
,
202 "PhyIdentifier", &phyId
) != 0) {
203 log(LOG_DEBUG
, ROUTINE
,
204 "Port SAS address not found");
208 if (updateMatchingPhy(portAddr
, phyId
, update
,
209 linkRate
) != HBA_STATUS_OK
) {
210 log(LOG_DEBUG
, ROUTINE
,
211 "updating phy for the events failed.");
214 } else if (strncmp(EC_DR
, sysevent_get_class_name(ev
), 2) == 0) {
215 /* handle DR events */
216 log(LOG_DEBUG
, ROUTINE
,
217 "handle EC_dr events.");
219 log(LOG_DEBUG
, ROUTINE
,
220 "Found Unregistered event. - exit");
224 log(LOG_DEBUG
, ROUTINE
, "- exit");
227 /* Registers events to the sysevent framework */
231 const char ROUTINE
[] = "registerSysevent";
232 const char *hba_subclass_list
[] = {
235 const char *dr_subclass_list
[] = {
236 ESC_DR_TARGET_STATE_CHANGE
239 gSysEventHandle
= sysevent_bind_handle(syseventHandler
);
240 if (gSysEventHandle
== NULL
) {
241 log(LOG_DEBUG
, ROUTINE
,
242 "- sysevent_bind_handle() failed");
243 log(LOG_DEBUG
, ROUTINE
, "- error exit");
244 return (HBA_STATUS_ERROR
);
247 if (sysevent_subscribe_event(gSysEventHandle
, EC_HBA
,
248 hba_subclass_list
, 1) != 0) {
249 log(LOG_DEBUG
, ROUTINE
,
250 "- sysevent_subscribe_event() failed for EC_HBA subclass");
251 log(LOG_DEBUG
, ROUTINE
, "- error exit");
252 sysevent_unbind_handle(gSysEventHandle
);
253 return (HBA_STATUS_ERROR
);
256 if (sysevent_subscribe_event(gSysEventHandle
, EC_DR
,
257 dr_subclass_list
, 1) != 0) {
258 log(LOG_DEBUG
, ROUTINE
,
259 "- sysevent_subscribe_event() failed for DR subclass");
260 log(LOG_DEBUG
, ROUTINE
, "- error exit");
261 sysevent_unbind_handle(gSysEventHandle
);
262 return (HBA_STATUS_ERROR
);
265 log(LOG_DEBUG
, ROUTINE
, "- exit");
267 return (HBA_STATUS_ERROR
);