xref: /titanic_52/usr/src/uts/common/io/1394/nx1394.c (revision 84ab085a13f931bc78e7415e7ce921dbaa14fcb3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * nx1394.c
31  *    1394 Services Layer Nexus Support Routines
32  *    Routines in this file implement nexus bus_ops.
33  */
34 
35 #include <sys/conf.h>
36 #include <sys/ddi.h>
37 #include <sys/modctl.h>
38 #include <sys/sunddi.h>
39 #include <sys/cmn_err.h>
40 #include <sys/types.h>
41 #include <sys/ddi_impldefs.h>
42 
43 #include <sys/tnf_probe.h>
44 
45 #include <sys/1394/t1394.h>
46 #include <sys/1394/s1394.h>
47 #include <sys/1394/h1394.h>
48 
49 static int nx1394_dma_allochdl(dev_info_t *dip, dev_info_t *rdip,
50     ddi_dma_attr_t *attr, int (*waitfnp)(caddr_t), caddr_t arg,
51     ddi_dma_handle_t *handlep);
52 
53 static int nx1394_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op,
54     void *arg, void *result);
55 
56 static int nx1394_get_event_cookie(dev_info_t *dip, dev_info_t *rdip,
57     char *name, ddi_eventcookie_t *event_cookiep);
58 
59 static int nx1394_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
60     ddi_eventcookie_t eventhdl, void (*callback)(), void *arg,
61     ddi_callback_id_t *cb_id);
62 
63 static int nx1394_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id);
64 
65 static int nx1394_post_event(dev_info_t *dip, dev_info_t *rdip,
66     ddi_eventcookie_t eventhdl, void *impl_data);
67 
68 struct bus_ops nx1394_busops = {
69 	BUSO_REV,
70 	nullbusmap,			/* bus_map */
71 	NULL,				/* bus_get_intrspec */
72 	NULL,				/* bus_add_intrspec */
73 	NULL,				/* bus_remove_intrspec */
74 	i_ddi_map_fault,		/* XXXX bus_map_fault */
75 	ddi_dma_map,			/* bus_dma_map */
76 	nx1394_dma_allochdl,
77 	ddi_dma_freehdl,
78 	ddi_dma_bindhdl,
79 	ddi_dma_unbindhdl,
80 	ddi_dma_flush,
81 	ddi_dma_win,
82 	ddi_dma_mctl,			/* bus_dma_ctl */
83 	nx1394_bus_ctl,			/* bus_ctl */
84 	ddi_bus_prop_op,		/* bus_prop_op */
85 	nx1394_get_event_cookie,	/* (*bus_get_eventcookie() */
86 	nx1394_add_eventcall,		/* (*bus_add_eventcall)(); */
87 	nx1394_remove_eventcall,	/* (*bus_remove_eventcall)(); */
88 	nx1394_post_event,		/* (*bus_post_event)(); */
89 	0,				/* (*interrupt control)();	*/
90 	0,				/* (*bus_config)();	*/
91 	0,				/* (*bus_unconfig)();	*/
92 	0,				/* (*bus_fm_init)();	*/
93 	0,				/* (*bus_fm_fini)();	*/
94 	0,				/* (*bus_fm_access_enter)();	*/
95 	0,				/* (*bus_fm_access_exit)();	*/
96 	0,				/* (*bus_power)();	*/
97 	i_ddi_intr_ops			/* (*bus_intr_op)();	*/
98 };
99 
100 /*
101  * removal/insertion/reset events
102  */
103 #define	NX1394_EVENT_TAG_HOT_REMOVAL		0
104 #define	NX1394_EVENT_TAG_HOT_INSERTION		1
105 #define	NX1394_EVENT_TAG_BUS_RESET		2
106 
107 static ndi_event_definition_t nx1394_event_defs[] = {
108 	{NX1394_EVENT_TAG_HOT_REMOVAL, DDI_DEVI_REMOVE_EVENT, EPL_KERNEL,
109 	    NDI_EVENT_POST_TO_TGT},
110 	{NX1394_EVENT_TAG_HOT_INSERTION, DDI_DEVI_INSERT_EVENT, EPL_KERNEL,
111 	    NDI_EVENT_POST_TO_TGT},
112 	{NX1394_EVENT_TAG_BUS_RESET, DDI_DEVI_BUS_RESET_EVENT, EPL_KERNEL,
113 	    NDI_EVENT_POST_TO_ALL},
114 };
115 
116 #define	NX1394_N_EVENTS \
117 	(sizeof (nx1394_event_defs) / sizeof (ndi_event_definition_t))
118 
119 static ndi_event_set_t nx1394_events = {
120 	NDI_EVENTS_REV1, NX1394_N_EVENTS, nx1394_event_defs
121 };
122 
123 /*
124  * nx1394_bus_ctl()
125  *    This routine implements nexus bus ctl operations. Of importance are
126  *    DDI_CTLOPS_REPORTDEV, DDI_CTLOPS_INITCHILD, DDI_CTLOPS_UNINITCHILD
127  *    and DDI_CTLOPS_POWER. For DDI_CTLOPS_INITCHILD, it tries to lookup
128  *    reg property on the child node and builds and sets the name
129  *    (name is of the form GGGGGGGGGGGGGGGG[,AAAAAAAAAAAA], where
130  *    GGGGGGGGGGGGGGGG is the GUID and AAAAAAAAAAAA is the optional unit
131  *    address).
132  */
133 static int
134 nx1394_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg,
135     void *result)
136 {
137 	int status;
138 
139 	TNF_PROBE_0_DEBUG(nx1394_bus_ctl_enter, S1394_TNF_SL_NEXUS_STACK, "");
140 
141 	switch (op) {
142 	case DDI_CTLOPS_REPORTDEV: {
143 		dev_info_t *pdip = ddi_get_parent(rdip);
144 		cmn_err(CE_CONT, "?%s%d at %s%d",
145 		    ddi_node_name(rdip), ddi_get_instance(rdip),
146 		    ddi_node_name(pdip), ddi_get_instance(pdip));
147 		TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
148 		    "");
149 		return (DDI_SUCCESS);
150 	}
151 
152 	case DDI_CTLOPS_INITCHILD: {
153 		dev_info_t *ocdip, *cdip = (dev_info_t *)arg;
154 		dev_info_t *pdip = ddi_get_parent(cdip);
155 		int reglen, i;
156 		uint32_t *regptr;
157 		char addr[MAXNAMELEN];
158 
159 		TNF_PROBE_1(nx1394_bus_ctl_init_child,
160 		    S1394_TNF_SL_HOTPLUG_STACK, "", tnf_opaque, dip, cdip);
161 
162 		i = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, cdip,
163 		    DDI_PROP_DONTPASS, "reg", (int **)&regptr,
164 		    (uint_t *)&reglen);
165 
166 		if (i != DDI_PROP_SUCCESS) {
167 			cmn_err(CE_NOTE, "!%s(%d): \"reg\" property not found",
168 			    ddi_node_name(cdip), ddi_get_instance(cdip));
169 			TNF_PROBE_2(nx1394_bus_ctl,
170 			    S1394_TNF_SL_NEXUS_ERROR, "", tnf_string, msg,
171 			    "Reg property not found", tnf_int, reason, i);
172 			TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit,
173 			    S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op,
174 			    "initchild");
175 			return (DDI_NOT_WELL_FORMED);
176 		}
177 
178 		ASSERT(reglen != 0);
179 
180 		/*
181 		 * addr is of the format GGGGGGGGGGGGGGGG[,AAAAAAAAAAAA]
182 		 */
183 		if (regptr[2] || regptr[3]) {
184 			(void) sprintf(addr, "%08x%08x,%04x%08x", regptr[0],
185 			    regptr[1], regptr[2], regptr[3]);
186 		} else {
187 			(void) sprintf(addr, "%08x%08x", regptr[0], regptr[1]);
188 		}
189 		ddi_prop_free(regptr);
190 		ddi_set_name_addr(cdip, addr);
191 
192 		/*
193 		 * Check for a node with the same name & addr as the current
194 		 * node. If such a node exists, return failure.
195 		 */
196 		if ((ocdip = ndi_devi_find(pdip, ddi_node_name(cdip), addr)) !=
197 		    NULL && ocdip != cdip) {
198 			cmn_err(CE_NOTE,
199 			    "!%s(%d): Duplicate dev_info node found %s@%s",
200 			    ddi_node_name(cdip), ddi_get_instance(cdip),
201 			    ddi_node_name(ocdip), addr);
202 			TNF_PROBE_1(nx1394_bus_ctl,
203 			    S1394_TNF_SL_NEXUS_ERROR, "", tnf_string, msg,
204 			    "Duplicate nodes");
205 			TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit,
206 			    S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op,
207 			    "initchild");
208 			ddi_set_name_addr(cdip, NULL);
209 			return (DDI_NOT_WELL_FORMED);
210 		}
211 
212 		/*
213 		 * If HAL (parent dip) has "active-dma-flush" property, then
214 		 * add property to child as well.  Workaround for active
215 		 * context flushing bug in Schizo rev 2.1 and 2.2.
216 		 */
217 		if (ddi_prop_exists(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
218 		    "active-dma-flush") != 0) {
219 			status = ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
220 			    "active-dma-flush", 1);
221 			if (status != NDI_SUCCESS) {
222 				cmn_err(CE_NOTE, "!%s(%d): Unable to add "
223 				    "\"active-dma-flush\" property",
224 				    ddi_node_name(cdip),
225 				    ddi_get_instance(cdip));
226 				TNF_PROBE_1(nx1394_bus_ctl,
227 				    S1394_TNF_SL_NEXUS_ERROR, "", tnf_string,
228 				    msg, "Unable to add \"active-dma-flush\" "
229 				    "property");
230 				TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit,
231 				    S1394_TNF_SL_NEXUS_STACK, "", tnf_string,
232 				    op, "initchild");
233 				ddi_set_name_addr(cdip, NULL);
234 				return (DDI_NOT_WELL_FORMED);
235 			}
236 		}
237 
238 		TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit,
239 		    S1394_TNF_SL_NEXUS_STACK, "", tnf_string, op, "initchild");
240 		return (DDI_SUCCESS);
241 	}
242 
243 	case DDI_CTLOPS_UNINITCHILD: {
244 		ddi_prop_remove_all((dev_info_t *)arg);
245 		ddi_set_name_addr((dev_info_t *)arg, NULL);
246 		TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
247 		    "", tnf_string, op, "uninitchild");
248 		return (DDI_SUCCESS);
249 	}
250 
251 	case DDI_CTLOPS_IOMIN: {
252 		status = ddi_ctlops(dip, rdip, op, arg, result);
253 		TNF_PROBE_1_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
254 		    "", tnf_string, op, "iomin");
255 		return (status);
256 	}
257 
258 	case DDI_CTLOPS_POWER: {
259 		return (DDI_SUCCESS);
260 	}
261 
262 	/*
263 	 * These ops correspond to functions that "shouldn't" be called
264 	 * by a 1394 client driver.
265 	 */
266 	case DDI_CTLOPS_DMAPMAPC:
267 	case DDI_CTLOPS_REPORTINT:
268 	case DDI_CTLOPS_REGSIZE:
269 	case DDI_CTLOPS_NREGS:
270 	case DDI_CTLOPS_NINTRS:
271 	case DDI_CTLOPS_SIDDEV:
272 	case DDI_CTLOPS_SLAVEONLY:
273 	case DDI_CTLOPS_AFFINITY:
274 	case DDI_CTLOPS_INTR_HILEVEL:
275 	case DDI_CTLOPS_XLATE_INTRS:
276 	case DDI_CTLOPS_POKE:
277 	case DDI_CTLOPS_PEEK: {
278 		cmn_err(CE_CONT, "!%s(%d): invalid op (%d) from %s(%d)",
279 		    ddi_node_name(dip), ddi_get_instance(dip),
280 		    op, ddi_node_name(rdip), ddi_get_instance(rdip));
281 		TNF_PROBE_2(nx1394_bus_ctl, S1394_TNF_SL_NEXUS_ERROR, "",
282 		    tnf_string, msg, "invalid op", tnf_int, op, op);
283 		TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
284 		    "");
285 		return (DDI_FAILURE);
286 	}
287 
288 	/*
289 	 * Everything else (e.g. PTOB/BTOP/BTOPR requests) we pass up
290 	 */
291 	default: {
292 		status = ddi_ctlops(dip, rdip, op, arg, result);
293 		TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
294 		    "");
295 		return (status);
296 	}
297 	}
298 }
299 
300 /*
301  * nx1394_dma_allochdl()
302  *    Merges the ddi_dma_attr_t passed in by the target (using
303  *    ddi_dma_alloc_handle() call) with that of the hal and passes the alloc
304  *    handle request up the device by calling ddi_dma_allochdl().
305  */
306 static int
307 nx1394_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
308     int (*waitfnp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
309 {
310 	s1394_hal_t *hal;
311 	ddi_dma_attr_t *hal_attr;
312 	int status;
313 
314 	_NOTE(SCHEME_PROTECTS_DATA("unique (per thread)", ddi_dma_attr_t))
315 
316 	TNF_PROBE_0_DEBUG(nx1394_dma_allochdl_enter, S1394_TNF_SL_NEXUS_STACK,
317 	    "");
318 
319 	/*
320 	 * If hal calls ddi_dma_alloc_handle, dip == rdip == hal dip.
321 	 * Unfortunately, we cannot verify this (by way of looking up for hal
322 	 * dip) here because h1394_attach() may happen much later.
323 	 */
324 	if (dip != rdip) {
325 		hal = s1394_dip_to_hal(ddi_get_parent(rdip));
326 		ASSERT(hal);
327 		hal_attr = &hal->halinfo.dma_attr;
328 		ASSERT(hal_attr);
329 		ddi_dma_attr_merge(attr, hal_attr);
330 	}
331 	status = ddi_dma_allochdl(dip, rdip, attr, waitfnp, arg, handlep);
332 	TNF_PROBE_1_DEBUG(nx1394_dma_allochdl_exit, S1394_TNF_SL_NEXUS_STACK,
333 	    "", tnf_int, status, status);
334 	return (status);
335 }
336 
337 /*
338  * nx1394_get_event_cookie()
339  *    Called when a child node calls ddi_get_eventcookie().
340  *    Returns event cookie corresponding to event "name".
341  */
342 static int
343 nx1394_get_event_cookie(dev_info_t *dip, dev_info_t *rdip, char *name,
344     ddi_eventcookie_t *event_cookiep)
345 {
346 	int ret;
347 	s1394_hal_t *hal;
348 
349 	TNF_PROBE_1_DEBUG(nx1394_get_event_cookie_enter,
350 	    S1394_TNF_SL_NEXUS_STACK, "", tnf_string, name, name);
351 
352 	hal = s1394_dip_to_hal(dip);
353 	ASSERT(hal);
354 
355 	ret = ndi_event_retrieve_cookie(hal->hal_ndi_event_hdl,
356 	    rdip, name, event_cookiep, 0);
357 
358 	TNF_PROBE_4_DEBUG(nx1394_get_event_cookie_exit,
359 	    S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip, (void *)dip,
360 	    tnf_opaque, requestor_dip, (void *)rdip, tnf_string, event_name,
361 	    name, tnf_int, request_status, ret);
362 
363 	return (ret);
364 
365 }
366 
367 /*
368  * nx1394_add_eventcall()
369  *    This gets called when a child node calls ddi_add_eventcall(). Registers
370  *    the specified callback for the requested event cookie with the ndi
371  *    event framework.
372  *    dip is the hal dip. This routine calls ndi_event_add_callback(),
373  *    allowing requests for events we don't generate to pass up the tree.
374  */
375 static int
376 nx1394_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
377     ddi_eventcookie_t cookie, void (*callback)(), void *arg,
378     ddi_callback_id_t *cb_id)
379 {
380 	int ret;
381 	s1394_hal_t *hal;
382 #if defined(DEBUG)
383 	char *event_name = NULL;
384 #endif
385 
386 	hal = s1394_dip_to_hal(dip);
387 	ASSERT(hal);
388 
389 	TNF_PROBE_0_DEBUG(nx1394_add_eventcall_enter, S1394_TNF_SL_NEXUS_STACK,
390 	    "");
391 
392 	ret = ndi_event_add_callback(hal->hal_ndi_event_hdl, rdip, cookie,
393 	    callback, arg, NDI_NOSLEEP, cb_id);
394 #if defined(DEBUG)
395 	event_name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
396 	if (event_name == NULL)
397 	    event_name = "";
398 #endif
399 	TNF_PROBE_4_DEBUG(nx1394_add_eventcall_exit, S1394_TNF_SL_NEXUS_STACK,
400 	    "", tnf_opaque, parent_dip, (void *)dip, tnf_opaque, requestor_dip,
401 	    (void *)rdip, tnf_string, event_name, event_name, tnf_int,
402 	    request_status, ret);
403 
404 	return (ret);
405 }
406 
407 /*
408  * nx1394_remove_eventcall()
409  *    Called as a result of a child node calling ddi_remove_eventcall().
410  *    Unregisters the callback corresponding to the callback id passed in.
411  */
412 static int
413 nx1394_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id)
414 {
415 	int ret;
416 	s1394_hal_t *hal;
417 	ddi_eventcookie_t cookie;
418 #if defined(DEBUG)
419 	char *event_name = NULL;
420 #endif
421 
422 	ASSERT(cb_id);
423 	cookie = ((ndi_event_callbacks_t *)cb_id)->ndi_evtcb_cookie;
424 
425 	hal = s1394_dip_to_hal(dip);
426 	ASSERT(hal);
427 
428 	TNF_PROBE_0_DEBUG(nx1394_remove_eventcall_enter,
429 	    S1394_TNF_SL_NEXUS_STACK, "");
430 
431 	ret = ndi_event_remove_callback(hal->hal_ndi_event_hdl, cb_id);
432 
433 #if defined(DEBUG)
434 	event_name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
435 	if (event_name == NULL)
436 	    event_name = "";
437 
438 	TNF_PROBE_4_DEBUG(nx1394_remove_eventcall_exit,
439 	    S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip, (void *)dip,
440 	    tnf_opaque, callback_id, (void *)cb_id, tnf_string, event_name,
441 	    event_name, tnf_int, request_status, ret);
442 #endif
443 
444 	return (ret);
445 }
446 
447 /*
448  * nx1394_post_event()
449  *    Called when a child node calls ddi_post_event. If the event is one of
450  *    the events supported by us (bus reset/insert/remove, for now), builds
451  *    a t1394_localinfo_t structure and calls ndi_event_run_callbacks(). This
452  *    will result in all registered callbacks being invoked with
453  *    t1394_localinfo_t as the impl_data. (see ddi_add_eventcall for callback
454  *    arguments.) If the event is not defined by us, the request is
455  *    propagated up the device tree by calling ndi_post_event().
456  */
457 static int
458 nx1394_post_event(dev_info_t *dip, dev_info_t *rdip, ddi_eventcookie_t cookie,
459     void *impl_data)
460 {
461 	int ret;
462 	char *name;
463 	s1394_hal_t *hal;
464 	t1394_localinfo_t localinfo;
465 
466 	hal = s1394_dip_to_hal(dip);
467 	ASSERT(hal);
468 
469 	TNF_PROBE_0_DEBUG(nx1394_post_event_enter, S1394_TNF_SL_NEXUS_STACK,
470 	    "");
471 
472 	name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
473 	/* name is NULL if we don't generate the event */
474 	if (name != NULL) {
475 
476 		mutex_enter(&hal->topology_tree_mutex);
477 		localinfo.bus_generation = hal->generation_count;
478 		localinfo.local_nodeID = hal->node_id;
479 		mutex_exit(&hal->topology_tree_mutex);
480 		impl_data = &localinfo;
481 
482 		ret = ndi_event_run_callbacks(hal->hal_ndi_event_hdl,
483 		    rdip, cookie, impl_data);
484 
485 		TNF_PROBE_4_DEBUG(nx1394_post_event_exit,
486 		    S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip,
487 		    (void *)dip, tnf_opaque, requestor_dip, (void *)rdip,
488 		    tnf_string, event_name, name, tnf_int, request_status, ret);
489 		return (ret);
490 
491 	} else {
492 		ret = ndi_post_event(ddi_get_parent(dip), rdip, cookie,
493 		    impl_data);
494 		TNF_PROBE_2_DEBUG(nx1394_post_event_exit,
495 		    S1394_TNF_SL_NEXUS_STACK, "", tnf_string, msg,
496 		    "Not our event", tnf_int, ret, ret);
497 		return (ret);
498 	}
499 }
500 
501 /*
502  * nx1394_define_events()
503  *    Allocates event handle for the hal dip and binds event set to it.
504  */
505 int
506 nx1394_define_events(s1394_hal_t *hal)
507 {
508 	int ret;
509 
510 	TNF_PROBE_0_DEBUG(nx1394_define_events_enter, S1394_TNF_SL_NEXUS_STACK,
511 	    "");
512 
513 	/* get event handle */
514 	ret = ndi_event_alloc_hdl(hal->halinfo.dip, hal->halinfo.hw_interrupt,
515 	    &hal->hal_ndi_event_hdl, NDI_SLEEP);
516 	if (ret != NDI_SUCCESS) {
517 		TNF_PROBE_1(nx1394_define_events_alloc_fail,
518 		    S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
519 	} else {
520 		/* and bind to it */
521 		ret = ndi_event_bind_set(hal->hal_ndi_event_hdl, &nx1394_events,
522 		    NDI_SLEEP);
523 		if (ret != NDI_SUCCESS) {
524 			TNF_PROBE_1(nx1394_define_events_bind_fail,
525 			    S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
526 			(void) ndi_event_free_hdl(hal->hal_ndi_event_hdl);
527 			TNF_PROBE_0_DEBUG(nx1394_define_events_exit,
528 			    S1394_TNF_SL_NEXUS_STACK, "");
529 			return (DDI_FAILURE);
530 		}
531 	}
532 
533 	TNF_PROBE_0_DEBUG(nx1394_define_events_exit, S1394_TNF_SL_NEXUS_STACK,
534 	    "");
535 
536 	return (DDI_SUCCESS);
537 }
538 
539 /*
540  * nx1394_undefine_events()
541  *    Unbinds event set bound to the hal and frees the event handle.
542  */
543 void
544 nx1394_undefine_events(s1394_hal_t *hal)
545 {
546 	int ret;
547 
548 	TNF_PROBE_0_DEBUG(nx1394_undefine_events_enter,
549 	    S1394_TNF_SL_NEXUS_STACK, "");
550 
551 	ret = ndi_event_unbind_set(hal->hal_ndi_event_hdl, &nx1394_events,
552 	    NDI_SLEEP);
553 	if (ret != NDI_SUCCESS) {
554 		TNF_PROBE_1(nx1394_undefine_events_unbind_fail,
555 		    S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
556 	} else {
557 		ret = ndi_event_free_hdl(hal->hal_ndi_event_hdl);
558 		if (ret != NDI_SUCCESS) {
559 			TNF_PROBE_1(nx1394_undefine_events_free_hdl_fail,
560 			    S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
561 		}
562 	}
563 
564 	TNF_PROBE_0_DEBUG(nx1394_undefine_events_exit,
565 	    S1394_TNF_SL_NEXUS_STACK, "");
566 }
567