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