|
PAPI
5.0.1.0
|
00001 /****************************/ 00002 /* THIS IS OPEN SOURCE CODE */ 00003 /****************************/ 00004 00020 #include "linux-L2unit.h" 00021 00022 /* Declare our vector in advance */ 00023 papi_vector_t _L2unit_vector; 00024 00025 /***************************************************************************** 00026 ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS ************* 00027 *****************************************************************************/ 00028 00029 /* 00030 * This is called whenever a thread is initialized 00031 */ 00032 int 00033 L2UNIT_init_thread( hwd_context_t * ctx ) 00034 { 00035 #ifdef DEBUG_BGQ 00036 printf( "L2UNIT_init_thread\n" ); 00037 #endif 00038 00039 ( void ) ctx; 00040 return PAPI_OK; 00041 } 00042 00043 00044 /* Initialize hardware counters, setup the function vector table 00045 * and get hardware information, this routine is called when the 00046 * PAPI process is initialized (IE PAPI_library_init) 00047 */ 00048 int 00049 L2UNIT_init_component( int cidx ) 00050 { 00051 #ifdef DEBUG_BGQ 00052 printf( "L2UNIT_init_component\n" ); 00053 #endif 00054 00055 _L2unit_vector.cmp_info.CmpIdx = cidx; 00056 #ifdef DEBUG_BGQ 00057 printf( "L2UNIT_init_component cidx = %d\n", cidx ); 00058 #endif 00059 00060 return ( PAPI_OK ); 00061 } 00062 00063 00064 /* 00065 * Control of counters (Reading/Writing/Starting/Stopping/Setup) 00066 * functions 00067 */ 00068 int 00069 L2UNIT_init_control_state( hwd_control_state_t * ptr ) 00070 { 00071 #ifdef DEBUG_BGQ 00072 printf( "L2UNIT_init_control_state\n" ); 00073 #endif 00074 00075 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr; 00076 00077 this_state->EventGroup = Bgpm_CreateEventSet(); 00078 CHECK_BGPM_ERROR( this_state->EventGroup, "Bgpm_CreateEventSet" ); 00079 00080 // initialized BGPM eventGroup flag to NOT applied yet (0) 00081 this_state->bgpm_eventset_applied = 0; 00082 00083 return PAPI_OK; 00084 } 00085 00086 00087 /* 00088 * 00089 */ 00090 int 00091 L2UNIT_start( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00092 { 00093 #ifdef DEBUG_BGQ 00094 printf( "L2UNIT_start\n" ); 00095 #endif 00096 ( void ) ctx; 00097 int retval; 00098 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr; 00099 00100 retval = Bgpm_Apply( this_state->EventGroup ); 00101 CHECK_BGPM_ERROR( retval, "Bgpm_Apply" ); 00102 00103 // set flag to 1: BGPM eventGroup HAS BEEN applied 00104 this_state->bgpm_eventset_applied = 1; 00105 00106 /* Bgpm_Apply() does an implicit reset; 00107 hence no need to use Bgpm_ResetStart */ 00108 retval = Bgpm_Start( this_state->EventGroup ); 00109 CHECK_BGPM_ERROR( retval, "Bgpm_Start" ); 00110 00111 return ( PAPI_OK ); 00112 } 00113 00114 00115 /* 00116 * 00117 */ 00118 int 00119 L2UNIT_stop( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00120 { 00121 #ifdef DEBUG_BGQ 00122 printf( "L2UNIT_stop\n" ); 00123 #endif 00124 ( void ) ctx; 00125 int retval; 00126 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr; 00127 00128 retval = Bgpm_Stop( this_state->EventGroup ); 00129 CHECK_BGPM_ERROR( retval, "Bgpm_Stop" ); 00130 00131 return ( PAPI_OK ); 00132 } 00133 00134 00135 /* 00136 * 00137 */ 00138 int 00139 L2UNIT_read( hwd_context_t * ctx, hwd_control_state_t * ptr, 00140 long_long ** events, int flags ) 00141 { 00142 #ifdef DEBUG_BGQ 00143 printf( "L2UNIT_read\n" ); 00144 #endif 00145 ( void ) ctx; 00146 ( void ) flags; 00147 int i, numEvts; 00148 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr; 00149 00150 numEvts = Bgpm_NumEvents( this_state->EventGroup ); 00151 if ( numEvts == 0 ) { 00152 #ifdef DEBUG_BGPM 00153 printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts ); 00154 #endif 00155 //return ( EXIT_FAILURE ); 00156 } 00157 00158 for ( i = 0; i < numEvts; i++ ) 00159 this_state->counters[i] = _common_getEventValue( i, this_state->EventGroup ); 00160 00161 *events = this_state->counters; 00162 00163 return ( PAPI_OK ); 00164 } 00165 00166 00167 /* 00168 * 00169 */ 00170 int 00171 L2UNIT_shutdown_thread( hwd_context_t * ctx ) 00172 { 00173 #ifdef DEBUG_BGQ 00174 printf( "L2UNIT_shutdown_thread\n" ); 00175 #endif 00176 00177 ( void ) ctx; 00178 return ( PAPI_OK ); 00179 } 00180 00181 00182 00183 00184 /* 00185 * user_signal_handler 00186 * 00187 * This function is used when hardware overflows are working or when 00188 * software overflows are forced 00189 */ 00190 void 00191 user_signal_handler_L2UNIT( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext ) 00192 { 00193 #ifdef DEBUG_BGQ 00194 printf( "user_signal_handler_L2UNIT\n" ); 00195 #endif 00196 00197 int retval, i; 00198 int isHardware = 1; 00199 int cidx = _L2unit_vector.cmp_info.CmpIdx; 00200 long_long overflow_bit = 0; 00201 caddr_t address1; 00202 _papi_hwi_context_t ctx; 00203 ctx.ucontext = ( hwd_ucontext_t * ) pContext; 00204 ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 ); 00205 EventSetInfo_t *ESI; 00206 ESI = thread->running_eventset[cidx]; 00207 // Get the indices of all events which have overflowed. 00208 unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS]; 00209 unsigned len = BGPM_MAX_OVERFLOW_EVENTS; 00210 00211 retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len ); 00212 if ( retval < 0 ) { 00213 #ifdef DEBUG_BGPM 00214 printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n", 00215 retval ); 00216 #endif 00217 return; 00218 } 00219 00220 if ( thread == NULL ) { 00221 PAPIERROR( "thread == NULL in user_signal_handler!" ); 00222 return; 00223 } 00224 00225 if ( ESI == NULL ) { 00226 PAPIERROR( "ESI == NULL in user_signal_handler!"); 00227 return; 00228 } 00229 00230 if ( ESI->overflow.flags == 0 ) { 00231 PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!"); 00232 return; 00233 } 00234 00235 for ( i = 0; i < len; i++ ) { 00236 uint64_t hProf; 00237 Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf ); 00238 if ( hProf ) { 00239 overflow_bit ^= 1 << ovfIdxs[i]; 00240 break; 00241 } 00242 00243 } 00244 00245 if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) { 00246 #ifdef DEBUG_BGQ 00247 printf("OVERFLOW_SOFTWARE\n"); 00248 #endif 00249 address1 = GET_OVERFLOW_ADDRESS( ctx ); 00250 _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx ); 00251 return; 00252 } 00253 else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) { 00254 #ifdef DEBUG_BGQ 00255 printf("OVERFLOW_HARDWARE\n"); 00256 #endif 00257 address1 = GET_OVERFLOW_ADDRESS( ctx ); 00258 _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx ); 00259 } 00260 else { 00261 #ifdef DEBUG_BGQ 00262 printf("OVERFLOW_NONE\n"); 00263 #endif 00264 PAPIERROR( "ESI->overflow.flags is set to something other than PAPI_OVERFLOW_HARDWARE or PAPI_OVERFLOW_FORCE_SW (%x)", thread->running_eventset[cidx]->overflow.flags); 00265 } 00266 } 00267 00268 00269 /* 00270 * Set Overflow 00271 * 00272 * This is commented out in BG/L/P - need to explore and complete... 00273 * However, with true 64-bit counters in BG/Q and all counters for PAPI 00274 * always starting from a true zero (we don't allow write...), the possibility 00275 * for overflow is remote at best... 00276 */ 00277 int 00278 L2UNIT_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold ) 00279 { 00280 #ifdef DEBUG_BGQ 00281 printf("BEGIN L2UNIT_set_overflow\n"); 00282 #endif 00283 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ESI->ctl_state; 00284 int retval; 00285 int evt_idx; 00286 uint64_t threshold_for_bgpm; 00287 00288 /* 00289 * In case an BGPM eventGroup HAS BEEN applied or attached before 00290 * overflow is set, delete the eventGroup and create an new empty one, 00291 * and rebuild as it was prior to deletion 00292 */ 00293 #ifdef DEBUG_BGQ 00294 printf( "L2UNIT_set_overflow: bgpm_eventset_applied = %d\n", 00295 this_state->bgpm_eventset_applied ); 00296 #endif 00297 if ( 1 == this_state->bgpm_eventset_applied ) { 00298 _common_deleteRecreate( &this_state->EventGroup ); 00299 _common_rebuildEventgroup( this_state->count, 00300 this_state->EventGroup_local, 00301 &this_state->EventGroup ); 00302 00303 /* set BGPM eventGroup flag back to NOT applied yet (0) 00304 * because the eventGroup has been recreated from scratch */ 00305 this_state->bgpm_eventset_applied = 0; 00306 } 00307 00308 /* convert threadhold value assigned by PAPI user to value that is 00309 * programmed into the counter. This value is required by Bgpm_SetOverflow() */ 00310 threshold_for_bgpm = BGPM_PERIOD2THRES( threshold ); 00311 00312 evt_idx = ESI->EventInfoArray[EventIndex].pos[0]; 00313 SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n", 00314 evt_idx, EventIndex, threshold ); 00315 #ifdef DEBUG_BGQ 00316 printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n", 00317 evt_idx, EventIndex, threshold ); 00318 #endif 00319 /* If this counter isn't set to overflow, it's an error */ 00320 if ( threshold == 0 ) { 00321 /* Remove the signal handler */ 00322 retval = _papi_hwi_stop_signal( _L2unit_vector.cmp_info.hardware_intr_sig ); 00323 if ( retval != PAPI_OK ) 00324 return ( retval ); 00325 } 00326 else { 00327 #ifdef DEBUG_BGQ 00328 printf( "L2UNIT_set_overflow: Enable the signal handler\n" ); 00329 #endif 00330 /* Enable the signal handler */ 00331 retval = _papi_hwi_start_signal( _L2unit_vector.cmp_info.hardware_intr_sig, 00332 NEED_CONTEXT, 00333 _L2unit_vector.cmp_info.CmpIdx ); 00334 if ( retval != PAPI_OK ) 00335 return ( retval ); 00336 00337 retval = Bgpm_SetOverflow( this_state->EventGroup, 00338 evt_idx, 00339 threshold_for_bgpm ); 00340 CHECK_BGPM_ERROR( retval, "Bgpm_SetOverflow" ); 00341 00342 retval = Bgpm_SetEventUser1( this_state->EventGroup, 00343 evt_idx, 00344 1024 ); 00345 CHECK_BGPM_ERROR( retval, "Bgpm_SetEventUser1" ); 00346 00347 /* user signal handler for overflow case */ 00348 retval = Bgpm_SetOverflowHandler( this_state->EventGroup, user_signal_handler_L2UNIT ); 00349 CHECK_BGPM_ERROR( retval, "Bgpm_SetOverflowHandler" ); 00350 } 00351 00352 return ( PAPI_OK ); 00353 } 00354 00355 00356 00357 /* This function sets various options in the component 00358 * The valid codes being passed in are PAPI_SET_DEFDOM, 00359 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT 00360 */ 00361 int 00362 L2UNIT_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option ) 00363 { 00364 #ifdef DEBUG_BGQ 00365 printf( "L2UNIT_ctl\n" ); 00366 #endif 00367 00368 ( void ) ctx; 00369 ( void ) code; 00370 ( void ) option; 00371 return ( PAPI_OK ); 00372 } 00373 00374 00375 /* 00376 * PAPI Cleanup Eventset 00377 * Destroy and re-create the BGPM / L2unit EventSet 00378 */ 00379 int 00380 L2UNIT_cleanup_eventset( hwd_control_state_t * ctrl ) 00381 { 00382 #ifdef DEBUG_BGQ 00383 printf( "L2UNIT_cleanup_eventset\n" ); 00384 #endif 00385 00386 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ctrl; 00387 00388 // create a new empty bgpm eventset 00389 // reason: bgpm doesn't permit to remove events from an eventset; 00390 // hence we delete the old eventset and create a new one 00391 _common_deleteRecreate( &this_state->EventGroup ); 00392 00393 // set BGPM eventGroup flag back to NOT applied yet (0) 00394 this_state->bgpm_eventset_applied = 0; 00395 00396 00397 return ( PAPI_OK ); 00398 } 00399 00400 00401 /* 00402 * 00403 */ 00404 int 00405 L2UNIT_update_control_state( hwd_control_state_t * ptr, 00406 NativeInfo_t * native, int count, 00407 hwd_context_t * ctx ) 00408 { 00409 #ifdef DEBUG_BGQ 00410 printf( "L2UNIT_update_control_state: count = %d\n", count ); 00411 #endif 00412 00413 ( void ) ctx; 00414 int retval, index, i; 00415 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr; 00416 00417 // Delete and re-create BGPM eventset 00418 _common_deleteRecreate( &this_state->EventGroup ); 00419 00420 // otherwise, add the events to the eventset 00421 for ( i = 0; i < count; i++ ) { 00422 index = ( native[i].ni_event ) + OFFSET; 00423 00424 native[i].ni_position = i; 00425 00426 #ifdef DEBUG_BGQ 00427 printf("L2UNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index ); 00428 #endif 00429 00430 this_state->EventGroup_local[i] = index; 00431 00432 00433 /* Add events to the BGPM eventGroup */ 00434 retval = Bgpm_AddEvent( this_state->EventGroup, index ); 00435 CHECK_BGPM_ERROR( retval, "Bgpm_AddEvent" ); 00436 } 00437 00438 // store how many events we added to an EventSet 00439 this_state->count = count; 00440 00441 return ( PAPI_OK ); 00442 } 00443 00444 00445 /* 00446 * This function has to set the bits needed to count different domains 00447 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER 00448 * By default return PAPI_EINVAL if none of those are specified 00449 * and PAPI_OK with success 00450 * PAPI_DOM_USER is only user context is counted 00451 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted 00452 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses) 00453 * PAPI_DOM_ALL is all of the domains 00454 */ 00455 int 00456 L2UNIT_set_domain( hwd_control_state_t * cntrl, int domain ) 00457 { 00458 #ifdef DEBUG_BGQ 00459 printf( "L2UNIT_set_domain\n" ); 00460 #endif 00461 int found = 0; 00462 ( void ) cntrl; 00463 00464 if ( PAPI_DOM_USER & domain ) 00465 found = 1; 00466 00467 if ( PAPI_DOM_KERNEL & domain ) 00468 found = 1; 00469 00470 if ( PAPI_DOM_OTHER & domain ) 00471 found = 1; 00472 00473 if ( !found ) 00474 return ( PAPI_EINVAL ); 00475 00476 return ( PAPI_OK ); 00477 } 00478 00479 00480 /* 00481 * 00482 */ 00483 int 00484 L2UNIT_reset( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00485 { 00486 #ifdef DEBUG_BGQ 00487 printf( "L2UNIT_reset\n" ); 00488 #endif 00489 ( void ) ctx; 00490 int retval; 00491 L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr; 00492 00493 /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 00494 restriction that an EventSet has to be stopped before resetting is 00495 possible. However, BGPM does have this restriction. 00496 Hence we need to stop, reset and start */ 00497 retval = Bgpm_Stop( this_state->EventGroup ); 00498 CHECK_BGPM_ERROR( retval, "Bgpm_Stop" ); 00499 00500 retval = Bgpm_ResetStart( this_state->EventGroup ); 00501 CHECK_BGPM_ERROR( retval, "Bgpm_ResetStart" ); 00502 00503 return ( PAPI_OK ); 00504 } 00505 00506 00507 /* 00508 * Native Event functions 00509 */ 00510 int 00511 L2UNIT_ntv_enum_events( unsigned int *EventCode, int modifier ) 00512 { 00513 #ifdef DEBUG_BGQ 00514 //printf( "L2UNIT_ntv_enum_events, EventCode = %x\n", *EventCode ); 00515 #endif 00516 00517 switch ( modifier ) { 00518 case PAPI_ENUM_FIRST: 00519 *EventCode = 0; 00520 00521 return ( PAPI_OK ); 00522 break; 00523 00524 case PAPI_ENUM_EVENTS: 00525 { 00526 int index = ( *EventCode ) + OFFSET; 00527 00528 if ( index < L2UNIT_MAX_COUNTERS ) { 00529 *EventCode = *EventCode + 1; 00530 return ( PAPI_OK ); 00531 } else 00532 return ( PAPI_ENOEVNT ); 00533 00534 break; 00535 } 00536 default: 00537 return ( PAPI_EINVAL ); 00538 } 00539 return ( PAPI_EINVAL ); 00540 } 00541 00542 00543 /* 00544 * 00545 */ 00546 int 00547 L2UNIT_ntv_name_to_code( char *name, unsigned int *event_code ) 00548 { 00549 #ifdef DEBUG_BGQ 00550 printf( "L2UNIT_ntv_name_to_code\n" ); 00551 #endif 00552 int ret; 00553 00554 /* Return event id matching a given event label string */ 00555 ret = Bgpm_GetEventIdFromLabel ( name ); 00556 00557 if ( ret <= 0 ) { 00558 #ifdef DEBUG_BGPM 00559 printf ("Error: ret value is %d for BGPM API function '%s'.\n", 00560 ret, "Bgpm_GetEventIdFromLabel" ); 00561 #endif 00562 return PAPI_ENOEVNT; 00563 } 00564 else if ( ret < OFFSET || ret > L2UNIT_MAX_COUNTERS ) // not a L2Unit event 00565 return PAPI_ENOEVNT; 00566 else 00567 *event_code = ( ret - OFFSET ); 00568 00569 return PAPI_OK; 00570 } 00571 00572 00573 /* 00574 * 00575 */ 00576 int 00577 L2UNIT_ntv_code_to_name( unsigned int EventCode, char *name, int len ) 00578 { 00579 #ifdef DEBUG_BGQ 00580 //printf( "L2UNIT_ntv_code_to_name\n" ); 00581 #endif 00582 int index; 00583 00584 index = ( EventCode ) + OFFSET; 00585 00586 if ( index >= MAX_COUNTERS ) 00587 return PAPI_ENOEVNT; 00588 00589 strncpy( name, Bgpm_GetEventIdLabel( index ), len ); 00590 00591 if ( name == NULL ) { 00592 #ifdef DEBUG_BGPM 00593 printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" ); 00594 #endif 00595 return PAPI_ENOEVNT; 00596 } 00597 00598 return ( PAPI_OK ); 00599 } 00600 00601 00602 /* 00603 * 00604 */ 00605 int 00606 L2UNIT_ntv_code_to_descr( unsigned int EventCode, char *name, int len ) 00607 { 00608 #ifdef DEBUG_BGQ 00609 //printf( "L2UNIT_ntv_code_to_descr\n" ); 00610 #endif 00611 int retval, index; 00612 00613 index = ( EventCode ) + OFFSET; 00614 00615 retval = Bgpm_GetLongDesc( index, name, &len ); 00616 CHECK_BGPM_ERROR( retval, "Bgpm_GetLongDesc" ); 00617 00618 return ( PAPI_OK ); 00619 } 00620 00621 00622 /* 00623 * 00624 */ 00625 int 00626 L2UNIT_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits ) 00627 { 00628 #ifdef DEBUG_BGQ 00629 //printf( "L2UNIT_ntv_code_to_bits\n" ); 00630 #endif 00631 00632 return ( PAPI_OK ); 00633 } 00634 00635 00636 /* 00637 * 00638 */ 00639 papi_vector_t _L2unit_vector = { 00640 .cmp_info = { 00641 /* default component information (unspecified values are initialized to 0) */ 00642 .name = "bgpm/L2Unit", 00643 .short_name = "L2Unit", 00644 .description = "Blue Gene/Q L2Unit component", 00645 .num_cntrs = L2UNIT_MAX_COUNTERS, 00646 .num_mpx_cntrs = L2UNIT_MAX_COUNTERS, 00647 .default_domain = PAPI_DOM_USER, 00648 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL, 00649 .default_granularity = PAPI_GRN_THR, 00650 .available_granularities = PAPI_GRN_THR, 00651 00652 .hardware_intr_sig = PAPI_INT_SIGNAL, 00653 .hardware_intr = 1, 00654 00655 .kernel_multiplex = 0, 00656 00657 /* component specific cmp_info initializations */ 00658 .fast_real_timer = 0, 00659 .fast_virtual_timer = 0, 00660 .attach = 0, 00661 .attach_must_ptrace = 0, 00662 } 00663 , 00664 00665 /* sizes of framework-opaque component-private structures */ 00666 .size = { 00667 .context = sizeof ( L2UNIT_context_t ), 00668 .control_state = sizeof ( L2UNIT_control_state_t ), 00669 .reg_value = sizeof ( L2UNIT_register_t ), 00670 .reg_alloc = sizeof ( L2UNIT_reg_alloc_t ), 00671 } 00672 , 00673 /* function pointers in this component */ 00674 .init_thread = L2UNIT_init_thread, 00675 .init_component = L2UNIT_init_component, 00676 .init_control_state = L2UNIT_init_control_state, 00677 .start = L2UNIT_start, 00678 .stop = L2UNIT_stop, 00679 .read = L2UNIT_read, 00680 .shutdown_thread = L2UNIT_shutdown_thread, 00681 .set_overflow = L2UNIT_set_overflow, 00682 .cleanup_eventset = L2UNIT_cleanup_eventset, 00683 .ctl = L2UNIT_ctl, 00684 00685 .update_control_state = L2UNIT_update_control_state, 00686 .set_domain = L2UNIT_set_domain, 00687 .reset = L2UNIT_reset, 00688 00689 .ntv_name_to_code = L2UNIT_ntv_name_to_code, 00690 .ntv_enum_events = L2UNIT_ntv_enum_events, 00691 .ntv_code_to_name = L2UNIT_ntv_code_to_name, 00692 .ntv_code_to_descr = L2UNIT_ntv_code_to_descr, 00693 .ntv_code_to_bits = L2UNIT_ntv_code_to_bits 00694 };