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
nx1394_bus_ctl(dev_info_t * dip,dev_info_t * rdip,ddi_ctl_enum_t op,void * arg,void * result)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 **)®ptr,
164 (uint_t *)®len);
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_SIDDEV:
271 case DDI_CTLOPS_SLAVEONLY:
272 case DDI_CTLOPS_AFFINITY:
273 case DDI_CTLOPS_POKE:
274 case DDI_CTLOPS_PEEK: {
275 cmn_err(CE_CONT, "!%s(%d): invalid op (%d) from %s(%d)",
276 ddi_node_name(dip), ddi_get_instance(dip),
277 op, ddi_node_name(rdip), ddi_get_instance(rdip));
278 TNF_PROBE_2(nx1394_bus_ctl, S1394_TNF_SL_NEXUS_ERROR, "",
279 tnf_string, msg, "invalid op", tnf_int, op, op);
280 TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
281 "");
282 return (DDI_FAILURE);
283 }
284
285 /*
286 * Everything else (e.g. PTOB/BTOP/BTOPR requests) we pass up
287 */
288 default: {
289 status = ddi_ctlops(dip, rdip, op, arg, result);
290 TNF_PROBE_0_DEBUG(nx1394_bus_ctl_exit, S1394_TNF_SL_NEXUS_STACK,
291 "");
292 return (status);
293 }
294 }
295 }
296
297 /*
298 * nx1394_dma_allochdl()
299 * Merges the ddi_dma_attr_t passed in by the target (using
300 * ddi_dma_alloc_handle() call) with that of the hal and passes the alloc
301 * handle request up the device by calling ddi_dma_allochdl().
302 */
303 static int
nx1394_dma_allochdl(dev_info_t * dip,dev_info_t * rdip,ddi_dma_attr_t * attr,int (* waitfnp)(caddr_t),caddr_t arg,ddi_dma_handle_t * handlep)304 nx1394_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attr,
305 int (*waitfnp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
306 {
307 s1394_hal_t *hal;
308 ddi_dma_attr_t *hal_attr;
309 int status;
310
311 _NOTE(SCHEME_PROTECTS_DATA("unique (per thread)", ddi_dma_attr_t))
312
313 TNF_PROBE_0_DEBUG(nx1394_dma_allochdl_enter, S1394_TNF_SL_NEXUS_STACK,
314 "");
315
316 /*
317 * If hal calls ddi_dma_alloc_handle, dip == rdip == hal dip.
318 * Unfortunately, we cannot verify this (by way of looking up for hal
319 * dip) here because h1394_attach() may happen much later.
320 */
321 if (dip != rdip) {
322 hal = s1394_dip_to_hal(ddi_get_parent(rdip));
323 ASSERT(hal);
324 hal_attr = &hal->halinfo.dma_attr;
325 ASSERT(hal_attr);
326 ddi_dma_attr_merge(attr, hal_attr);
327 }
328 status = ddi_dma_allochdl(dip, rdip, attr, waitfnp, arg, handlep);
329 TNF_PROBE_1_DEBUG(nx1394_dma_allochdl_exit, S1394_TNF_SL_NEXUS_STACK,
330 "", tnf_int, status, status);
331 return (status);
332 }
333
334 /*
335 * nx1394_get_event_cookie()
336 * Called when a child node calls ddi_get_eventcookie().
337 * Returns event cookie corresponding to event "name".
338 */
339 static int
nx1394_get_event_cookie(dev_info_t * dip,dev_info_t * rdip,char * name,ddi_eventcookie_t * event_cookiep)340 nx1394_get_event_cookie(dev_info_t *dip, dev_info_t *rdip, char *name,
341 ddi_eventcookie_t *event_cookiep)
342 {
343 int ret;
344 s1394_hal_t *hal;
345
346 TNF_PROBE_1_DEBUG(nx1394_get_event_cookie_enter,
347 S1394_TNF_SL_NEXUS_STACK, "", tnf_string, name, name);
348
349 hal = s1394_dip_to_hal(dip);
350 ASSERT(hal);
351
352 ret = ndi_event_retrieve_cookie(hal->hal_ndi_event_hdl,
353 rdip, name, event_cookiep, 0);
354
355 TNF_PROBE_4_DEBUG(nx1394_get_event_cookie_exit,
356 S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip, (void *)dip,
357 tnf_opaque, requestor_dip, (void *)rdip, tnf_string, event_name,
358 name, tnf_int, request_status, ret);
359
360 return (ret);
361
362 }
363
364 /*
365 * nx1394_add_eventcall()
366 * This gets called when a child node calls ddi_add_eventcall(). Registers
367 * the specified callback for the requested event cookie with the ndi
368 * event framework.
369 * dip is the hal dip. This routine calls ndi_event_add_callback(),
370 * allowing requests for events we don't generate to pass up the tree.
371 */
372 static int
nx1394_add_eventcall(dev_info_t * dip,dev_info_t * rdip,ddi_eventcookie_t cookie,void (* callback)(),void * arg,ddi_callback_id_t * cb_id)373 nx1394_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
374 ddi_eventcookie_t cookie, void (*callback)(), void *arg,
375 ddi_callback_id_t *cb_id)
376 {
377 int ret;
378 s1394_hal_t *hal;
379 #if defined(DEBUG)
380 char *event_name = NULL;
381 #endif
382
383 hal = s1394_dip_to_hal(dip);
384 ASSERT(hal);
385
386 TNF_PROBE_0_DEBUG(nx1394_add_eventcall_enter, S1394_TNF_SL_NEXUS_STACK,
387 "");
388
389 ret = ndi_event_add_callback(hal->hal_ndi_event_hdl, rdip, cookie,
390 callback, arg, NDI_NOSLEEP, cb_id);
391 #if defined(DEBUG)
392 event_name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
393 if (event_name == NULL)
394 event_name = "";
395 #endif
396 TNF_PROBE_4_DEBUG(nx1394_add_eventcall_exit, S1394_TNF_SL_NEXUS_STACK,
397 "", tnf_opaque, parent_dip, (void *)dip, tnf_opaque, requestor_dip,
398 (void *)rdip, tnf_string, event_name, event_name, tnf_int,
399 request_status, ret);
400
401 return (ret);
402 }
403
404 /*
405 * nx1394_remove_eventcall()
406 * Called as a result of a child node calling ddi_remove_eventcall().
407 * Unregisters the callback corresponding to the callback id passed in.
408 */
409 static int
nx1394_remove_eventcall(dev_info_t * dip,ddi_callback_id_t cb_id)410 nx1394_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id)
411 {
412 int ret;
413 s1394_hal_t *hal;
414 ddi_eventcookie_t cookie;
415 #if defined(DEBUG)
416 char *event_name = NULL;
417 #endif
418
419 ASSERT(cb_id);
420 cookie = ((ndi_event_callbacks_t *)cb_id)->ndi_evtcb_cookie;
421
422 hal = s1394_dip_to_hal(dip);
423 ASSERT(hal);
424
425 TNF_PROBE_0_DEBUG(nx1394_remove_eventcall_enter,
426 S1394_TNF_SL_NEXUS_STACK, "");
427
428 ret = ndi_event_remove_callback(hal->hal_ndi_event_hdl, cb_id);
429
430 #if defined(DEBUG)
431 event_name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
432 if (event_name == NULL)
433 event_name = "";
434
435 TNF_PROBE_4_DEBUG(nx1394_remove_eventcall_exit,
436 S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip, (void *)dip,
437 tnf_opaque, callback_id, (void *)cb_id, tnf_string, event_name,
438 event_name, tnf_int, request_status, ret);
439 #endif
440
441 return (ret);
442 }
443
444 /*
445 * nx1394_post_event()
446 * Called when a child node calls ddi_post_event. If the event is one of
447 * the events supported by us (bus reset/insert/remove, for now), builds
448 * a t1394_localinfo_t structure and calls ndi_event_run_callbacks(). This
449 * will result in all registered callbacks being invoked with
450 * t1394_localinfo_t as the impl_data. (see ddi_add_eventcall for callback
451 * arguments.) If the event is not defined by us, the request is
452 * propagated up the device tree by calling ndi_post_event().
453 */
454 static int
nx1394_post_event(dev_info_t * dip,dev_info_t * rdip,ddi_eventcookie_t cookie,void * impl_data)455 nx1394_post_event(dev_info_t *dip, dev_info_t *rdip, ddi_eventcookie_t cookie,
456 void *impl_data)
457 {
458 int ret;
459 char *name;
460 s1394_hal_t *hal;
461 t1394_localinfo_t localinfo;
462
463 hal = s1394_dip_to_hal(dip);
464 ASSERT(hal);
465
466 TNF_PROBE_0_DEBUG(nx1394_post_event_enter, S1394_TNF_SL_NEXUS_STACK,
467 "");
468
469 name = ndi_event_cookie_to_name(hal->hal_ndi_event_hdl, cookie);
470 /* name is NULL if we don't generate the event */
471 if (name != NULL) {
472
473 mutex_enter(&hal->topology_tree_mutex);
474 localinfo.bus_generation = hal->generation_count;
475 localinfo.local_nodeID = hal->node_id;
476 mutex_exit(&hal->topology_tree_mutex);
477 impl_data = &localinfo;
478
479 ret = ndi_event_run_callbacks(hal->hal_ndi_event_hdl,
480 rdip, cookie, impl_data);
481
482 TNF_PROBE_4_DEBUG(nx1394_post_event_exit,
483 S1394_TNF_SL_NEXUS_STACK, "", tnf_opaque, parent_dip,
484 (void *)dip, tnf_opaque, requestor_dip, (void *)rdip,
485 tnf_string, event_name, name, tnf_int, request_status, ret);
486 return (ret);
487
488 } else {
489 ret = ndi_post_event(ddi_get_parent(dip), rdip, cookie,
490 impl_data);
491 TNF_PROBE_2_DEBUG(nx1394_post_event_exit,
492 S1394_TNF_SL_NEXUS_STACK, "", tnf_string, msg,
493 "Not our event", tnf_int, ret, ret);
494 return (ret);
495 }
496 }
497
498 /*
499 * nx1394_define_events()
500 * Allocates event handle for the hal dip and binds event set to it.
501 */
502 int
nx1394_define_events(s1394_hal_t * hal)503 nx1394_define_events(s1394_hal_t *hal)
504 {
505 int ret;
506
507 TNF_PROBE_0_DEBUG(nx1394_define_events_enter, S1394_TNF_SL_NEXUS_STACK,
508 "");
509
510 /* get event handle */
511 ret = ndi_event_alloc_hdl(hal->halinfo.dip, hal->halinfo.hw_interrupt,
512 &hal->hal_ndi_event_hdl, NDI_SLEEP);
513 if (ret != NDI_SUCCESS) {
514 TNF_PROBE_1(nx1394_define_events_alloc_fail,
515 S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
516 } else {
517 /* and bind to it */
518 ret = ndi_event_bind_set(hal->hal_ndi_event_hdl, &nx1394_events,
519 NDI_SLEEP);
520 if (ret != NDI_SUCCESS) {
521 TNF_PROBE_1(nx1394_define_events_bind_fail,
522 S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
523 (void) ndi_event_free_hdl(hal->hal_ndi_event_hdl);
524 TNF_PROBE_0_DEBUG(nx1394_define_events_exit,
525 S1394_TNF_SL_NEXUS_STACK, "");
526 return (DDI_FAILURE);
527 }
528 }
529
530 TNF_PROBE_0_DEBUG(nx1394_define_events_exit, S1394_TNF_SL_NEXUS_STACK,
531 "");
532
533 return (DDI_SUCCESS);
534 }
535
536 /*
537 * nx1394_undefine_events()
538 * Unbinds event set bound to the hal and frees the event handle.
539 */
540 void
nx1394_undefine_events(s1394_hal_t * hal)541 nx1394_undefine_events(s1394_hal_t *hal)
542 {
543 int ret;
544
545 TNF_PROBE_0_DEBUG(nx1394_undefine_events_enter,
546 S1394_TNF_SL_NEXUS_STACK, "");
547
548 ret = ndi_event_unbind_set(hal->hal_ndi_event_hdl, &nx1394_events,
549 NDI_SLEEP);
550 if (ret != NDI_SUCCESS) {
551 TNF_PROBE_1(nx1394_undefine_events_unbind_fail,
552 S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
553 } else {
554 ret = ndi_event_free_hdl(hal->hal_ndi_event_hdl);
555 if (ret != NDI_SUCCESS) {
556 TNF_PROBE_1(nx1394_undefine_events_free_hdl_fail,
557 S1394_TNF_SL_NEXUS_ERROR, "", tnf_int, ret, ret);
558 }
559 }
560
561 TNF_PROBE_0_DEBUG(nx1394_undefine_events_exit,
562 S1394_TNF_SL_NEXUS_STACK, "");
563 }
564