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