Print this page
OS-1988 Make ldi_ev_remove_callbacks safe to use in LDI callbacks


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */



  25 
  26 #ifndef _SYS_SUNLDI_IMPL_H
  27 #define _SYS_SUNLDI_IMPL_H
  28 
  29 #pragma ident   "%Z%%M% %I%     %E% SMI"
  30 
  31 #ifdef __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 #include <sys/dditypes.h>
  36 #include <sys/vnode.h>
  37 
  38 /*
  39  * NOTE
  40  *
  41  * The contents of this file are private to this implementation
  42  * of Solaris and are subject to change at any time without notice.
  43  *
  44  * Applications and drivers using these interfaces will fail
  45  * to run on future releases.
  46  */
  47 
  48 /*
  49  * LDI hash definitions
  50  */


 124         struct ldi_handle       *le_lhp;
 125         void                    (*le_handler)();
 126         void                    *le_arg;
 127         ddi_callback_id_t       le_id;
 128 } ldi_event_t;
 129 #endif
 130 
 131 typedef struct ldi_ev_callback_impl {
 132         struct ldi_handle       *lec_lhp;
 133         dev_info_t              *lec_dip;
 134         dev_t                   lec_dev;
 135         int                     lec_spec;
 136         int                     (*lec_notify)();
 137         void                    (*lec_finalize)();
 138         void                    *lec_arg;
 139         void                    *lec_cookie;
 140         void                    *lec_id;
 141         list_node_t             lec_list;
 142 } ldi_ev_callback_impl_t;
 143 















 144 struct ldi_ev_callback_list {
 145         kmutex_t        le_lock;
 146         kcondvar_t      le_cv;
 147         int             le_busy;
 148         void            *le_thread;
 149         list_t          le_head;


 150 };
 151 
 152 int ldi_invoke_notify(dev_info_t *dip, dev_t dev, int spec_type, char *event,
 153     void *ev_data);
 154 void ldi_invoke_finalize(dev_info_t *dip, dev_t dev, int spec_type, char *event,
 155     int ldi_result, void *ev_data);
 156 int e_ddi_offline_notify(dev_info_t *dip);
 157 void e_ddi_offline_finalize(dev_info_t *dip, int result);
 158 
 159 
 160 /*
 161  * LDI device usage interfaces
 162  *
 163  * ldi_usage_count(), ldi_usage_walker(), and ldi_usage_t
 164  *
 165  * These functions are used by the devinfo driver and fuser to get a
 166  * device usage information from the LDI. These functions along with
 167  * the ldi_usage_t data structure allow these other subsystems to have
 168  * no knowledge of how the LDI stores it's internal state.
 169  *




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  27  */
  28 
  29 #ifndef _SYS_SUNLDI_IMPL_H
  30 #define _SYS_SUNLDI_IMPL_H
  31 


  32 #ifdef __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 #include <sys/dditypes.h>
  37 #include <sys/vnode.h>
  38 
  39 /*
  40  * NOTE
  41  *
  42  * The contents of this file are private to this implementation
  43  * of Solaris and are subject to change at any time without notice.
  44  *
  45  * Applications and drivers using these interfaces will fail
  46  * to run on future releases.
  47  */
  48 
  49 /*
  50  * LDI hash definitions
  51  */


 125         struct ldi_handle       *le_lhp;
 126         void                    (*le_handler)();
 127         void                    *le_arg;
 128         ddi_callback_id_t       le_id;
 129 } ldi_event_t;
 130 #endif
 131 
 132 typedef struct ldi_ev_callback_impl {
 133         struct ldi_handle       *lec_lhp;
 134         dev_info_t              *lec_dip;
 135         dev_t                   lec_dev;
 136         int                     lec_spec;
 137         int                     (*lec_notify)();
 138         void                    (*lec_finalize)();
 139         void                    *lec_arg;
 140         void                    *lec_cookie;
 141         void                    *lec_id;
 142         list_node_t             lec_list;
 143 } ldi_ev_callback_impl_t;
 144 
 145 /*
 146  * Members of "struct ldi_ev_callback_list" are protected by their le_lock
 147  * member.  The struct is currently only used once, as a file-level global,
 148  * and the locking protocol is currently implemented in ldi_ev_lock() and
 149  * ldi_ev_unlock().
 150  *
 151  * When delivering events to subscribers, ldi_invoke_notify() and
 152  * ldi_invoke_finalize() will walk the list of callbacks: le_head.  It is
 153  * possible that an invoked callback function will need to unregister an
 154  * arbitrary number of callbacks from this list.
 155  *
 156  * To enable ldi_ev_remove_callbacks() to remove elements from the list
 157  * without breaking the walk-in-progress, we store the next element in the
 158  * walk direction on the struct as le_walker_next and le_walker_prev.
 159  */
 160 struct ldi_ev_callback_list {
 161         kmutex_t                le_lock;
 162         kcondvar_t              le_cv;
 163         int                     le_busy;
 164         void                    *le_thread;
 165         list_t                  le_head;
 166         ldi_ev_callback_impl_t  *le_walker_next;
 167         ldi_ev_callback_impl_t  *le_walker_prev;
 168 };
 169 
 170 int ldi_invoke_notify(dev_info_t *dip, dev_t dev, int spec_type, char *event,
 171     void *ev_data);
 172 void ldi_invoke_finalize(dev_info_t *dip, dev_t dev, int spec_type, char *event,
 173     int ldi_result, void *ev_data);
 174 int e_ddi_offline_notify(dev_info_t *dip);
 175 void e_ddi_offline_finalize(dev_info_t *dip, int result);
 176 
 177 
 178 /*
 179  * LDI device usage interfaces
 180  *
 181  * ldi_usage_count(), ldi_usage_walker(), and ldi_usage_t
 182  *
 183  * These functions are used by the devinfo driver and fuser to get a
 184  * device usage information from the LDI. These functions along with
 185  * the ldi_usage_t data structure allow these other subsystems to have
 186  * no knowledge of how the LDI stores it's internal state.
 187  *