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 **)®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 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 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 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 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 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 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 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